基础知识:鼠标在窗口内移动,点击或者释放时都会产生WM_NCHITTEST消息,响应函数OnNcHitTest会返回一个枚举值,系统会根据这个枚举值进行相应的处理。当返回值为HTCAPTION时,系统会认为此时鼠标位于标题栏上,于是当鼠标按下并移动时就会执行拖动操做。
LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT pt; RECT rcClient; RECT rcCaption; rcCaption = m_pm.GetCaptionRect(); GetClientRect(m_pm.GetPaintWindow(), &rcClient); pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); ::ScreenToClient(m_pm.GetPaintWindow(), &pt); //xml中设置bottom为-1时,整个窗口区域均可以拖动 if (-1 == rcCaption.bottom) { rcCaption.bottom = rcClient.bottom; } if ((pt.x >= rcClient.left) && (pt.x < rcClient.right) && (pt.y >= rcCaption.top) && (pt.y < rcCaption.bottom)) { return HTCAPTION; } return __super::OnNcHitTest(uMsg, wParam, lParam, bHandled); }
基础知识:咱们能够模拟在win32中窗口移动的函数处理过程。简单的说,咱们只须要在本身的窗口中对WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP这三个消息进行处理便可。在WM_LBUTTONDOWN中记录鼠标左键被按下时的信息,WM_MOUSEMOVE中记录鼠标移动距离,WM_LBUTTONUP记录鼠标左键弹起。
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { //记录鼠标按下 is_lbutton_down_ = true; //鼠标按下时的坐标 start_point_.x = GET_X_LPARAM(lParam); start_point_.y = GET_Y_LPARAM(lParam); bHandled = TRUE; return 0; } LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { //左键弹起,改变鼠标状态 is_lbutton_down_ = false; bHandled = TRUE; return 0; } LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (is_lbutton_down_ == true) { POINT point; //获取当前鼠标的位置 ::GetCursorPos(&point); ::ScreenToClient(m_pm.GetPaintWindow(), &point); //获取新的位置 int Dx = point.x - start_point_.x; int Dy = point.y - start_point_.y; start_rect_.left += Dx; start_rect_.right += Dx; start_rect_.top += Dy; start_rect_.bottom += Dy; //将窗口移到新的位置 SetWindowPos(m_hWnd, HWND_TOP, start_rect_.left, start_rect_.top, 0, 0, SWP_NOSIZE); } bHandled = TRUE; return 0; }
MSDN:The _TrackMouseEvent function posts messages when the mouse pointer leaves a window or hovers over a window for a specified amount of time. This function calls TrackMouseEvent if it exists, otherwise it emulates it.
具体方法以下:函数
BOOL is_mouse_track_=TRUE ;
if (is_mouse_track_) { TRACKMOUSEEVENT csTME; csTME.cbSize = sizeof (csTME); csTME.dwFlags = TME_LEAVE|TME_HOVER; csTME.hwndTrack = m_hWnd ; csTME.dwHoverTime = 10; // 鼠标在按钮上停留超过10ms ,才认为状态 HOVER ::_TrackMouseEvent (&csTME); is_mouse_track_=FALSE ; }
is_mouse_track_=TRUE ;