GME  13
SplitterBar.cpp
Go to the documentation of this file.
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 }