void TSplitter::DoMouseUp(const TPoint& mouse, TMouseButton button, TModifierState state) { if (fTracking && button == kLeftButton) { TPoint point; ConstrainMouse(mouse, point); if (!fLiveDrag) { TRect rect; GetTrackingRect(fLastMouse, rect); DrawTrackingRect(rect); TRect bounds; GetLocalBounds(bounds); if (fVertical) fRatio = (float)point.h / (float)bounds.GetWidth(); else fRatio = (float)point.v / (float)bounds.GetHeight(); if (fRatio < 0.0) fRatio = 0.0; else if (fRatio > 1.0) fRatio = 1.0; ResizeChildren(); } fTracking = false; } }
void TSplitter::DoMouseDown(const TPoint& mouse, TMouseButton button, TModifierState state) { if (! fTracking && button == kLeftButton) { TPoint point; ConstrainMouse(mouse, point); if (!fLiveDrag) { TRect rect; GetTrackingRect(point, rect); DrawTrackingRect(rect); } fTracking = true; fLastMouse = point; } }
void TSplitter::DoMouseMoved(const TPoint& mouse, TModifierState state) { if (fTracking) { TPoint point; ConstrainMouse(mouse, point); if ((fVertical && fLastMouse.h != point.h) || (!fVertical && fLastMouse.v != point.v)) { if (fLiveDrag) { TRect bounds; GetLocalBounds(bounds); if (fVertical) fRatio = (float)point.h / (float)bounds.GetWidth(); else fRatio = (float)point.v / (float)bounds.GetHeight(); if (fRatio < 0.0) fRatio = 0.0; else if (fRatio > 1.0) fRatio = 1.0; ResizeChildren(); TDrawContext context(this); DrawSplitterRect(context); } else { TRect rect; GetTrackingRect(fLastMouse, rect); DrawTrackingRect(rect); GetTrackingRect(point, rect); DrawTrackingRect(rect); } } fLastMouse = point; } }
// Track mouse bool CMouseTracker::Track(HWND hWnd, POINT& pt) { // Capture mouse SetCapture(hWnd); // Constrain to bounds SnapMouse(pt); ConstrainMouse(pt); // Store attributes m_hWnd=hWnd; m_ptStart=pt; if (m_bLockWindowUpdate) { // Update the window RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW|RDW_ALLCHILDREN); LockWindowUpdate(m_hWnd); } // Call start handler OnStarting(m_ptStart); if (m_bAutoScroll) { m_dwLastScrollAt=GetTickCount(); SetTimer(m_hWnd, AUTOSCROLL_TIMER_ID, AUTOSCROLL_TIMER_PERIOD, NULL); } if (m_bHoverDetect) { m_dwHoverStart=GetTickCount(); SetTimer(m_hWnd, HOVER_TIMER_ID, HOVER_TIMER_PERIOD, NULL); } // Spin message loop bool bCancelled=true; bool bMoved=false; while (true) { // Get a message MSG msg; if (!GetMessage(&msg, NULL, 0, 0)) break; // Dispatch all non-input messages if (!IsInputMessage(msg.message) && !(msg.message==WM_TIMER && (msg.wParam==AUTOSCROLL_TIMER_ID || msg.wParam==HOVER_TIMER_ID))) { DispatchMessage(&msg); continue; } // Quit if lost capture if (GetCapture()!=m_hWnd) break; // Handle message switch (msg.message) { case WM_TIMER: if (m_bHoverDetect && m_dwHoverStart && msg.wParam==HOVER_TIMER_ID) { if (GetTickCount() > m_dwHoverStart+HOVER_TIMEOUT) { POINT pt; GetCursorPos(&pt); ScreenToClient(m_hWnd, &pt); m_dwHoverStart=0; OnHover(pt); } break; } if (msg.wParam!=AUTOSCROLL_TIMER_ID) break; { POINT pt; GetCursorPos(&pt); ScreenToClient(m_hWnd, &pt); msg.lParam=MAKELPARAM(pt.x, pt.y); // Fall throught to fake a WM_MOUSEMOVE } case WM_MOUSEMOVE: { // Get new point POINT ptNew; ptNew.x=(int)(short)LOWORD(msg.lParam); ptNew.y=(int)(short)HIWORD(msg.lParam); if (ptNew.x!=m_ptStart.x || ptNew.y!=m_ptStart.y) bMoved=true; // Get client rectangle if (m_bAutoScroll) { // Outside client area? RECT rcClient; GetClientRect(m_hWnd, &rcClient); if (!PtInRect(&rcClient, ptNew) && GetTickCount()>m_dwLastScrollAt + AUTOSCROLL_FREQUENCY) { // Kill old feedback DrawFeedback(); // Release DC if (m_bLockWindowUpdate) { LockWindowUpdate(NULL); } // Do scrolling if (ptNew.x<rcClient.left) SendMessage(m_hWnd, WM_HSCROLL, SB_LINEUP, 0); if (ptNew.x>rcClient.right) SendMessage(m_hWnd, WM_HSCROLL, SB_LINEDOWN, 0); if (ptNew.y<rcClient.top) SendMessage(m_hWnd, WM_VSCROLL, SB_LINEUP, 0); if (ptNew.y>rcClient.bottom) SendMessage(m_hWnd, WM_VSCROLL, SB_LINEDOWN, 0); UpdateWindow(m_hWnd); // Get a newly clipped DC if (m_bLockWindowUpdate) { RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW|RDW_ALLCHILDREN); LockWindowUpdate(m_hWnd); } // Redraw feedback DrawFeedback(); m_dwLastScrollAt=GetTickCount(); } } // Adjust for scrolling POINT ptScrollOffset=GetScrollOffset(); ptNew.x+=ptScrollOffset.x; ptNew.y+=ptScrollOffset.y; // Constrain to bounds SnapMouse(ptNew); ConstrainMouse(ptNew); // Only handle if still moved after constraining if (ptNew.x!=pt.x || ptNew.y!=pt.y || msg.message==WM_TIMER) { if (msg.message!=WM_TIMER) { m_dwHoverStart=GetTickCount(); } // Call handler OnMove(pt, ptNew); // Store new point pt=ptNew; } } break; case WM_LBUTTONUP: case WM_RBUTTONUP: bCancelled=false; ReleaseCapture(); break; case WM_RBUTTONDOWN: ReleaseCapture(); break; case WM_KEYDOWN: if (msg.wParam==VK_ESCAPE) { ReleaseCapture(); break; } // Fall through case WM_KEYUP: case WM_SYSKEYDOWN: case WM_SYSKEYUP: // Call handler OnMove(pt, pt); break; } // Quit if lost capture if (GetCapture()!=m_hWnd) break; } if (m_bAutoScroll) { KillTimer(m_hWnd, AUTOSCROLL_TIMER_ID); } if (m_bHoverDetect) { KillTimer(m_hWnd, HOVER_TIMER_ID); } // Finished OnFinished(pt, bCancelled); // Clean up if (m_bLockWindowUpdate) { LockWindowUpdate(NULL); } return bMoved && !bCancelled; }