前因:
本来想用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); } }