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 m_rectDragCurt.top=point.y; 00208 m_rectDragCurt.bottom=point.y+m_rectSplitter.Height(); 00209 } 00210 else 00211 { 00212 m_rectDragCurt.left=point.x; 00213 m_rectDragCurt.right=point.x+m_rectSplitter.Width(); 00214 } 00215 00216 CSize size(m_rectDragCurt.Width(),m_rectDragCurt.Height()); 00217 00218 CWnd *pParentWnd=GetParent(); 00219 ASSERT(pParentWnd); 00220 CDC *pDC=pParentWnd->GetDC(); 00221 pParentWnd->ScreenToClient(m_rectDragCurt); 00222 switch(df) 00223 { 00224 case DRAG_ENTER: 00225 pDC->DrawDragRect(m_rectDragCurt,size,NULL,size); 00226 break; 00227 case DRAG_EXIT: //fall through 00228 default: 00229 pDC->DrawDragRect(m_rectDragCurt,size,m_rectDragPrev,size); 00230 break; 00231 } 00232 00233 pParentWnd->ReleaseDC(pDC); 00234 m_rectDragPrev=m_rectDragCurt; 00235 } 00236 00237 void CSplitterBar::SetPanes(CWnd *pwndLeftPane,CWnd *pwndRightPane) 00238 { 00239 ASSERT(pwndLeftPane); 00240 ASSERT(pwndRightPane); 00241 00242 m_pwndLeftPane=pwndLeftPane; 00243 m_pwndRightPane=pwndRightPane; 00244 00245 if(m_bHorizontal) 00246 { 00247 //Initialize splitter bar position & size 00248 CRect rectBar; 00249 pwndLeftPane->GetWindowRect(rectBar); 00250 GetParent()->ScreenToClient(rectBar); 00251 rectBar.top=rectBar.bottom; 00252 int nBarWidth=GetSystemMetrics(SM_CXFRAME); 00253 rectBar.top-=nBarWidth/2; 00254 rectBar.bottom+=nBarWidth/2; 00255 MoveWindow(rectBar); 00256 00257 //repostion top & bottom panes 00258 MovePanes(); 00259 00260 //calculate top most and bottom most coordinator 00261 CRect rectLeft; 00262 m_pwndLeftPane->GetWindowRect(rectLeft); 00263 GetParent()->ScreenToClient(rectLeft); 00264 m_cxLeftMost=rectLeft.top; 00265 00266 CRect rectRight; 00267 m_pwndRightPane->GetWindowRect(rectRight); 00268 GetParent()->ScreenToClient(rectRight); 00269 m_cxRightMost=rectRight.bottom; 00270 } 00271 else 00272 { 00273 //Initialize splitter bar position & size 00274 CRect rectBar; 00275 pwndLeftPane->GetWindowRect(rectBar); 00276 GetParent()->ScreenToClient(rectBar); 00277 rectBar.left=rectBar.right; 00278 int nBarWidth=GetSystemMetrics(SM_CYFRAME); 00279 rectBar.left-=nBarWidth/2; 00280 rectBar.right+=nBarWidth/2; 00281 MoveWindow(rectBar); 00282 00283 //repostion left & rigth panes 00284 MovePanes(); 00285 00286 //calculate left most and right most coordinator 00287 CRect rectLeft; 00288 m_pwndLeftPane->GetWindowRect(rectLeft); 00289 GetParent()->ScreenToClient(rectLeft); 00290 m_cxLeftMost=rectLeft.left; 00291 00292 CRect rectRight; 00293 m_pwndRightPane->GetWindowRect(rectRight); 00294 GetParent()->ScreenToClient(rectRight); 00295 m_cxRightMost=rectRight.right; 00296 } 00297 } 00298 00299 void CSplitterBar::MovePanes() 00300 { 00301 ASSERT(m_pwndLeftPane); 00302 ASSERT(m_pwndRightPane); 00303 00304 if(m_bHorizontal) 00305 { 00306 //Get position of the splitter bar 00307 CRect rectBar; 00308 GetWindowRect(rectBar); 00309 GetParent()->ScreenToClient(rectBar); 00310 00311 //reposition top pane 00312 CRect rectLeft; 00313 m_pwndLeftPane->GetWindowRect(rectLeft); 00314 GetParent()->ScreenToClient(rectLeft); 00315 rectLeft.bottom=rectBar.top+GetSystemMetrics(SM_CXBORDER); 00316 m_pwndLeftPane->MoveWindow(rectLeft); 00317 00318 //reposition bottom pane 00319 CRect rectRight; 00320 m_pwndRightPane->GetWindowRect(rectRight); 00321 GetParent()->ScreenToClient(rectRight); 00322 rectRight.top=rectBar.bottom-GetSystemMetrics(SM_CXBORDER);; 00323 m_pwndRightPane->MoveWindow(rectRight); 00324 } 00325 else 00326 { 00327 //Get position of the splitter bar 00328 CRect rectBar; 00329 GetWindowRect(rectBar); 00330 GetParent()->ScreenToClient(rectBar); 00331 00332 //reposition left pane 00333 CRect rectLeft; 00334 m_pwndLeftPane->GetWindowRect(rectLeft); 00335 GetParent()->ScreenToClient(rectLeft); 00336 rectLeft.right=rectBar.left+GetSystemMetrics(SM_CYBORDER); 00337 m_pwndLeftPane->MoveWindow(rectLeft); 00338 00339 //reposition right pane 00340 CRect rectRight; 00341 m_pwndRightPane->GetWindowRect(rectRight); 00342 GetParent()->ScreenToClient(rectRight); 00343 rectRight.left=rectBar.right-GetSystemMetrics(SM_CYBORDER);; 00344 m_pwndRightPane->MoveWindow(rectRight); 00345 } 00346 00347 //repaint client area 00348 GetParent()->Invalidate(); 00349 }