前因:
本來想用MFC做一個按不了的按鈕(鼠標移動到按鈕上方,按鈕就會移走),使用WM_MOUSEMOVE消息發現
鼠標在按鈕上時不會給父窗口發送WM_MOUSEMOVE消息
解決辦法:
使用SetCapture()函數捕獲鼠標消息
setCapture捕獲以下鼠標事件:onmousedown、onmouseup、onclick、ondblclick、onmouseover和onmouseout
其中剛好有我們需要捕獲到的消息,不過這個函數有點霸道,捕獲期間不能做別的事件,所以需要及時釋放
釋放使用ReleaseCapture()函數
注意:
SetCapture()函數貌似需要程序擁有管理員權限
void CBiaoBai1Dlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息處理程序代碼和/或調用默認值 CDialogEx::OnMouseMove(nFlags, point); //設置鼠標捕獲 SetCapture(); //獲取不同意按鈕位置(相對於顯示屏左上角的) CRect rect_disagree; m_Disagree_Button.GetWindowRect(&rect_disagree); //獲取同意按鈕位置 CRect rect_agree; m_agree.GetWindowRect(&rect_agree); //獲取考慮按鈕位置 CRect rect_think; m_think.GetWindowRect(&rect_think); //獲取不同意按鈕寬和高 int height = rect_disagree.Height(); int width = rect_disagree.Width(); //將客戶端坐標轉換為屏幕坐標 ClientToScreen(&point); //判斷鼠標是否落在同意與考慮按鈕上 //如果落在他們上,就釋放鼠標捕獲 if (rect_agree.PtInRect(point) || rect_think.PtInRect(point)) { //釋放鼠標捕獲 ReleaseCapture(); } rect_disagree.NormalizeRect(); BOOL ret = PtInRect(rect_disagree,point); if (ret) { //獲取客戶端大小 CRect rect; GetClientRect(&rect); //確定隨機移動的范圍在客戶端內 //如果落在同意與考慮按鈕上就再次隨機 int re_x; int re_y; CPoint point_youxia; CPoint point_youshang; CPoint point_zuoxia; do { re_x = rand() % (rect.right - width); re_y = rand() % (rect.bottom - height); point.SetPoint(re_x, re_y); //將客戶端坐標轉換為屏幕坐標 ClientToScreen(&point); point_youxia.SetPoint(point.x + width, point.y + height); point_youshang.SetPoint(point.x + width, point.y); point_zuoxia.SetPoint(point.x, point.y + height); } while (rect_agree.PtInRect(point) || rect_think.PtInRect(point) || rect_agree.PtInRect(point_youxia) || rect_think.PtInRect(point_youxia) || rect_agree.PtInRect(point_youshang) || rect_think.PtInRect(point_youshang) || rect_agree.PtInRect(point_zuoxia) || rect_think.PtInRect(point_zuoxia)); rect.SetRect(re_x, re_y, re_x + width, re_y + height); m_Disagree_Button.MoveWindow(&rect, TRUE); } }