Windows应用程序中几种特殊鼠标事件的识别_第1页
Windows应用程序中几种特殊鼠标事件的识别_第2页
Windows应用程序中几种特殊鼠标事件的识别_第3页
Windows应用程序中几种特殊鼠标事件的识别_第4页
Windows应用程序中几种特殊鼠标事件的识别_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Windows应用程序中几种特殊鼠标事件的识别 鼠标作为计算机输入设备随着Windows的流行而逐渐成为计算机的标准配置。在Windows中鼠标的操作可以产生二十多个消息,主要分为客户区鼠标消息和非客户区鼠标消息两大类,包括鼠标的移动,左中右键的按下、释放、双击等。事实上,实际的应用程序中往往会用到一些特殊的鼠标事件,如鼠标三击、左右鼠标同时按下、鼠标单击双击三击的独立识别或依次处理等。下面结合笔者编程的体会来谈一下Windows中这几种特殊的鼠标事件的识别方法。 一、独立处理单击、双击和三击 我们先看一下Windows对鼠标的响应。对左键而言,如果鼠标按下,则产生WM_LBUTTONDOWN

2、消息。接着,鼠标释放产生WM_LBUTTONUP消息;但如果鼠标双击,则Windows并不仅仅只产生WM_LBUTTONDBLCLK 消息,而是先产生WM_LBUTTONDOWN消息,然后产生WM_LBUTTONDBLCLK消息,其中还有WM_LBUTTONUP等消息,这里暂不讨论。对于鼠标的三击,Windows没有提供独立的消息,但我们不妨认为三击是在WM_LBUTTONDBLCLK消息之后再发一个WM_LBUTTONDOWN消息。所以,在应用程序编程时若要窗口分别独立地响应鼠标的单击、双击、三击消息,只有用户自己动手去处理。例如,Winows95中的文件夹改名就是一个例子,用鼠标单击一个已

3、经加亮的文件夹名称时稍作停留便可改名,如果双击则可打开该文件。这时,就必须单独处理鼠标的单击和双击,否则执行顺序应该是先响应WM_LBUTTONDOWN消息,然后再响应WM_LBUTTONDBLCLK,即先改名再打开,这是事与愿违的。 为了单独识别这三个鼠标消息,我们不能直接使用WM_LBUTTONDOWN和WM_LBUTTONDBLCLK消息来判断鼠标的单击和双击。这里,定义三个“伪”消息WM_MYSNGCLK、WM_MYDBLCLK、WM_MYTHRCLK,用它们分别标识鼠标的单击、双击和三击事件。由于我们在两次连续的鼠标单击后还不能确定是否有三击,所以再增加一个 WM_MYDBLCLKT

4、伪消息,在处理该伪消息时再进一步判断双击与三击。我们只处理WM_LBUTTONDOWN消息,所以注册窗口类时不设置CS_DBLCLKS风格。 具体处理过程如下:设置逻辑标志FLAG1及FLAG2,初始值均为FALSE,当已经单击时将FLAG1置为TRUE,已经双击时将FLAG2置为TRUE。在处理WM_LBUTTONDOWN消息时通过函数 SetTimer增加一个计时器ID_TIMER1,计时器的时间参数置为鼠标双击的时间间隔(用GetDoubleClickTime取得),并将FLAG1置为TRUE。如果计时器D_TIMER1发出消息,则表明在规定时间内没有按键,可以判断鼠标为单击,可发出WM

5、_MYSNGCLK消息,同时将FLAG1置为FALSE;如果计时器消息没有产生,则表明在规定的时间内有鼠标键按下,此时鼠标已经双击,将FLAG2置为TRUE,但是否有三击还需要继续判断,此时发出WM_MYDBLCLKT消息,我们用同样的方法在伪消息WM_MYDBLCLKT中再定义一个计时器ID_TIMER2。同理,如果计时器ID_TIMER2发出消息,则表明在规定时间内没有按键,可以判断鼠标为双击,可发出WM_MYDBLCLK消息;如果计时器ID_TIMER2没有发出消息,则表明在规定的时间内有鼠标键被按下,此时鼠标已经三击,可以发出WM_MYTHRCLK消息。至此已完成识别,当然计时器要使用

6、 KillTimer及时删除。另外要注意的是,鼠标双击的时间间隔不要设置太大,否则延时感太明显。 下面是具体的实现方法,本文只给出窗口过程WndProc的部分内容,其它函数与通常的Windows应用程序大同小异,故从略。 #define ID_TIMER1 1001 /* 计时器1*/ #define ID_TIMER2 1002 /* 计时器2*/ #define WM_MYDBLCLKT WM_USER+100 /*当已经双击但还不能决定三击时发出*/ #define WM_MYSNGCLK WM_USER+101 /*已经确定为单击时发出*/ #define WM_MYDBLCLK WM

7、_USER+102 /*已经确定为双击时发出*/ #define WM_MYTHRCLK WM_USER+103 /*已经确定为三击时发出*/ LRESULT CALLBACK WndProc(HWND hwnd,UINT uMessage,WPARAM wparam,LPARAM lparam) static int FLAG1,FLAG2; int wTime; POINT pt; switch (uMessage) case WM_LBUTTONDOWN: /*程序只对单击消息进行处理,不处理双击消息*/ GetCursorPos(&pt); /*取鼠标位置用于传递消息中的LPA

8、RAM*/ ScreenToClient(hwnd,&pt); if(! FLAG2) /*FLAG2不为真时,鼠标状态为第一次单击或第二次单击*/ if(!FLAG1) /*FLAG1不为真时为第一次单击*/ wTime=GetDoubleClickTime(); /*取鼠标双击时间间隔*/ SetTimer(hwnd,ID_TIMER1,wTime,NULL); /*第一次单击后建立计时器*/ if(FLAG1) /*FLAG1为真,已经确定为双击,发出WM_MYDBLCLKT继续判断*/ PostMessage(hwnd,WM_MYDBLCLKT,0,MAKELPARAM(pt.

9、x,pt.y); FLAG1=FALSE; KillTimer(hwnd,ID_TIMER1); break; FLAG1=TRUE; if(FLAG2) /*FLAG2为真,已经确定为三击*/ PostMessage(hwnd,WM_MYTHRCLK,0,MAKELPARAM(pt.x,pt.y); FLAG2=FALSE; KillTimer(hwnd,ID_TIMER2); break; break; case WM_TIMER: /*计时器消息产生,说明鼠标没有按键操作*/ switch(wparam) case ID_TIMER1: /*第一次按键后没有后续按键,故确定为单击*/ K

10、illTimer(hwnd,wparam); FLAG1=FALSE; GetCursorPos(&pt); ScreenToClient(hwnd,&pt); PostMessage(hwnd,WM_MYSNGCLK,0,MAKELPARAM(pt.x,pt.y); break; case ID_TIMER2: /*第二次按键后没有后续按键,故确定为双击*/ KillTimer(hwnd,wparam); FLAG2=FALSE; GetCursorPos(&pt); ScreenToClient(hwnd,&pt); PostMessage(hwnd,WM_

11、MYDBLCLK,0,MAKELPARAM(pt.x,pt.y); break; break; case WM_MOUSEMOVE: /*如果鼠标移动,则不认为是双击或三击*/ FLAG1=FALSE; FLAG2=FALSE; break; case WM_MYDBLCLKT: /*双击后等待再次按鼠标键*/ wTime=GetDoubleClickTime(); SetTimer(hwnd,ID_TIMER2,wTime,NULL); FLAG2=TRUE; break; case WM_MYSNGCLK: /*处理单击*/ break; case WM_MYDBLCLK: /*处理双击*

12、/ break; case WM_MYTHRCLK: /*处理三击*/ break; /其它消息 二、 依次处理单击、双击和三击 鼠标的单击、双击、三击处理还有一种情况。例如,Word及其它字处理软件中用鼠标选择编辑区域的处理方法,单击则定位插入点,双击则选中一个词,三击则选中一个段落。这种处理鼠标的方法是依次处理单击、双击、三击。下面要介绍的这种鼠标事件的处理方法与上述独立识别方法的思路基本相同,不同之处在于注册窗口类时风格设置为CS_DBLCLKS,以便窗口类识别鼠标双击。 具体方法是:在处理鼠标双击消息处理时发出WM_MYDBLCLK消息,同时设置计时器,并置标志FLAG为TRUE(初始

13、值为FALSE),这样在处理WM_LBUTTINDOWN时判断FLAG的值:若为FALSE则为单击,发送WM_MYSNGCLK消息;若为TRUE则为双击之后的一次单击(即三击),发送WM_MYTHRCLK消息,从而完成消息的识别。计时器的作用,只是等待双击之后是否出现单击。如果计时器消息已经发出则说明后面已经没有按键,这时可以删除计时器,从单击处重新进行识别。 下面是窗口函数WndProc的部分内容,程序注释部分说明了与上例的差别。 #define ID_TIMER 1001 #define WM_MYSNGCLK WM_USER+101 #define WM_MYDBLCLK WM_USER

14、+102 #define WM_MYTHRCLK WM_USER+103 LRESULT CALLBACK WndProc(HWND hwnd,UINT uMessage,WPARAM wparam,LPARAM lparam) static int FLAG; int wTime; POINT pt; switch (uMessage) case WM_LBUTTONDOWN: GetCursorPos(&pt); ScreenToClient(hwnd,&pt); if(FLAG)/*若为TRUE,则说明为双击之后的单击(即三击)*/ PostMessage(hwnd,WM

15、_MYTHRCLK,0,MAKELPARAM(pt.x,pt.y); FLAG=FALSE; KillTimer(hwnd,ID_TIMER); else /*否则为单击*/ PostMessage(hwnd,WM_MYSNGCLK,0,MAKELPARAM(pt.x,pt.y); break; case WM_TIMER: switch(wparam) case ID_TIMER: KillTimer(hwnd,wparam); /*计时器产生时,简单删除*/ FLAG=FALSE; break; break; case WM_LBUTTONDBLCLK: GetCursorPos(&

16、;pt); ScreenToClient(hwnd,&pt); wTime=GetDoubleClickTime(); SetTimer(hwnd,ID_TIMER,wTime,NULL); /*设置计时器*/ PostMessage(hwnd,WM_MYDBLCLK,0,MAKELPARAM(pt.x,pt.y); FLAG=TRUE; break; case WM_MOUSEMOVE:/*鼠标移动,则从单击重新开始判断*/ FLAG=FALSE; break; case WM_MYSNGCLK: /*处理单击*/ break; case WM_MYDBLCLK: /*处理双击*/ break; case WM_MYTHRCLK: /*处理三击*/ break; /其它消息 三、鼠标左右键同时按下与鼠标与键盘同时按下的识别 玩过Windows的扫雷游戏吗?该游戏中就有一个同时按下鼠标左右键的操作,其实对同时按下鼠标左右键的判断并不复杂,判断方法与判断鼠标按键是否与Ctrl和Shift同时按下的方法相同,这里要用到鼠标消息中的wparam项,其中含

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论