这里直接贴上MFC window程序设计的代码,然后加上编程需要注意的地方
CMainWindow::CMainWindow () { m_bTracking = FALSE; m_bCaptureEnabled = TRUE; // // Register a WNDCLASS. // CString strWndClass = AfxRegisterWndClass ( 0, AfxGetApp ()->LoadStandardCursor (IDC_CROSS), //加载window的十字光标 (HBRUSH) (COLOR_WINDOW + 1), AfxGetApp ()->LoadStandardIcon (IDI_WINLOGO) ); // // Create a window. // Create (strWndClass, _T ("Mouse Capture Demo (Capture Enabled)")); } void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point) { // // Record the anchor point and set the tracking flag. // m_ptFrom = point; m_ptTo = point; m_bTracking = TRUE; // // If capture is enabled, capture the mouse. // if (m_bCaptureEnabled) SetCapture (); //这里“捕获”鼠标,意思是即使鼠标不在客户区,也发送鼠标消息到窗口 } void CMainWindow::OnMouseMove (UINT nFlags, CPoint point) { // // If the mouse is moved while we're "tracking" (that is, while a // line is being rubber-banded), erase the old rubber-band line and // draw a new one. // if (m_bTracking) { CClientDC dc (this); InvertLine (&dc, m_ptFrom, m_ptTo); InvertLine (&dc, m_ptFrom, point); m_ptTo = point; } } void CMainWindow::OnLButtonUp (UINT nFlags, CPoint point) { // // If the left mouse button is released while we're tracking, release // the mouse if it's currently captured, erase the last rubber-band // line, and draw a thick red line in its place. //
//假如没有捕获鼠标,鼠标在非客户区抬起时,不会发送消息到窗口
if (m_bTracking) {
m_bTracking = FALSE; if (GetCapture () == this) ::ReleaseCapture (); //假如有捕获鼠标,在这一定要释放掉 CClientDC dc (this); InvertLine (&dc, m_ptFrom, m_ptTo); CPen pen (PS_SOLID, 16, RGB (255, 0, 0)); dc.SelectObject (&pen); dc.MoveTo (m_ptFrom); dc.LineTo (point); } } void CMainWindow::OnNcLButtonDown (UINT nHitTest, CPoint point) { // // When the window's title bar is clicked with the left mouse button, // toggle the capture flag on or off and update the window title. //
//非客户区鼠标左键点击会发送此消息
if (nHitTest == HTCAPTION) { m_bCaptureEnabled = m_bCaptureEnabled ? FALSE : TRUE; SetWindowText (m_bCaptureEnabled ? _T ("Mouse Capture Demo (Capture Enabled)") : _T ("Mouse Capture Demo (Capture Disabled)")); } CFrameWnd::OnNcLButtonDown (nHitTest, point); //这里要把消息发给子类,让window去处理,否则鼠标的其他操作会失效 } void CMainWindow::InvertLine (CDC* pDC, CPoint ptFrom, CPoint ptTo) { // // Invert a line of pixels by drawing a line in the R2_NOT drawing mode. // int nOldMode = pDC->SetROP2 (R2_NOT); //这是设置前背景渲染模式,R2_NOT是取反 pDC->MoveTo (ptFrom); pDC->LineTo (ptTo); pDC->SetROP2 (nOldMode); }