Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別_第1頁
Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別_第2頁
Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別_第3頁
Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別_第4頁
Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Windows應(yīng)用程序中幾種特殊鼠標(biāo)事件的識(shí)別 鼠標(biāo)作為計(jì)算機(jī)輸入設(shè)備隨著Windows的流行而逐漸成為計(jì)算機(jī)的標(biāo)準(zhǔn)配置。在Windows中鼠標(biāo)的操作可以產(chǎn)生二十多個(gè)消息,主要分為客戶區(qū)鼠標(biāo)消息和非客戶區(qū)鼠標(biāo)消息兩大類,包括鼠標(biāo)的移動(dòng),左中右鍵的按下、釋放、雙擊等。事實(shí)上,實(shí)際的應(yīng)用程序中往往會(huì)用到一些特殊的鼠標(biāo)事件,如鼠標(biāo)三擊、左右鼠標(biāo)同時(shí)按下、鼠標(biāo)單擊雙擊三擊的獨(dú)立識(shí)別或依次處理等。下面結(jié)合筆者編程的體會(huì)來談一下Windows中這幾種特殊的鼠標(biāo)事件的識(shí)別方法。 一、獨(dú)立處理單擊、雙擊和三擊 我們先看一下Windows對(duì)鼠標(biāo)的響應(yīng)。對(duì)左鍵而言,如果鼠標(biāo)按下,則產(chǎn)生WM_LBUTTONDOWN

2、消息。接著,鼠標(biāo)釋放產(chǎn)生WM_LBUTTONUP消息;但如果鼠標(biāo)雙擊,則Windows并不僅僅只產(chǎn)生WM_LBUTTONDBLCLK 消息,而是先產(chǎn)生WM_LBUTTONDOWN消息,然后產(chǎn)生WM_LBUTTONDBLCLK消息,其中還有WM_LBUTTONUP等消息,這里暫不討論。對(duì)于鼠標(biāo)的三擊,Windows沒有提供獨(dú)立的消息,但我們不妨認(rèn)為三擊是在WM_LBUTTONDBLCLK消息之后再發(fā)一個(gè)WM_LBUTTONDOWN消息。所以,在應(yīng)用程序編程時(shí)若要窗口分別獨(dú)立地響應(yīng)鼠標(biāo)的單擊、雙擊、三擊消息,只有用戶自己動(dòng)手去處理。例如,Winows95中的文件夾改名就是一個(gè)例子,用鼠標(biāo)單擊一個(gè)已

3、經(jīng)加亮的文件夾名稱時(shí)稍作停留便可改名,如果雙擊則可打開該文件。這時(shí),就必須單獨(dú)處理鼠標(biāo)的單擊和雙擊,否則執(zhí)行順序應(yīng)該是先響應(yīng)WM_LBUTTONDOWN消息,然后再響應(yīng)WM_LBUTTONDBLCLK,即先改名再打開,這是事與愿違的。 為了單獨(dú)識(shí)別這三個(gè)鼠標(biāo)消息,我們不能直接使用WM_LBUTTONDOWN和WM_LBUTTONDBLCLK消息來判斷鼠標(biāo)的單擊和雙擊。這里,定義三個(gè)“偽”消息WM_MYSNGCLK、WM_MYDBLCLK、WM_MYTHRCLK,用它們分別標(biāo)識(shí)鼠標(biāo)的單擊、雙擊和三擊事件。由于我們?cè)趦纱芜B續(xù)的鼠標(biāo)單擊后還不能確定是否有三擊,所以再增加一個(gè) WM_MYDBLCLKT

4、偽消息,在處理該偽消息時(shí)再進(jìn)一步判斷雙擊與三擊。我們只處理WM_LBUTTONDOWN消息,所以注冊(cè)窗口類時(shí)不設(shè)置CS_DBLCLKS風(fēng)格。 具體處理過程如下:設(shè)置邏輯標(biāo)志FLAG1及FLAG2,初始值均為FALSE,當(dāng)已經(jīng)單擊時(shí)將FLAG1置為TRUE,已經(jīng)雙擊時(shí)將FLAG2置為TRUE。在處理WM_LBUTTONDOWN消息時(shí)通過函數(shù) SetTimer增加一個(gè)計(jì)時(shí)器ID_TIMER1,計(jì)時(shí)器的時(shí)間參數(shù)置為鼠標(biāo)雙擊的時(shí)間間隔(用GetDoubleClickTime取得),并將FLAG1置為TRUE。如果計(jì)時(shí)器D_TIMER1發(fā)出消息,則表明在規(guī)定時(shí)間內(nèi)沒有按鍵,可以判斷鼠標(biāo)為單擊,可發(fā)出WM

5、_MYSNGCLK消息,同時(shí)將FLAG1置為FALSE;如果計(jì)時(shí)器消息沒有產(chǎn)生,則表明在規(guī)定的時(shí)間內(nèi)有鼠標(biāo)鍵按下,此時(shí)鼠標(biāo)已經(jīng)雙擊,將FLAG2置為TRUE,但是否有三擊還需要繼續(xù)判斷,此時(shí)發(fā)出WM_MYDBLCLKT消息,我們用同樣的方法在偽消息WM_MYDBLCLKT中再定義一個(gè)計(jì)時(shí)器ID_TIMER2。同理,如果計(jì)時(shí)器ID_TIMER2發(fā)出消息,則表明在規(guī)定時(shí)間內(nèi)沒有按鍵,可以判斷鼠標(biāo)為雙擊,可發(fā)出WM_MYDBLCLK消息;如果計(jì)時(shí)器ID_TIMER2沒有發(fā)出消息,則表明在規(guī)定的時(shí)間內(nèi)有鼠標(biāo)鍵被按下,此時(shí)鼠標(biāo)已經(jīng)三擊,可以發(fā)出WM_MYTHRCLK消息。至此已完成識(shí)別,當(dāng)然計(jì)時(shí)器要使用

6、 KillTimer及時(shí)刪除。另外要注意的是,鼠標(biāo)雙擊的時(shí)間間隔不要設(shè)置太大,否則延時(shí)感太明顯。 下面是具體的實(shí)現(xiàn)方法,本文只給出窗口過程WndProc的部分內(nèi)容,其它函數(shù)與通常的Windows應(yīng)用程序大同小異,故從略。 #define ID_TIMER1 1001 /* 計(jì)時(shí)器1*/ #define ID_TIMER2 1002 /* 計(jì)時(shí)器2*/ #define WM_MYDBLCLKT WM_USER+100 /*當(dāng)已經(jīng)雙擊但還不能決定三擊時(shí)發(fā)出*/ #define WM_MYSNGCLK WM_USER+101 /*已經(jīng)確定為單擊時(shí)發(fā)出*/ #define WM_MYDBLCLK WM

7、_USER+102 /*已經(jīng)確定為雙擊時(shí)發(fā)出*/ #define WM_MYTHRCLK WM_USER+103 /*已經(jīng)確定為三擊時(shí)發(fā)出*/ LRESULT CALLBACK WndProc(HWND hwnd,UINT uMessage,WPARAM wparam,LPARAM lparam) static int FLAG1,FLAG2; int wTime; POINT pt; switch (uMessage) case WM_LBUTTONDOWN: /*程序只對(duì)單擊消息進(jìn)行處理,不處理雙擊消息*/ GetCursorPos(&pt); /*取鼠標(biāo)位置用于傳遞消息中的LPA

8、RAM*/ ScreenToClient(hwnd,&pt); if(! FLAG2) /*FLAG2不為真時(shí),鼠標(biāo)狀態(tài)為第一次單擊或第二次單擊*/ if(!FLAG1) /*FLAG1不為真時(shí)為第一次單擊*/ wTime=GetDoubleClickTime(); /*取鼠標(biāo)雙擊時(shí)間間隔*/ SetTimer(hwnd,ID_TIMER1,wTime,NULL); /*第一次單擊后建立計(jì)時(shí)器*/ if(FLAG1) /*FLAG1為真,已經(jīng)確定為雙擊,發(fā)出WM_MYDBLCLKT繼續(xù)判斷*/ PostMessage(hwnd,WM_MYDBLCLKT,0,MAKELPARAM(pt.

9、x,pt.y); FLAG1=FALSE; KillTimer(hwnd,ID_TIMER1); break; FLAG1=TRUE; if(FLAG2) /*FLAG2為真,已經(jīng)確定為三擊*/ PostMessage(hwnd,WM_MYTHRCLK,0,MAKELPARAM(pt.x,pt.y); FLAG2=FALSE; KillTimer(hwnd,ID_TIMER2); break; break; case WM_TIMER: /*計(jì)時(shí)器消息產(chǎn)生,說明鼠標(biāo)沒有按鍵操作*/ switch(wparam) case ID_TIMER1: /*第一次按鍵后沒有后續(xù)按鍵,故確定為單擊*/ 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: /*第二次按鍵后沒有后續(xù)按鍵,故確定為雙擊*/ 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: /*如果鼠標(biāo)移動(dòng),則不認(rèn)為是雙擊或三擊*/ FLAG1=FALSE; FLAG2=FALSE; break; case WM_MYDBLCLKT: /*雙擊后等待再次按鼠標(biāo)鍵*/ wTime=GetDoubleClickTime(); SetTimer(hwnd,ID_TIMER2,wTime,NULL); FLAG2=TRUE; break; case WM_MYSNGCLK: /*處理單擊*/ break; case WM_MYDBLCLK: /*處理雙擊*

12、/ break; case WM_MYTHRCLK: /*處理三擊*/ break; /其它消息 二、 依次處理單擊、雙擊和三擊 鼠標(biāo)的單擊、雙擊、三擊處理還有一種情況。例如,Word及其它字處理軟件中用鼠標(biāo)選擇編輯區(qū)域的處理方法,單擊則定位插入點(diǎn),雙擊則選中一個(gè)詞,三擊則選中一個(gè)段落。這種處理鼠標(biāo)的方法是依次處理單擊、雙擊、三擊。下面要介紹的這種鼠標(biāo)事件的處理方法與上述獨(dú)立識(shí)別方法的思路基本相同,不同之處在于注冊(cè)窗口類時(shí)風(fēng)格設(shè)置為CS_DBLCLKS,以便窗口類識(shí)別鼠標(biāo)雙擊。 具體方法是:在處理鼠標(biāo)雙擊消息處理時(shí)發(fā)出WM_MYDBLCLK消息,同時(shí)設(shè)置計(jì)時(shí)器,并置標(biāo)志FLAG為TRUE(初始

13、值為FALSE),這樣在處理WM_LBUTTINDOWN時(shí)判斷FLAG的值:若為FALSE則為單擊,發(fā)送WM_MYSNGCLK消息;若為TRUE則為雙擊之后的一次單擊(即三擊),發(fā)送WM_MYTHRCLK消息,從而完成消息的識(shí)別。計(jì)時(shí)器的作用,只是等待雙擊之后是否出現(xiàn)單擊。如果計(jì)時(shí)器消息已經(jīng)發(fā)出則說明后面已經(jīng)沒有按鍵,這時(shí)可以刪除計(jì)時(shí)器,從單擊處重新進(jìn)行識(shí)別。 下面是窗口函數(shù)WndProc的部分內(nèi)容,程序注釋部分說明了與上例的差別。 #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); /*計(jì)時(shí)器產(chǎn)生時(shí),簡(jiǎn)單刪除*/ FLAG=FALSE; break; break; case WM_LBUTTONDBLCLK: GetCursorPos(&

16、;pt); ScreenToClient(hwnd,&pt); wTime=GetDoubleClickTime(); SetTimer(hwnd,ID_TIMER,wTime,NULL); /*設(shè)置計(jì)時(shí)器*/ PostMessage(hwnd,WM_MYDBLCLK,0,MAKELPARAM(pt.x,pt.y); FLAG=TRUE; break; case WM_MOUSEMOVE:/*鼠標(biāo)移動(dòng),則從單擊重新開始判斷*/ FLAG=FALSE; break; case WM_MYSNGCLK: /*處理單擊*/ break; case WM_MYDBLCLK: /*處理雙擊*/ break; case WM_MYTHRCLK: /*處理三擊*/ break; /其它消息 三、鼠標(biāo)左右鍵同時(shí)按下與鼠標(biāo)與鍵盤同時(shí)按下的識(shí)別 玩過Windows的掃雷游戲嗎?該游戲中就有一個(gè)同時(shí)按下鼠標(biāo)左右鍵的操作,其實(shí)對(duì)同時(shí)按下鼠標(biāo)左右鍵的判斷并不復(fù)雜,判斷方法與判斷鼠標(biāo)按鍵是否與Ctrl和Shift同時(shí)按下的方法相同,這里要用到鼠標(biāo)消息中的wparam項(xiàng),其中含

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論