// Setup splitter position. void ClsSplitter::SetSplitterPosition( int nSplitPos ) { // Get the splitter rectangle. If it is // empty we use the parent client rectangle. ClsRect rc = m_SplitRect; if ( rc.IsEmpty()) GetParent()->GetClientRect( rc ); // Horizontal or vertical? int nMaxPos = m_bIsHorizontal ? rc.Width() : rc.Height(); nMaxPos -= m_nMinPane2 + SPLITTER_SIZE; // Make sure the splitter stays in range. if ( nSplitPos > nMaxPos ) nSplitPos = nMaxPos; if ( nSplitPos < m_nMinPane1 ) nSplitPos = m_nMinPane1; // Did it change? if ( m_nPosition != nSplitPos ) { // If the splitter bar is visible we render // it again at the same position to make it // disappear. if ( m_bIsVisible ) DrawSplitterBar(); // Setup the new position. m_nPosition = nSplitPos; // Draw the splitter bar. DrawSplitterBar(); } }
/** * @param hdc - drawing context. */ void CSplitter::DrawSplitter(HDC hdc) const { _ASSERTE(m_hwnd != NULL); DrawSplitterBar(hdc); DrawPanel(hdc, 0); DrawPanel(hdc, 1); }
// Window procedure override. LRESULT ClsSplitter::WindowProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_ERASEBKGND: { // Fill the entire client rectangle // with the same color as the button // background. ClsBrush b( ::GetSysColor( COLOR_BTNFACE )); ::FillRect(( HDC )wParam, GetClientRect(), b ); return 0; } case WM_LBUTTONDOWN: { // Obtain a device context and attach it. if ( m_pDC.Attach( ::GetDC( *GetParent()))) { // Snapshot the device context. m_nSaveDC = m_pDC.SaveDC(); // OK? if ( m_nSaveDC ) { // Mark the current position. m_nStartPosition = m_nPosition; // Setup DC. m_pDC.SetROP2( R2_NOTXORPEN ); m_pDC.SelectObject( m_HatchBrush ); m_pDC.SelectObject( ::GetStockObject( NULL_PEN )); m_pDC.SetTextColor( RGB( 0, 0, 0 )); // Capture the mouse. SetCapture(); // We are moving the splitter. m_bIsMoving = TRUE; // We want the keyboard focus. m_hFocus = ::SetFocus( *this ); // Show the track bar. DrawSplitterBar(); return 0; } // Failure... ::ReleaseDC( *GetParent(), m_pDC.Detach()); } return 0; } case WM_MOUSEMOVE: // Are we moving the splitter? if ( m_bIsMoving ) { // Get the current mouse position. ClsPoint p; GetCursorPos( p ); // Map the position to our parent. GetParent()->ScreenToClient(p); // Get position (Horizontal or vertical). int nPos = m_bIsHorizontal ? p.X() : p.Y(); // Set splitter position. SetSplitterPosition( nPos ); return 0; } break; case WM_GETDLGCODE: // We want them all. return DLGC_WANTALLKEYS; case WM_KEYDOWN: // Are we moving the splitter or was a key // pressed other than escape? if ( ! m_bIsMoving || wParam != VK_ESCAPE ) // Pass the message to the base class. break; // Erase the splitter if necessary. if ( m_bIsVisible ) DrawSplitterBar(); // Restore the old position. m_nPosition = m_nStartPosition; // Fall through which will stop the // mouse tracking etc. case WM_LBUTTONUP: // Are we moving? if ( m_bIsMoving ) { // Make sure we are invisible. if ( m_bIsVisible ) DrawSplitterBar(); // Restore DC snapshot. m_pDC.RestoreDC( m_nSaveDC ); // Release it and detach it from the object. ::ReleaseDC( *GetParent(), m_pDC.Detach()); // Release the mouse. ReleaseCapture(); // No longer moving. m_bIsMoving = FALSE; // Move the panes. MoveSplitter(); // Restore the focus. ::SetFocus( m_hFocus ); } return 0; case WM_SETCURSOR: // Setup the correct cursor. if ( m_bIsHorizontal ) SetCursor( m_hVert ); else SetCursor( m_hHorz ); return 0; } // Call the base class. return ClsWindow::WindowProc( uMsg, wParam, lParam ); }