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                 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 }