一、鼠标基础
1、从系统得到鼠标是否存在及相关信息:
GetSystemMetrics(SM_MOUSEPRESENT);返回值为整型,非0为true,没有安装为0,在windows98中都返回为true;
GetSystemMetrics(SM_CMOUSEBUTTONS);返回鼠标用几个按键,windows98默认2。
2、鼠标样式:
通过在窗口类中设置鼠标的样式,wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
3、鼠标三键:
LBUTTON,MBUTTON,RBUTTON
二、显示区域鼠标消息:
窗口接收鼠标消息:只要鼠标跨越窗口或者在某窗口中按下鼠标按键,那么窗口消息处理程序就会收到鼠标消息,不管该窗口是否活动或是否拥有输入焦点。
1、鼠标在显示区域的消息:
键 按下 释放 双击
左 WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBCLK
中 WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBCLK
右 WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBCLK
在这些消息中lParam值均含有鼠标的位置:低字组为x座标,高字组为y座标这两个座标是相对于窗口显示区域左上角的位置
X=LOWORD(lParam);
Y=HIWORD(lParma);
而wParam的值指示鼠标按键以及shift和ctrl键的状态,在这里要用winuser.h中定义的位运算来测试wParam(MK表示鼠标按键)
MK_LBUTTON 按下左键
MK_MBUTTON 按下中键
MK_RBUTTON 按下右键
MK_SHIFT 按下shift键
MK_CONTROL 按下Ctrl键
例如:如果收到了WM_LBUTTONDOWN消息,而且值wparam & MK_SHIFT是非0.你就知道左键按下时也按下了shift键。
当你把鼠标移动过窗口的显示区域时,windows并不会把每个可能者产生一个WM_MOUSEMOVE消息这是收硬件决定的。
2、鼠标键盘混合消息:
与wParam & MK_LBUTTON一样用wParam & MK_MK_CONTROL 也可以确定是否按下了control键。
3、双击鼠标按键:
如果你希望在窗口处理程序能处理双击消息,那么你要在RegisterClass初始化窗口类别结构时,必须在窗口风格中包含CS_DBLCLKS识别字:
Wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
没有包含CS_DBLCLKS时你双击的结果为:
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONUP
如果加入CS_DB_LCLKS时你的双击结果为:
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_LBUTTONDBLCLK
WM_LBUTTONUP
WM_LBUTTONDBLCLK消息简单地替换了第二个WM_LBUTTONDOWN消息
如果双击中第一次操作完成单击的功能,那么双击这一消息是很容易处理的,第二次按键WM_LBUTTONDBLCLK消息则完成第一次按键以外的事情,双击则实作两个功能:
第一次是单击那个选中对象,第二次则运行双击的事件。
三、非显示区域鼠标消息:
如果鼠标在窗口的显示区域之外但还在窗体中,那么windows就会给窗体发送一条非显示区域鼠标消息,非显示区域包括标题列、功能表和视察滚动列。
通常你不需要处理非显示区域鼠标消息,而是将这些消息传给DefWindowProc从而使windows执行系统功能,就这方面来说,非显示区域鼠标消息类似于系统键盘消息WM_SYSKEYDOWN、WM_SYSKEYUP、WM_SYSCHAR。
消息如下:
键 按下 释放 双击
左 WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
中 WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
右 WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK
wParam参数指明移动或者按鼠标键的非显示区域(HT)
lParam参数和显示区一样但是他是相对于萤幕坐标
可以用以下函数来转换:
ScreenToClient(hwnd,&pt);
ClientToScreen(hwnd,&pt);
命中测试消息:
WM_NCHITTEST,它代表非显示区域中的测试,此消息优先于所有其他显示区域和非显示区域鼠标的消息,lParam参数含有鼠标位置的x和y屏幕座标wParam参数没有用,Windows应用程序通常把这个消息传送DefWindowProc然后winodws用WM_NCHITTEST消息产生与鼠标位置相关的所有其他鼠标消息在处理WM_NCHITTEST时,从DefWindowProc传回的值将成为鼠标消息中的wParam参数这个值可以是任意非显示区域鼠标消息的wParam值再加上以下内容:
HTCLIENT 显示区域
HTNOWHERE 不在窗口中
HTTRANSPARENT 窗体由另一个窗体覆盖
HTERROR 使DefWindowProc产生获救用的声音
可以用他来所有的系统键盘功能:
Case WM_NCHITTEST:
四、使用键盘模拟鼠标消息:
一些基本鼠标函数:
ShowCursor(TRUE);显示鼠标
ShowCursor(FALSE);不显示鼠标
POINT pt;GetCursorPos(&pt);返回鼠标位置到pt结构体中。
SetCursorPos(x,y);使用鼠标移动到x,y坐标上。在这里xy者是显示器的坐标。
五、拦截鼠标消息:
一个窗体消息处理程序通常只在鼠标位于窗体显示区域,或非显示区域上时才接收鼠标消息的,一个程序也可能需要在鼠标位于窗口外时接收鼠标消息,如果是这样,程序就要拦截鼠标消息了!
拦截的解决方案:
SetCapture(hwnd);
在这个函数调用之后,windows将所有的鼠标消息发给窗口代号为hwnd的窗体中处理程序,之后收到鼠标消息都是以显示区域消息的形态出现,即使鼠标正在窗口的非显示区域,lParam参数将指示鼠标在显示区域坐标中的位置。要想释放鼠标拦截可以用:
ReleaseCapture();