Windows桌面应用程序(1-2-5-4th) 其他鼠标操作
2018-02-07 20:08
337 查看
前面几节讨论了鼠标点击和鼠标移动。以下是一些可以用鼠标执行的其他操作。
拖动UI元素
如果您的用户界面支持拖动UI元素,那么您应该在鼠标悬停的消息处理程序中调用另一个函数:DragDetect。如果用户启动一个应解释为拖动的鼠标手势,则DragDetect函数返回TRUE。以下代码显示如何使用此功能。
这里的想法是:当一个程序支持拖放,你不希望每个鼠标点击被解释为一个拖动。否则,用户可能会偶然拖动某些东西,只是简单地点击它(例如,选择它)。但是,如果鼠标特别敏感,点击时可能很难保持鼠标完美。因此,Windows定义了几个像素的拖动阈值。当用户按下鼠标按钮时,除非鼠标超过此阈值,否则不会将其视为拖动。DragDetect函数测试是否达到这个阈值。如果函数返回TRUE,则可以将鼠标单击解释为拖动。否则,不要。
注意 如果DragDetect返回FALSE,Windows将在用户释放鼠标按钮时取消WM_LBUTTONUP消息。因此,除非您的程序当前处于支持拖动的模式,否则不要调用DragDetect。(例如,如果已经选择了可拖动的UI元素)。在本模块结尾处,我们将看到使用DragDetect函数的更长的代码示例。
限制游标
有时您可能想要限制光标到客户区或客户区的一部分。ClipCursor函数限制游标移动到指定的矩形。此矩形在屏幕坐标中给出,而不是客户端坐标,所以点(0,0)表示屏幕的左上角。要将客户端坐标转换为屏幕坐标,请调用ClientToScreen函数。
下面的代码将光标限制在窗口的客户区域。
ClipCursor采用RECT结构,但ClientToScreen采用POINT结构。矩形由左上角和右下角定义。您可以将光标限制在任何矩形区域,包括窗口外的区域,但将光标限制在客户区域是使用该功能的典型方法。将光标限制在完全位于窗口外的区域将是不寻常的,用户可能会将其视为一个错误。
要删除该限制,请使用值为NULL的方式调用ClipCursor。
鼠标跟踪事件:悬停和离开
其他两个鼠标消息在默认情况下是禁用的,但对于某些应用程序可能有用:
WM_MOUSEHOVER:光标在客户区上空盘旋了一段固定的时间。
WM_MOUSELEAVE:光标离开了客户区域。
要启用这些消息,请调用TrackMouseEvent函数。
TRACKMOUSEEVENT结构包含该函数的参数。该结构的dwFlags成员包含位标志,用于指定您感兴趣的跟踪消息。您可以选择同时获取WM_MOUSEHOVER和WM_MOUSELEAVE,如下所示,或者只是其中的一个。 dwHoverTime成员指定在系统生成悬停消息之前鼠标需要悬停的时间。该值以毫秒为单位给出。常量HOVER_DEFAULT意味着使用系统默认值。
在收到您请求的消息之一后,TrackMouseEvent函数将重置。您必须再次调用才能获得另一个跟踪消息。但是,在再次调用TrackMouseEvent之前,您应该等到下一个鼠标移动消息。否则,您的窗口可能会被跟踪消息充斥。例如,如果鼠标悬停,则鼠标静止时,系统将继续生成WM_MOUSEHOVER消息流。在鼠标移动到另一个位置并再次悬停之前,实际上并不需要另一个WM_MOUSEHOVER消息。
这里有一个小助手类,可以用来管理鼠标跟踪事件。
下一个例子展示了如何在你的窗口过程中使用这个类。
鼠标跟踪事件需要系统进行额外的处理,所以如果您不需要它们,请将其禁用。
为了完整起见,下面是一个函数,查询系统默认的悬停超时时间。
鼠标滚轮
以下功能检查鼠标滚轮是否存在。
如果用户旋转鼠标滚轮,具有焦点的窗口收到WM_MOUSEWHEEL消息。该消息的lParam参数包含一个称为delta的整数值,用于测量车轮旋转的距离。三角洲使用任意单位,其中120单位被定义为执行一个“行动”所需的轮换。当然,一个行动的定义取决于你的程序。例如,如果使用鼠标滚轮来滚动文字,则每120个旋转单位将滚动一行文字。
三角洲的符号表示旋转的方向:
正向:向前旋转,远离用户。
负面:向后旋转,朝向用户。
增量的值与一些附加的标志一起被放置在lParam中。使用GET_WHEEL_DELTA_WPARAM宏来获取增量的值。
如果鼠标滚轮具有较高的分辨率,则增量的绝对值可能小于120。在这种情况下,如果以较小的增量出现动作是有意义的,则可以这样做。例如,文本可以以小于一行的增量滚动。否则,积累总的三角洲,直到轮旋转足够执行行动。将未使用的增量存储在一个变量中,当120个单位累加(正数或负数)时,执行该操作。
下一个
键盘输入
原文链接:Miscellaneous Mouse Operations
拖动UI元素
如果您的用户界面支持拖动UI元素,那么您应该在鼠标悬停的消息处理程序中调用另一个函数:DragDetect。如果用户启动一个应解释为拖动的鼠标手势,则DragDetect函数返回TRUE。以下代码显示如何使用此功能。
case WM_LBUTTONDOWN: { POINT pt={GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)}; if(DragDetect(m_hwnd,pt)){ // Start dragging. } } return 0;
这里的想法是:当一个程序支持拖放,你不希望每个鼠标点击被解释为一个拖动。否则,用户可能会偶然拖动某些东西,只是简单地点击它(例如,选择它)。但是,如果鼠标特别敏感,点击时可能很难保持鼠标完美。因此,Windows定义了几个像素的拖动阈值。当用户按下鼠标按钮时,除非鼠标超过此阈值,否则不会将其视为拖动。DragDetect函数测试是否达到这个阈值。如果函数返回TRUE,则可以将鼠标单击解释为拖动。否则,不要。
注意 如果DragDetect返回FALSE,Windows将在用户释放鼠标按钮时取消WM_LBUTTONUP消息。因此,除非您的程序当前处于支持拖动的模式,否则不要调用DragDetect。(例如,如果已经选择了可拖动的UI元素)。在本模块结尾处,我们将看到使用DragDetect函数的更长的代码示例。
限制游标
有时您可能想要限制光标到客户区或客户区的一部分。ClipCursor函数限制游标移动到指定的矩形。此矩形在屏幕坐标中给出,而不是客户端坐标,所以点(0,0)表示屏幕的左上角。要将客户端坐标转换为屏幕坐标,请调用ClientToScreen函数。
下面的代码将光标限制在窗口的客户区域。
// Get the window client area. RECT rc; GetClientRect(m_hwnd,&rc); // Convert the client area to screen coordinates. POINT pt={rc.left,rc.top}; POINT pt2={rc.right,rc.bottom}; ClientToScreen(m_hwnd,&pt); ClientToScreen(m_hwnd,&pt2); SetRect(&rc,pt.x,pt.y,pt2.x,pt2.y); // Confine the cursor. ClipCursor(&rc);
ClipCursor采用RECT结构,但ClientToScreen采用POINT结构。矩形由左上角和右下角定义。您可以将光标限制在任何矩形区域,包括窗口外的区域,但将光标限制在客户区域是使用该功能的典型方法。将光标限制在完全位于窗口外的区域将是不寻常的,用户可能会将其视为一个错误。
要删除该限制,请使用值为NULL的方式调用ClipCursor。
ClipCursor(NULL);
鼠标跟踪事件:悬停和离开
其他两个鼠标消息在默认情况下是禁用的,但对于某些应用程序可能有用:
WM_MOUSEHOVER:光标在客户区上空盘旋了一段固定的时间。
WM_MOUSELEAVE:光标离开了客户区域。
要启用这些消息,请调用TrackMouseEvent函数。
TRACKMOUSEEVENT tme; tme.cbSize=sizeof(tme); tme.hwndTrack=hwnd; tme.dwFlags=TME_HOVER|TME_LEAVE; tme.dwHoverTime=HOVER_DEFAULT; TrackMouseEvent(&tme);
TRACKMOUSEEVENT结构包含该函数的参数。该结构的dwFlags成员包含位标志,用于指定您感兴趣的跟踪消息。您可以选择同时获取WM_MOUSEHOVER和WM_MOUSELEAVE,如下所示,或者只是其中的一个。 dwHoverTime成员指定在系统生成悬停消息之前鼠标需要悬停的时间。该值以毫秒为单位给出。常量HOVER_DEFAULT意味着使用系统默认值。
在收到您请求的消息之一后,TrackMouseEvent函数将重置。您必须再次调用才能获得另一个跟踪消息。但是,在再次调用TrackMouseEvent之前,您应该等到下一个鼠标移动消息。否则,您的窗口可能会被跟踪消息充斥。例如,如果鼠标悬停,则鼠标静止时,系统将继续生成WM_MOUSEHOVER消息流。在鼠标移动到另一个位置并再次悬停之前,实际上并不需要另一个WM_MOUSEHOVER消息。
这里有一个小助手类,可以用来管理鼠标跟踪事件。
class MouseTrackEvents{
bool m_bMouseTracking;
public:
MouseTrackEvents():m_bMouseTracking(false){}
void OnMouseMove(HWND hwnd){
if(!m_bMouseTracking){
// Enable mouse tracking.
TRACKMOUSEEVENT tme; tme.cbSize=sizeof(tme); tme.hwndTrack=hwnd; tme.dwFlags=TME_HOVER|TME_LEAVE; tme.dwHoverTime=HOVER_DEFAULT; TrackMouseEvent(&tme);
m_bMouseTracking=true;
}
}
void Reset(HWND hwnd){
m_bMouseTracking=false;
}
};
下一个例子展示了如何在你的窗口过程中使用这个类。
LRESULT MainWindow::HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam){ switch(uMsg){ case WM_MOUSEMOVE: mouseTrack.OnMouseMove(m_hwnd);// Start tracking. // TODO: Handle the mouse-move message. return 0; case WM_MOUSELEAVE: // TODO: Handle the mouse-leave message. mouseTrack.Reset(m_hwnd); return 0; case WM_MOUSEHOVER: // TODO: Handle the mouse-hover message. mouseTrack.Reset(m_hwnd); return 0; } return DefWindowProc(m_hwnd,uMsg,wParam,lParam); }
鼠标跟踪事件需要系统进行额外的处理,所以如果您不需要它们,请将其禁用。
为了完整起见,下面是一个函数,查询系统默认的悬停超时时间。
UINT GetMouseHoverTime(){ UINT msec; if(SystemParametersInfo(SPI_GETMOUSEHOVERTIME,0,&msec,0)) return msec; else return 0; }
鼠标滚轮
以下功能检查鼠标滚轮是否存在。
BOOL IsMouseWheelPresent(){ return GetSystemMetrics(SM_MOUSEWHEELPRESENT)!=0; }
如果用户旋转鼠标滚轮,具有焦点的窗口收到WM_MOUSEWHEEL消息。该消息的lParam参数包含一个称为delta的整数值,用于测量车轮旋转的距离。三角洲使用任意单位,其中120单位被定义为执行一个“行动”所需的轮换。当然,一个行动的定义取决于你的程序。例如,如果使用鼠标滚轮来滚动文字,则每120个旋转单位将滚动一行文字。
三角洲的符号表示旋转的方向:
正向:向前旋转,远离用户。
负面:向后旋转,朝向用户。
增量的值与一些附加的标志一起被放置在lParam中。使用GET_WHEEL_DELTA_WPARAM宏来获取增量的值。
int delta=GET_WHEEL_DELTA_WPARAM(wParam);
如果鼠标滚轮具有较高的分辨率,则增量的绝对值可能小于120。在这种情况下,如果以较小的增量出现动作是有意义的,则可以这样做。例如,文本可以以小于一行的增量滚动。否则,积累总的三角洲,直到轮旋转足够执行行动。将未使用的增量存储在一个变量中,当120个单位累加(正数或负数)时,执行该操作。
下一个
键盘输入
原文链接:Miscellaneous Mouse Operations
相关文章推荐
- Windows桌面应用程序(1-2-4th) 模块3.Windows图形
- Windows桌面应用程序(1-2-1-4th) 什么是窗口?
- Windows桌面应用程序(1-2-2-4th) 绘画窗口
- Windows桌面应用程序(1-2-5-1st) 鼠标输入
- Windows桌面应用程序(1-2-5-3rd) 鼠标移动
- Windows桌面应用程序(1-2-4-4th) 您的第一个Direct2D程序
- Windows桌面应用程序(1-2-3-4th) 在COM中创建一个对象
- Windows桌面应用程序(1-2-5-2nd) 响应鼠标点击
- windows桌面频繁截图时的鼠标闪烁问题
- Windows应用程序中几种特殊鼠标事件的识别【转】
- Windows 7系统下鼠标滚轮操作的6个小技巧
- 远程桌面登录Windows 7 时报Atbroker.exe 应用程序错误
- C#编写Windows桌面应用程序窗体上放置图片
- 如何创建一个最简单的Windows桌面应用程序 (C++)
- Windows桌面应用程序(1-2-4-10th) 附录:矩阵变换
- 行动起来:转换传统桌面应用程序到UWP 并发布到Windows 应用商店!
- 更改windows 2003远程桌面端口3389为其他的端口号【转】
- Qt开发桌面Helloworld与Qt windows应用程序 双击不能运行解决方法
- Windows桌面应用程序(1-2-2-1st) 创建一个窗口
- Windows桌面应用程序(1-2-2-6th) 管理应用程序状态