[MFC]鼠标消息处理

1. 鼠标事件和鼠标消息:

    1) 鼠标和光标的区别:鼠标是指实体鼠标,而光标就是鼠标在屏幕上的表示,因此在编程中通常称为光标;

    2) 鼠标事件:Windows中分为是三种,按下或释放鼠标、双击鼠标、移动鼠标;

    3) 上述三种鼠标实际那将触发鼠标消息,而鼠标消息分为两类,一类是客户区鼠标消息,另一类是非客户区鼠标消息,一般非客户区鼠标消息直接交由DefWindowProc处理;


2. 客户区鼠标消息:

    1) 鼠标消息都属于窗口消息,因此消息ID的前缀都是WM_,根据鼠标左右中键的不同以及按下和释放这两个不同动作,鼠标消息的一般名称为WM_xBUTTONyyy;

    2) 前缀x有L、R、M分别表示鼠标左键、右键和中键,yyy有DOWN表示按下、UP表示释放、DBLCLK表示双击;

    3) 如果鼠标只有两个键(左右键)则应用程序不会收到中间消息,如果只有左键(单键鼠标,这种鼠标很少)则应用程序将不会收到右键消息,可以使用Win32 API函数GetSystemMetrics来查看鼠标有几个键,用法是:int nButtonCount = ::GetSystemMetrics(SM_CMOUSEBUTTONS);,其中SM_是System Metrics的缩写(系统度量的意思),后面的前缀C表示Count,如果返回0则表示没插鼠标;

    4) 双击鼠标消息:消息ID是WM_xBUTTONDBLCLK,但要注意的是并不是双击只会产生一个DBLCLK消息,而是按顺序产生4个消息,以左键双击为例

WM_LBUTTONDOWN ; 第一次按下鼠标

WM_LBUTTONUP ; 第一次鼠标释放

WM_LBUTTONDBCLK ; 第二次按下鼠标,用DBLCLK替换了DOWN

WM_LBUTTONUP ; 第二次鼠标释放

!在编程时要注意,不要让同一个键的连续单击和双击执行不同的任务,这样容易混淆导致混乱,原因就是上面的双击消息产生顺序,一般在双击的时候都是在第一次单击时选中目标,而在第二次按下(即DBLCLK消息产生后)才会执行一些特殊任务,比如Windows操作系统双击打开文件就是这样,第一次单击时选中文件并使图标变色,而在第二次按下时才打开文件;

    5) 窗口接受双击消息的前提:在注册窗口类时必须声明为CS_DBLCLKS,这在Win32中遇到过,但是MFC为框架窗口类注册是默认使用CS_DBLCLKS,因此MFC程序总能接受鼠标双击消息;

    6) 光标移动消息:消息ID是WM_MOUSEMOVE,接受该消息的对象是光标底下的窗口,窗口会接收到快速报告光标位置的消息,但是由于光标移动是频繁的,Windows并不是时时刻刻都报告光标移动消息,因为这样做的代价太大,很多其它消息会被光标移动消息淹没,并且时刻都报告光标移动消息会使程序效率降低,因此Windows并不报告所有的光标消息,而是每隔适当时间、适当位置报告一次,因此当光标在屏幕上快速划过时系统只会报告少数的几个消息,只有在光标缓慢滑动的时候才可能捕捉到精确的光标轨迹;


7. 鼠标消息的处理:

    1) 鼠标消息的消息ID、消息条目、响应函数的对应关系,所有鼠标消息的形式都是统一的:

WM_xBUTTONyyy ; 消息ID

ON_WM_xBUTTONyyy ; 消息条目

afx_msg void OnXButtonYYY(UINT nFlags, CPOINT point);

!还有一个鼠标移动消息也类同;

    2) 鼠标消息处理函数的参数:

         i. point:记录了鼠标被按下、释放时的客户区坐标(原点在客户区左上角),如果鼠标移动消息则该参数记录的是最近的光标位置;

         ii. uFlags:记录了鼠标消息产生时的瞬时状态,里面有若干位标志,前缀MK_表示Mask Key,即掩码的意思;

MK_LBUTTON、MK_MBUTTON、MK_RBUTTON:表示鼠标的左、中、右键被按下

MK_CONTROL:Ctrl键被按下

MK_SHIFT:Shift键被按下

!比如在检测操作鼠标的同时是否按下了Ctrl键则可以:if ( nFlags & MK_CONTROL ) { ... }

你可能感兴趣的:(MFC)