GME
13
|
00001 // CSplitterBar.cpp : implementation file 00002 // 00004 00005 #include "stdafx.h" 00006 #include "SplitterBar.h" 00007 00008 #ifdef _DEBUG 00009 #define new DEBUG_NEW 00010 #undef THIS_FILE 00011 static char THIS_FILE[] = __FILE__; 00012 #endif 00013 00015 // CSplitterBar 00016 00017 IMPLEMENT_DYNAMIC(CSplitterBar, CWnd) 00018 00019 BEGIN_MESSAGE_MAP(CSplitterBar, CWnd) 00020 //{{AFX_MSG_MAP(CSplitterBar) 00021 ON_WM_PAINT() 00022 ON_WM_NCHITTEST() 00023 ON_WM_CREATE() 00024 ON_WM_SETCURSOR() 00025 ON_WM_MOUSEMOVE() 00026 ON_WM_LBUTTONDOWN() 00027 ON_WM_LBUTTONUP() 00028 //}}AFX_MSG_MAP 00029 END_MESSAGE_MAP() 00030 00031 CSplitterBar::CSplitterBar() 00032 { 00033 m_bDragging=FALSE; 00034 m_pwndLeftPane=m_pwndRightPane=NULL; 00035 } 00036 00037 CSplitterBar::~CSplitterBar() 00038 { 00039 } 00040 00041 BOOL CSplitterBar::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, BOOL bHorizontal) 00042 { 00043 CWnd* pWnd = this; 00044 m_bHorizontal=bHorizontal; 00045 return pWnd->Create(NULL, _T(""), dwStyle, rect, pParentWnd, nID); 00046 } 00047 00049 // CSplitterBar message handlers 00050 00051 void CSplitterBar::OnPaint() 00052 { 00053 RECT rc; 00054 if (!GetUpdateRect(&rc)) return; 00055 00056 PAINTSTRUCT paint; 00057 CDC *pDC = BeginPaint(&paint); 00058 00059 CRect rect; 00060 GetClientRect(rect); 00061 /* pDC->Draw3dRect(&rect, 00062 ::GetSysColor(COLOR_BTNHIGHLIGHT), 00063 ::GetSysColor(COLOR_BTNSHADOW)); */ 00064 EndPaint(&paint); 00065 } 00066 00067 LRESULT CSplitterBar::OnNcHitTest(CPoint point) 00068 { 00069 return HTCLIENT; 00070 } 00071 00072 int CSplitterBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 00073 { 00074 if (CWnd::OnCreate(lpCreateStruct) == -1) 00075 return -1; 00076 00077 GetWindowRect(&m_rectSplitter); 00078 SetWindowPos(&CWnd::wndTop,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); 00079 00080 //Initialize left most and right most coordinator 00081 CRect rectParent; 00082 GetParent()->GetClientRect(rectParent); 00083 if(m_bHorizontal) 00084 { 00085 m_cxLeftMost=rectParent.top; 00086 m_cxRightMost=rectParent.bottom; 00087 } 00088 else 00089 { 00090 m_cxLeftMost=rectParent.left; 00091 m_cxRightMost=rectParent.right; 00092 } 00093 00094 return 0; 00095 } 00096 00097 BOOL CSplitterBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 00098 { 00099 CPoint ptCursor=GetMessagePos(); 00100 if(IsCursorOverSplitter(ptCursor)) 00101 { 00102 ::SetCursor( AfxGetApp()->LoadCursor(m_bHorizontal?AFX_IDC_VSPLITBAR:AFX_IDC_HSPLITBAR)); 00103 return TRUE; 00104 } 00105 00106 return CWnd::OnSetCursor(pWnd, nHitTest, message); 00107 } 00108 00109 BOOL CSplitterBar::IsCursorOverSplitter( const CPoint& ptCursor ) 00110 { 00111 CRect rectSplitter; 00112 GetWindowRect(rectSplitter); 00113 return rectSplitter.PtInRect( ptCursor ); 00114 } 00115 00116 void CSplitterBar::OnMouseMove(UINT nFlags, CPoint point) 00117 { 00118 if(nFlags & MK_LBUTTON && m_bDragging) 00119 { 00120 DrawDraggingBar(point); 00121 return; 00122 } 00123 00124 CWnd::OnMouseMove(nFlags, point); 00125 } 00126 00127 void CSplitterBar::OnLButtonDown(UINT nFlags, CPoint point) 00128 { 00129 ClientToScreen(&point); 00130 if(IsCursorOverSplitter(point)) 00131 { 00132 SetCapture(); 00133 m_bDragging=TRUE; 00134 GetWindowRect(&m_rectSplitter); 00135 ScreenToClient(&point); 00136 DrawDraggingBar(point,DRAG_ENTER); 00137 return; 00138 } 00139 00140 CWnd::OnLButtonDown(nFlags, point); 00141 } 00142 00143 void CSplitterBar::OnLButtonUp(UINT nFlags, CPoint point) 00144 { 00145 if(m_bDragging) 00146 { 00147 DrawDraggingBar(point,DRAG_EXIT); 00148 //Move the splitter here 00149 ClientToScreen(&point); 00150 00151 //with in client area? 00152 if(m_bHorizontal) 00153 { 00154 CPoint pointLeftMost; 00155 pointLeftMost.y=m_cxLeftMost; 00156 GetParent()->ClientToScreen(&pointLeftMost); 00157 CPoint pointRightMost; 00158 pointRightMost.y=m_cxRightMost; 00159 GetParent()->ClientToScreen(&pointRightMost); 00160 00161 if(point.y < pointLeftMost.y) 00162 point.y=pointLeftMost.y; 00163 if(point.y > pointRightMost.y) 00164 point.y=pointRightMost.y; 00165 00166 m_rectDragCurt=m_rectSplitter; 00167 m_rectDragCurt.top=point.y; 00168 m_rectDragCurt.bottom=point.y+m_rectSplitter.Height(); 00169 } 00170 else 00171 { 00172 CPoint pointLeftMost; 00173 pointLeftMost.x=m_cxLeftMost; 00174 GetParent()->ClientToScreen(&pointLeftMost); 00175 CPoint pointRightMost; 00176 pointRightMost.x=m_cxRightMost; 00177 GetParent()->ClientToScreen(&pointRightMost); 00178 00179 if(point.x < pointLeftMost.x) 00180 point.x=pointLeftMost.x; 00181 if(point.x > pointRightMost.x) 00182 point.x=pointRightMost.x; 00183 00184 m_rectDragCurt=m_rectSplitter; 00185 m_rectDragCurt.left=point.x; 00186 m_rectDragCurt.right=point.x+m_rectSplitter.Width(); 00187 } 00188 GetParent()->ScreenToClient(m_rectDragCurt); 00189 MoveWindow(m_rectDragCurt,TRUE); 00190 OnPaint(); 00191 00192 ReleaseCapture(); 00193 m_bDragging=FALSE; 00194 MovePanes(); 00195 GetParent()->SendMessage(WM_SPLITTER_MOVED,0,0L); 00196 } 00197 00198 CWnd::OnLButtonUp(nFlags, point); 00199 } 00200 00201 void CSplitterBar::DrawDraggingBar(CPoint point,DRAGFLAG df) 00202 { 00203 ClientToScreen(&point); 00204 m_rectDragCurt=m_rectSplitter; 00205 if(m_bHorizontal) 00206 { 00207 CPoint pointLeftMost; 00208 pointLeftMost.y=m_cxLeftMost; 00209 GetParent()->ClientToScreen(&pointLeftMost); 00210 CPoint pointRightMost; 00211 pointRightMost.y=m_cxRightMost; 00212 GetParent()->ClientToScreen(&pointRightMost); 00213 00214 if(point.y < pointLeftMost.y) 00215 point.y=pointLeftMost.y; 00216 if(point.y > pointRightMost.y) 00217 point.y=pointRightMost.y; 00218 00219 m_rectDragCurt.top=point.y; 00220 m_rectDragCurt.bottom=point.y+m_rectSplitter.Height(); 00221 } 00222 else 00223 { 00224 CPoint pointLeftMost; 00225 pointLeftMost.x=m_cxLeftMost; 00226 GetParent()->ClientToScreen(&pointLeftMost); 00227 CPoint pointRightMost; 00228 pointRightMost.x=m_cxRightMost; 00229 GetParent()->ClientToScreen(&pointRightMost); 00230 00231 if(point.x < pointLeftMost.x) 00232 point.x=pointLeftMost.x; 00233 if(point.x > pointRightMost.x) 00234 point.x=pointRightMost.x; 00235 m_rectDragCurt.left=point.x; 00236 m_rectDragCurt.right=point.x+m_rectSplitter.Width(); 00237 } 00238 00239 CSize size(m_rectDragCurt.Width(),m_rectDragCurt.Height()); 00240 00241 CWnd *pParentWnd=GetParent(); 00242 ASSERT(pParentWnd); 00243 CDC *pDC=pParentWnd->GetDC(); 00244 pParentWnd->ScreenToClient(m_rectDragCurt); 00245 switch(df) 00246 { 00247 case DRAG_ENTER: 00248 pDC->DrawDragRect(m_rectDragCurt,size,NULL,size); 00249 break; 00250 case DRAG_EXIT: //fall through 00251 default: 00252 pDC->DrawDragRect(m_rectDragCurt,size,m_rectDragPrev,size); 00253 break; 00254 } 00255 00256 pParentWnd->ReleaseDC(pDC); 00257 m_rectDragPrev=m_rectDragCurt; 00258 } 00259 00260 void CSplitterBar::SetPanes(CWnd *pwndLeftPane,CWnd *pwndRightPane) 00261 { 00262 ASSERT(pwndLeftPane); 00263 ASSERT(pwndRightPane); 00264 00265 m_pwndLeftPane=pwndLeftPane; 00266 m_pwndRightPane=pwndRightPane; 00267 00268 if(m_bHorizontal) 00269 { 00270 //Initialize splitter bar position & size 00271 CRect rectBar; 00272 pwndLeftPane->GetWindowRect(rectBar); 00273 GetParent()->ScreenToClient(rectBar); 00274 rectBar.top=rectBar.bottom; 00275 00276 // Modified by Tihamer Levendovszky 2002 July 00277 CRect rectRightPane; 00278 pwndRightPane->GetWindowRect(rectRightPane); 00279 GetParent()->ScreenToClient(rectRightPane); 00280 int nDist=rectRightPane.top-rectBar.bottom; 00281 00282 int nBarWidth=GetSystemMetrics(SM_CXFRAME); 00283 rectBar.top-=(nBarWidth/2); 00284 rectBar.top+=nDist/2; 00285 00286 rectBar.bottom+=nBarWidth/2; 00287 rectBar.bottom+=nDist/2; 00288 00289 MoveWindow(rectBar); 00290 00291 //repostion top & bottom panes 00292 MovePanes(); 00293 00294 //calculate top most and bottom most coordinator 00295 CRect rectLeft; 00296 m_pwndLeftPane->GetWindowRect(rectLeft); 00297 GetParent()->ScreenToClient(rectLeft); 00298 m_cxLeftMost=rectLeft.top; 00299 00300 CRect rectRight; 00301 m_pwndRightPane->GetWindowRect(rectRight); 00302 GetParent()->ScreenToClient(rectRight); 00303 m_cxRightMost=rectRight.bottom; 00304 } 00305 else 00306 { 00307 //Initialize splitter bar position & size 00308 CRect rectBar; 00309 pwndLeftPane->GetWindowRect(rectBar); 00310 GetParent()->ScreenToClient(rectBar); 00311 rectBar.left=rectBar.right; 00312 int nBarWidth=GetSystemMetrics(SM_CYFRAME); 00313 rectBar.left-=nBarWidth/2; 00314 rectBar.right+=nBarWidth/2; 00315 MoveWindow(rectBar); 00316 00317 //repostion left & rigth panes 00318 MovePanes(); 00319 00320 //calculate left most and right most coordinator 00321 CRect rectLeft; 00322 m_pwndLeftPane->GetWindowRect(rectLeft); 00323 GetParent()->ScreenToClient(rectLeft); 00324 m_cxLeftMost=rectLeft.left; 00325 00326 CRect rectRight; 00327 m_pwndRightPane->GetWindowRect(rectRight); 00328 GetParent()->ScreenToClient(rectRight); 00329 m_cxRightMost=rectRight.right; 00330 } 00331 } 00332 00333 void CSplitterBar::MovePanes() 00334 { 00335 ASSERT(m_pwndLeftPane); 00336 ASSERT(m_pwndRightPane); 00337 00338 if(m_bHorizontal) 00339 { 00340 //Get position of the splitter bar 00341 CRect rectBar; 00342 GetWindowRect(rectBar); 00343 GetParent()->ScreenToClient(rectBar); 00344 00345 //reposition top pane 00346 CRect rectLeft; 00347 m_pwndLeftPane->GetWindowRect(rectLeft); 00348 GetParent()->ScreenToClient(rectLeft); 00349 rectLeft.bottom=rectBar.top-GetSystemMetrics(SM_CXBORDER); 00350 m_pwndLeftPane->MoveWindow(rectLeft); 00351 00352 //reposition bottom pane 00353 CRect rectRight; 00354 m_pwndRightPane->GetWindowRect(rectRight); 00355 GetParent()->ScreenToClient(rectRight); 00356 rectRight.top=rectBar.bottom+GetSystemMetrics(SM_CXBORDER); 00357 m_pwndRightPane->MoveWindow(rectRight); 00358 00359 ChangeHelpControls(rectRight); 00360 } 00361 else 00362 { 00363 //Get position of the splitter bar 00364 CRect rectBar; 00365 GetWindowRect(rectBar); 00366 GetParent()->ScreenToClient(rectBar); 00367 00368 //reposition left pane 00369 CRect rectLeft; 00370 m_pwndLeftPane->GetWindowRect(rectLeft); 00371 GetParent()->ScreenToClient(rectLeft); 00372 rectLeft.right=rectBar.left+GetSystemMetrics(SM_CYBORDER); 00373 m_pwndLeftPane->MoveWindow(rectLeft); 00374 00375 //reposition right pane 00376 CRect rectRight; 00377 m_pwndRightPane->GetWindowRect(rectRight); 00378 GetParent()->ScreenToClient(rectRight); 00379 rectRight.left=rectBar.right-GetSystemMetrics(SM_CYBORDER);; 00380 m_pwndRightPane->MoveWindow(rectRight); 00381 } 00382 00383 //repaint client area 00384 GetParent()->Invalidate(); 00385 } 00386 00387 00388 #include "resource.h" 00389 void CSplitterBar::ChangeHelpControls(CRect ctrlRect) 00390 { 00391 00392 CWnd* pHelpTitleCtrl=GetParent()->GetDlgItem(IDC_HELP_TITLE); 00393 if (pHelpTitleCtrl->GetSafeHwnd()) 00394 { 00395 static int yDPI = 0; 00396 if (yDPI == 0) { 00397 HDC dc = ::GetDC(NULL); 00398 yDPI = ::GetDeviceCaps(dc, LOGPIXELSY); 00399 ::ReleaseDC(NULL, dc); 00400 } 00401 00402 int INSP_HELP_TITLE_HEIGHT = 15 * yDPI / 96 /* USER_DEFAULT_SCREEN_DPI */; 00403 pHelpTitleCtrl->SetWindowPos(NULL,ctrlRect.left+1,ctrlRect.top+1,ctrlRect.Width()-2, 00404 INSP_HELP_TITLE_HEIGHT,SWP_NOZORDER); 00405 00406 CWnd* pHelpTextCtrl=GetParent()->GetDlgItem(IDC_HELP_TEXT); 00407 if(pHelpTextCtrl->GetSafeHwnd()) 00408 { 00409 pHelpTextCtrl->SetWindowPos(NULL, 00410 ctrlRect.left+1, 00411 ctrlRect.top+INSP_HELP_TITLE_HEIGHT+2, 00412 ctrlRect.Width()-2, 00413 ctrlRect.Height()-INSP_HELP_TITLE_HEIGHT-3, 00414 SWP_NOZORDER); 00415 } 00416 } 00417 00418 }