第4章 鼠标与键盘消息的处理
特殊说明:版权归个人所有,请勿转载,谢谢合作。
鼠标及键盘作为Windows系统最重要的输入设置,要深入理解消息的类型以及消息的捕获方法。本章节重点介绍鼠标及键盘消息的基本概念与应用。
4.1 鼠标消息的应用
根据MSDN的描述,Windows系统有24种不同的消息,用来报告与鼠标有关的事件。这些消息分为两大类:客户区域鼠标消息与非客户区域鼠标消息。客户区域鼠标消息,用来报告当前窗口客户区域里发生的事件。非客户区域鼠标消息,则用来报告除当前窗口以外的窗口区域发生的事件。
在鼠标消息处理过程中,非客户区域并不常用,在过程处理函数中不去捕获这部分消息即可,系统会通过DefWindowProc函数交给系统处理。表4.1列出了鼠标的消息,并对响应区域进行了区分。
表4.1 鼠标消息事件
区域
消息
事件描述
客户区域
WM_LBUTTONDOWN
客户区左键按下事件
WM_LBUTTONUP
客户区左键抬起事件
WM_LBUTTONDBLCLK
客户区左键双击事件
WM_MBUTTONDOWN
客户区中键按下事件
WM_MBUTTONUP
客户区中键抬起事件
WM_MBUTTONDBLCLK
客户区中键双击事件
WM_RBUTTONDOWN
客户区右键按下事件
WM_RBUTTONUP
客户区右键抬起事件
WM_RBUTTONDBLCLK
客户区右键双击事件
WM_MOUSEMOVE
客户区鼠标移动事件
WM_MOUSEWHEEL
客户区滚轮滚动事件
WM_MOUSEACTIVATE
非活动窗口,鼠标操作事件
WM_CAPTURECHANGED
失去鼠标捕获窗口的事件
非客户区域
WM_NCHITTEST
移动窗口标题栏发生的事件
WM_NCLBUTTONDBLCLK
非客户区左键双击事件
WM_NCLBUTTONDOWN
非客户区左键按下事件
WM_NCLBUTTONUP
非客户区左键抬起事件
WM_NCMBUTTONDBLCLK
非客户区中键双击事件
WM_NCMBUTTONDOWN
非客户区中键按下事件
WM_NCMBUTTONUP
非客户区中键抬起事件
WM_NCMOUSEMOVE
非客户区鼠标移动事件
WM_NCRBUTTONDBLCLK
非客户区右键双击事件
WM_NCRBUTTONDOWN
非客户区右键按下事件
WM_NCRBUTTONUP
非客户区右键抬起事件
鼠标消息的记忆,有一定的规则,“WM_”为消息的标识,“L”为left,代表左键,“M”为middle,代表中键, “R”为right,代表右键,NC表示为非客户区域。例如,鼠标右键抬起事件,可以写为:“WM_ R BUTTON UP”,当然正确的写法是“WM_RBUTTONUP”,只是用空格将规则进行区分。部分鼠标消息是有连贯性的,其中包括左键、中键与右键。如果做了一次鼠标左键的点击事件,系统则先触发左键接下(WM_LBUTTONDOWN)事件,再触发左键抬起(WM_LBUTTONUP)事件。
接下来以鼠标左键按下事件为例,讲解鼠标消息在过程处理函数中的处理方法以及各参数的含义。下例是鼠标左键按下时,弹出一个提示框:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// 鼠标左键按下实例
case WM_LBUTTONDOWN:
MessageBox(hWnd, "鼠标左键被接下。", "提示", MB_OK);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// 调用系统默认消息处理,即交给系统处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}//end switch
return 0;
}
从事例中不难看出,捕获鼠标消息非常简单。对于此时的过程处理函数,其参数是有一定含义的:
参数hWnd,当前窗口的句柄;
参数message,消息的类型,此处值为WM_LBUTTONDOWN;
参数wParam,存放一个标志,该标志注明了当鼠标左键按下的时,还有什么键同时被按下。如果判断鼠标左键按下的同时按了什么键,可以通过如下方法来验证:
// 鼠标左键按下实例
case WM_LBUTTONDOWN:
if(wParam & MK_CONTROL)
{
MessageBox(hWnd, "Ctrl键同时被按下。", "提示", MB_OK);
}
break;
其中MK_CONTROL为虚拟键值,系统还提供如表4.2所示的虚拟键值。
表4.2 鼠标消息中wParam的值
值
含义
MK_CONTROL
按下了Ctrl键
MK_LBUTTON
按下了鼠标左键
MK_MBUTTON
按下了鼠标中键
MK_RBUTTON
按下了鼠标右键
MK_SHIFT
按下了Shift键
参数lParam,存放当前光标在窗口中的位置。在获得光标位置时,需要将lParam进行拆分,lParam为四个字节的数值,高位两位代表着鼠标的Y坐标,低两位代表着鼠标的X坐标,如图所示。
图4.1 lParam中的坐标
可以通过LOWORD函数与HIWORD函数,分别获得鼠标的X坐标值与Y坐标值,具体写法如下:
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
已经学会了鼠标左键按下消息的捕获与处理,针对于鼠标的其他事件,处理方法相同,所以,这里不过多介绍。接下来,做一个关于鼠标的示例。【例4-1】介绍了如何响应鼠标消息。鼠标移动时,窗口标题显示当前光标在客户区的位置。
//-----------------------------------------------------------------------------
// FUNC : 回调函数
//-----------------------------------------------------------------------------
// IN : hWnd,窗口句柄;
// message,要处理的消息ID,以此来区分消息;
// wParam,消息参数,根据消息的不同内容也有所不同;
// lParam,消息参数,根据消息的不同内容也有所不同。
// OUT : void
// RETURN : void
// AUTHOR : 2012-2-6 11:36 Create by lixinghua for functions.
// NOTE : 此函数用于系统消息的处理。
//-----------------------------------------------------------------------------
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char szBuffer[64] = { 0 }; // 用于存放鼠标位置的缓冲区
int nX, nY; // 存放鼠标的X,Y值
// 消息处理
//
switch (message)
{
// 鼠标移动事件
case WM_MOUSEMOVE:
// 获取X,Y值
nX = LOWORD(lParam);
nY = HIWORD(lParam);
// 格式化到缓冲区
sprintf(szBuffer, "X:%d, Y:%d", nX, nY);
// 设置窗口标题
SetWindowText(hWnd, szBuffer);
break;
// 窗口销毁消息,关闭窗口时响应。
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// 调用系统默认消息处理,即交给系统处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}//end switch
return 0;
}
首先,需要捕获鼠标的移动事件(捕获WM_MOUSEMOVE消息);其次,得到鼠标的坐标位置。可以使用LOWORD、HIWORD函数,分别获得X、Y坐标。坐标已经有了,但需要将X、Y的值格式化到字符串中,可以使用sprintf函数。sprintf函数的用法与printf函数的用法相似,printf函数是打印相关的内容到屏幕上,而sprintf函数是结果格式化到它的第一个参数中。sprintf函数的第一个参数是字符串,它要有足够大的空间来存放X、Y坐标值;最后,将存放坐标位置的字符串显示在窗口的标题栏中。SetWindowText函数的功能是设置窗口标题的内容,它的第一个参数是窗口的句柄(将设置窗口的句柄),第二个参数是设置的内容。最终实现结果如图4.2所示。
图4.2 鼠标移动实例
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。Windows编程
收藏 分享链接:https://www.lixh.cn/archives/2065.html
分享到 :
靠“草”能赢球?世界杯球场草皮下的秘密
常用的小说网站,这87个小说网址强烈推荐收藏