Windows应用程序中几种特殊鼠标事件的识别

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Windows应用程序中几种特殊鼠标事件的识别

鼠标作为计算机输入设备随着Windows的流行而逐渐成为计算机的标准配置。在

Windows中鼠标的操作可以产生二十多个消息,主要分为客户区鼠标消息和非客户区

鼠标消息两大类,包括鼠标的移动,左中右键的按下、释放、双击等。事实上,实

际的应用程序中往往会用到一些特殊的鼠标事件,如鼠标三击、左右鼠标同时按下

、鼠标单击双击三击的独立识别或依次处理等。下面结合笔者编程的体会来谈一下

Windows中这几种特殊的鼠标事件的识别方法。

一、独立处理单击、双击和三击

我们先看一下Windows对鼠标的响应。对左键而言,如果鼠标按下,则产生WM_LBUTTONDOWN消息。接着,鼠标释放产生WM_LBUTTONUP消息;但如果鼠标双击,

则Windows并不仅仅只产生WM_LBUTTONDBLCLK 消息,而是先产生

WM_LBUTTONDOWN消

息,然后产生WM_LBUTTONDBLCLK消息,其中还有WM_LBUTTONUP等消息,这里暂不讨

论。对于鼠标的三击,Windows没有提供独立的消息,但我们不妨认为三击是在WM_LBUTTONDBLCLK消息之后再发一个WM_LBUTTONDOWN消息。所以,在应用程序编程

时若要窗口分别独立地响应鼠标的单击、双击、三击消息,只有用户自己动手去处

理。例如,Winows95中的文件夹改名就是一个例子,用鼠标单击一个已经加亮的文

件夹名称时稍作停留便可改名,如果双击则可打开该文件。这时,就必须单独处理

鼠标的单击和双击,否则执行顺序应该是先响应WM_LBUTTONDOWN消息,然后再响应

WM_LBUTTONDBLCLK,即先改名再打开,这是事与愿违的。

为了单独识别这三个鼠标消息,我们不能直接使用WM_LBUTTONDOWN和

WM_LBUTTONDBLCLK消息来判断鼠标的单击和双击。这里,定义三个“伪”消息WM_MYSNGCLK、WM_MYDBLCLK、WM_MYTHRCLK,用它们分别标识鼠标的单击、双击和三

击事件。由于我们在两次连续的鼠标单击后还不能确定是否有三击,所以再增加一

个 WM_MYDBLCLKT伪消息,在处理该伪消息时再进一步判断双击与三击。我们只处理

WM_LBUTTONDOWN消息,所以注册窗口类时不设置CS_DBLCLKS风格。

具体处理过程如下:设置逻辑标志FLAG1及FLAG2,初始值均为FALSE,当已经单

击时将FLAG1置为TRUE,已经双击时将FLAG2置为TRUE。在处理WM_LBUTTONDOWN 消息

时通过函数 SetTimer增加一个计时器ID_TIMER1,计时器的时间参数置为鼠标双击

的时间间隔(用GetDoubleClickTime取得),并将FLAG1置为TRUE。如果计时器

D_TIMER1发出消息,则表明在规定时间内没有按键,可以判断鼠标为单击,可发出

WM_MYSNGCLK消息,同时将FLAG1置为FALSE;如果计时器消息没有产生,则表明在规

定的时间内有鼠标键按下,此时鼠标已经双击,将FLAG2置为TRUE,但是否有三击还

需要继续判断,此时发出WM_MYDBLCLKT消息,我们用同样的方法在伪消息

WM_MYDBLCLKT中再定义一个计时器ID_TIMER2。同理,如果计时器ID_TIMER2

发出消

息,则表明在规定时间内没有按键,可以判断鼠标为双击,可发出WM_MYDBLCLK 消息

;如果计时器ID_TIMER2没有发出消息,则表明在规定的时间内有鼠标键被按下,此

时鼠标已经三击,可以发出WM_MYTHRCLK消息。至此已完成识别,当然计时器要使用

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_USER+102 /*已经确定为双击时发出*/

#define WM_MYTHRCLK WM_USER+103 /*已经确定为三击时发出*/

LRESULT CALLBACK WndProc(HWND

hwnd,UINTuMessage,WPARAMwparam,LPARAMlparam)

{

static int FLAG1,FLAG2;

intwTime;

POINT pt;

switch (uMessage)

{

case WM_LBUTTONDOWN: /*程序只对单击消息进行处理,不处理双击消息*/

GetCursorPos(&pt); /*取鼠标位置用于传递消息中的LPARAM*/

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.x,pt.y));

FLAG1=FALSE;

KillTimer(hwnd,ID_TIMER1);

break;

相关文档
最新文档