您的位置:首页 > 其它

Windows学习笔记14——鼠标相关

2014-02-20 21:51 260 查看
键盘便于输入和操作文字资料,而鼠标则便于画图和操作图形物件。

1、鼠标基础

<1>、***确认PC系统是否安装了鼠标的测试方法:使用GetSystemMetrics函数。

用法:

bool bMouse = GetSystemMetrics(SM_MOUSEPRESENT);

如果安装了鼠标,fMouse返回TRUE(非0),如果没有安装,则返回false。

*** 确认所安装鼠标上的按键个数,使用以下方法:

int CButtons = GetSystemMetrics(SM_MOUSEBUTTONS);

如果没有安装鼠标,返回0。

*** 判断是否设置切换为左手习惯的鼠标:使用GetSystemMetrics中的SM_SWAPBUTTON参数。

<2>、几个简单定义

鼠标游标:当使用者移动鼠标时,Windows在显示器上移动的一个小点阵图。

热点:鼠标游标指向的显示器上的精确位置的小图素。

<3>、只要鼠标划过窗口或者在某窗口中按下鼠标按键,那么窗口过程就会收到鼠标消息,而不管该窗口是否活动或拥有输入焦点,Windows为鼠标定义了21种消息。

对于所有鼠标消息,消息的lParam值包含鼠标的位置信息:低字为x坐标,高字为y坐标。这两个坐标是相对于窗口左上角的位置。x = LOWORD(lParam); y = HIWORD(lParam);

消息的wParam的值指示的是鼠标按键以及Shift和Ctrl键的状态。以MK开头表示“鼠标按键”。MK_LBUTTON:按下左键;MK_MBUTTON:按下中键;MK_RBUTTON:按下右键;MK_SHIFT:按下SHIFT键;MK_CONTROL:按下Ctrl键。

例如:如果收到了WM_LBUTTONDOWN消息,而且值wParam & MK_SHIFT是TRUE,则表示在鼠标左键按下的同时,也按下了Shift键。

<4>、需要注意的两点

*当鼠标不在窗口范围内时,窗口过程可以“拦截鼠标消息”并连续地接收鼠标消息。

*当正在显示一个系统模态消息框或系统模态对话框时,那么其他程序就不能接收鼠标消息。而且当系统模态消息框或模态对话框活动时,禁止切换到其他窗口或程序。

2、Shift键、Ctrl键的处理:

方法1:

例如在收到WM_MOUSEMOVE消息时,处理Shift\Ctrl:

if(wParam & MK_SHIFT)

{

if(wParam & MK_CONTROL)

{

//按下Shift和Ctrl

}

else

{

//按下Shift

}

}

else

{

if(wParam & MK_CONTROL)

{

//按下了Ctrl

}

else

{

//Shift和Ctrl均未被按下

}

}

方法2:使用GetKeyState函数返回按键状态

GetKeyState函数使用虚拟键码VK_LBUTTON、VK_RBUTTON、VK_MBUTTON、VK_SHIFT和VK_CONTROL来传回鼠标按键和Shift键的状态。

3、双击鼠标按键

*如果希望窗口过程能够接收到双击鼠标的消息,那么在设计窗口类时应该在窗口风格里包含CS_DBLCLKS识别字:如:wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

注:如果wndClass未包含CS_DBLCLKS风格,则使用者短时间内双击鼠标左键,窗口过程会收到两组LBUTTONDOWN和LBUTTONUP消息:

如果wndClass包含CS_DBLCLKS风格,则此时第二组的LBUTTONDOWN消息将由LBUTTONDBLCLK替换。

双击的第一次按键消息是处理单击消息(LBUTTONDOWN)。

4、非显示区域鼠标消息

窗口的非显示区域包括标题列、功能表和窗口卷动列。

如果鼠标在窗口的显示区域之外,但还在窗口内,Windows给窗口过程发送一条“非显示区域”鼠标消息。

非显示区域鼠标消息中含有字母“NC”:表示是非显示区域消息。

<1>、非显示区域鼠标消息种类:

WM_NCMOUSEMOVE、WM_NCLBUTTONDOWN、WM_NCMBUTTONDOWN、WM_NCRBUTTONDOWN、WM_NCLBUTTONUP、WM_NCMBUTTONUP、WM_NCRBUTTONUP、WM_NCLBUTTONDBLCLK、WM_NC_MBUTTONDBLCLK、WM_RBUTTONDBLCLK。

<2>、非显示区域鼠标消息的wParam和lParam参数

wParam参数指明移动或按鼠标按键的“非显示区域”,是以HT开头的识别字(HT表示“命中测试”);

lParam参数的低字为x坐标,高字为y坐标。注意,它们是“屏幕坐标”。

<3>命中测试消息

“WM_NCHITTEST”消息表示“非显示区域命中测试”。此消息优先于所有其他鼠标消息(包括显示区域和非显示区域)。lParam参数含有鼠标位置的x和y屏幕坐标,wParam参数没有用。

Windows应用程序通常把这个消息传送给DefWindowProc,然后Windows用WM_NCHITTEST消息产生与鼠标位置相关的其他鼠标消息。

对于非显示区域鼠标消息,在处理WM_NCHITTEST时,从DefWindowProc传回的值将成为鼠标消息的wParam参数,这个值可以是任意非显示区域鼠标消息再加上以下值之一:HTCLIENT(显示区域)、HTNOWHERE(不在窗口中)、HTTRANSPARENT(窗口被另一个窗口覆盖)、HTERROR(使DefWindowProc产生警示用的哗声)。

如果DefWindowProc在处理WM_NCHITTEST消息后传回HTCLIENT,那么Windows将把屏幕坐标转换为客户区坐标并产生显示区域鼠标消息。

<4>、屏蔽鼠标消息

在窗口过程中加入以下代码:

case WM_NCHITTEST:

return (LRESULT) HTNOWHERE;

这样就可以屏蔽所有鼠标消息(包括显示区域和非显示区域)。这时当鼠标在窗口中(包括系统功能表图示、缩放按钮、关闭按钮)时,鼠标按键就会失效。

5、使用键盘模拟鼠标

<1>、小知识:即时没有安装鼠标,Windows仍然会显示一个鼠标游标。Windows为这个游标保存一个“显示计数”,如果安装了鼠标,显示计数会被初始化为0,否则,显示计数会被初始化为-1,只有在显示计数非负时才显示鼠标游标。增加显示计数,可以调用ShowCursor(TRUE);要减少显示计数,可以调用ShowCursor(false);

*获得游标的位置:GetCursorPos(&pt);

*设定游标位置:SetCursorPos(x, y);//注意这里x,y都是屏幕坐标。

*注意:GetCursorPos传回的坐标表示鼠标的当前位置,鼠标消息的lParam参数中的坐标是产生消息时鼠标的位置。

6、子窗口与键盘

注意:父窗口和子窗口可能共用键盘消息,即子窗口和父窗口各自的窗口过程获得键盘消息没有先后次序。

但是,鼠标消息就不一样了,鼠标消息是由父窗口的窗口过程先获得的。

7、拦截鼠标消息

一个窗口过程通常只在鼠标游标位于窗口的显示区域,或非显示区域时才接收鼠标消息。如果程序要在鼠标游标位于窗口之外时,接收鼠标消息,则程序可以自行拦截鼠标。

拦截鼠标消息的方法:

调用SetCapture(hwnd);

释放拦截的方法:

调用ReleaseCapture();

当鼠标消息被拦截时,鼠标消息将发送到拦截窗口,鼠标的坐标是相对于拦截窗口的客户区坐标。

注意:32位windows系统,对鼠标消息的拦截做了较多限制,这样做可以防止一个程序在拦截鼠标之后而不释放它而引起整个系统混乱。

如果鼠标消息被当前窗口拦截,而鼠标在没有按下的情况下移动到另一个窗口,那么拦截将失效,将由鼠标游标下面的窗口接收鼠标消息;

拦截鼠标时,鼠标按下的情况下移动到另一个窗口,则当鼠标按键被释放时,才释放拦截。

8、鼠标滑轮

按下鼠标滑轮,它的功能相当于鼠标中键;

转动滑轮,会产生WM_MOUSEWHEEL消息。

<1>、关于WM_MOUSEWHEEL消息

lParam参数包含鼠标位置信息,wParam参数的低字组包含一些标志,用于标识鼠标按键、Shift、Ctrl键的状态。

wParam的高字组,其中有一个“data”值,该值目前可以是120 和-120(表示滑轮向前或向后转动,文件将向上或向下转动3行)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: