1. 程式人生 > >[MFC]滑鼠訊息處理

[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 ) { ... }