1.基本功能
OnMouseMove对鼠标移动时间的响应
OnMouseWheel响应鼠标中键的滚动
2.参数说明
afx_msgvoidOnMouseMove(UINT nFlags,CPoint point);
nFlags描述:指示是否按下了虚拟按钮,此参数可以是以下值的任意组合
按下CTRL键时的MK_CONTROL
按下鼠标左键时的MK_LBUTTON
按下鼠标中键(滚动不是按下)时的MK_MBUTTON
按下鼠标右键时会显示MK_RBUTTON。
按下SHIFT时的MK_SHIFT。
点描述:鼠标的X,Y坐标:此坐标是鼠标基点相对于其所在窗口左上角的位置。它是屏幕像素上的相对位置,而不是绝对位置。
afx_msg BOOL OnMouseWheel(UINTnFlags,shortzDelta,CPointpt);
nFlags与上述相同
zDelta:当它大于0时,向上滚动,而当它小于0时,向下滚动。小于零的值表示向后旋转(朝向用户),而大于零的值表示向后旋转(远离用户)。在Windows下,通常向上滚动以缩小/向上移动窗口,反之亦然。
pt ::鼠标的X和Y坐标基于父窗口的左上角。指定光标的x和y坐标。这些坐标始终相对于窗口的左上角。
实现3.运动的效果
要实现移动,例如用鼠标左键拖动按钮/图片在窗口上移动,就可以达到附加的结果要求:将鼠标放在按钮/图片的A点上,移动后,鼠标点仍在点A
我们通过了
a。检查鼠标是否在按钮/图片上(确保不能将图标移动到任何地方),然后按向左按钮
b。记录鼠标的当前点和最后一点,计算两者的偏移值,然后使用此偏移值移动按钮/图片(MoveWindows)
(记录最后一点的方法可以使用静态变量。完成移动后,将当前点分配给静态变量)(具体实现可以灵活处理)
实现原理是:相对静态-鼠标和对象的相对位置保持不变,鼠标的偏移量就是对象的偏移量
4.实现缩放效果(以鼠标点为中心进行缩放)
要实现缩放,例如滑动中间轮以放大或缩小以放大按钮/图像,还需要满足其他要求:将鼠标放在按钮/图像的A点上,缩放后,鼠标点仍在点A上,并且缩放以鼠标点为中心

a。还要检测鼠标在按钮/图片上(确保您可以缩放按钮/图片的位置不是全部)
b。获取当前按钮/图片的高度和宽度(使用getClientRect)
c。获取相对于按钮/图片位置的当前pt点x,y,然后计算该位置相对于宽度和高度的比例
d。确定zDelta是正值还是负值以放大和缩小(按比例调整图片的高度和宽度),并调整图片左上点(左,上)的位置,以确保c中的比率保持不变(---确保鼠标在中央放大或缩小)
实现原理是:相对运动---鼠标和对象点的位置保持不变,鼠标周围对象点的长和宽成比例缩放。
鼠标事件
在每天使用的许多软件中,当鼠标停留在某个事件的特定菜单或按钮上时,会弹出有关该空间的一些提示信息。提示信息可以通过使用MFC中的CToolTipCtrl类并输出提示来实现,这并不困难,但是如何确定鼠标是否位于某个按钮上呢?您可以在对话框中响应WM_SETCOUSE消息。在响应事件中,可以确定发生事件的窗口的句柄是否是控件的句柄。如果是响应操作,则确定光标是否离开控件相对较复杂。因为在光标离开控件后,接收到鼠标移动消息的窗口句柄绝对不是控件句柄,可以通过以下方式解决:
BOOLCMy12Dlg :: OnSetCursor(CWnd * pWnd,UINT nHitTest,UINT消息)
{
if(pWnd-> GetDlgCtrlID()== IDC_BUTTON 3)
{
pWnd-> SetWindowTextW(_T(“ Hover”));
}
elseif(pWnd-> GetDlgCtrlID()!= IDC_BUTTON 3)
{
GetDlgItem(IDC_BUTTON 3)-> SetWindowTextW(_T(“ Leave”)));
}
returnCDialogEx :: OnSetCursor(pWnd,nHitTest,message);
}
(注意:以这种方式,当鼠标快速移动时,似乎鼠标已离开了按钮,但按钮仍显示出鼠标停留在其上的现象。)
但是,如果有多个这样的控件,是否应该不必使用其他ifs来确定该句柄是否是相应的控件句柄?这有点不合理。有更好的解决方案吗?
实验后,以下方法是可行且相对最佳的:
从Cbutton派生MyHoverBtn子类,响应该子类中的WM_MOUSEMOVE事件,并将以下代码添加到该事件的响应函数中,以响应鼠标的Hover和Leave事件:
voidMyHoverBtn :: OnMouseMove(UINT nFlags,CPointpoint)
{

TRACKMOUSEEVENT mouse_event; //定义鼠标移动事件结构
mouse_event.cbSize = sizeof(mouse_event); //定义结构的大小
mouse_event.hwndTrack = m_hWnd; //关联的窗口句柄
mouse_event.dwFlags = TME_HOVER | TME_LEAVE; //设置响应标志
mouse_event.dwHoverTime = 100 / * HOVER_DEFAULT = 400 * /; //设置悬停时间
_TrackMouseEvent(&mouse_event);
CButton :: OnMouseMove(nFlags,point);
}
然后响应子类MyHoverBtn中的WM_MOUSEHOVER和WM_MOUSELEAVE消息,并将实现代码添加到相应的事件响应函数中;例如
voidMyHoverBtn :: OnMouseLeave()
{
this-> SetWindowTextW(_T(“ I left〜”));
CButton :: OnMouseLeave();
}
voidMyHoverBtn :: OnMouseHover(UINT nFlags,CPointpoint)
{
this-> SetWindowTextW(_T(“我在这里〜”));
CButton :: OnMouseHover(nFlags,point);
}
Internet上的某些人说,您可以覆盖对话框中的PreTranslateMessage函数来确定消息类型和控件句柄。如果消息是WM_MOUSEMOVE,并且事件发生的控件句柄是您要控制的控件句柄,则对其进行响应。代码如下:
BOOLCMy12Dlg :: PreTranslateMessage(MSG * pMsg)
{
CWnd * pWnd = GetDlgItem(IDC_BUTTON 1);
if(pMsg-> hwnd == pWnd-> GetSafeHwnd()&& pMsg-> message == WM_MOUSEMOVE)
{

CPoint点(pMsg-> pt);
pWnd-> ScreenToClient(&point);
CRect rect;
pWnd-> GetClientRect(&rect);
if(rect.PtInRect(point))
pWnd-> SetWindowTextW(_T(“ Hover”));
其他
pWnd-> SetWindowTextW(_T(“ Leave”));
returnTRUE;
}
returnCDialogEx :: PreTranslateMessage(pMsg);
}
请注意绿色部分,此处不合理,因为当光标离开按钮控件时,鼠标移动的事件目标控件不是按钮。该方法与本文开头的方法相同,并且需要其他判断。···
提到了几种方法,最好派生子类,然后响应子类中的鼠标移动消息以进行相应的操作。但是,如果您根据默认的HOVER_DEFAULT设置(即时间为400毫秒)设置了悬停时间,那么您需要等待此时间以在鼠标移至控件后响应OnMouseHover(),因此我减少了时间到100毫秒。更加合理,如下所示:
mouse_event.dwHoverTime = 100 / * HOVER_DEFAULT = 400 * /; //设置悬停时间
我只是不明白时间是否设置为非常小的值,会导致程序不断获取鼠标移动消息,从而增加CPU使用率吗?
测试后,时间设置为1毫秒。与100毫秒的设置相比,CPU不会显着增加。 MSDN解释该参数如下:
dwHoverTime
指定悬停超时(如果在dwFlags中指定了TME_HOVER),以毫秒为单位。可以为HOVER_DEFAULT,表示使用系统默认的悬停超时。
窗口重绘方面:
Invalidate()使窗口区域无效,以等待消息队列为空时发送下一个重绘WM_PAINT消息。同样,有InvalidateRect(),可以指定要重绘的特定矩形区域。
UpdateWindow()强制立即更新窗口。在OnPaint()函数中,可以使用GetUpdateRect()确定重绘区域或确定是否需要重绘。
RedrawWindow与UpdateWindow类似,它强制重画窗口,但是它提供了更多参数来设置重画区域等。
重新绘制时,您需要调用BeginPaint()来准备要绘制的Windows设备环境,填写PAINTSTRUCT结构,然后返回要重新绘制的DC句柄。
绘画结束后,需要调用EndPaint()释放设备句柄。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-363508-1.html
美日口粮做事的啦
但发展方向是对的