Chui-Wen's profileChui-Wen Chiu's NoteBlogListsGuestbookMore Tools Help

Blog


    11/21/2005

    [C++]偵測系統的滑鼠事件

    阿發總是給我丟難題,今天的題目是要偵測Windows上任何地方都能夠偵測目前的滑鼠是否被按下,為何有這種需求呢?因為他要做觸控螢幕,需要在每個點選位置上發出聲音,所以必須在系統的任何地方都能夠偵測出滑鼠目前是否被按下。這個問題我聽到之後就想到可以用 hook 來處理,不過實作細節並不太記得,在找了許多的資料之後,終於解開這個問題,其實也沒這麼困難,程式執行畫面如附圖,程式碼如下:
    //---------------------------------------------------------------------------
    /*
     * 偵測系統的滑鼠事件
     *
     * 設計者:Chui-Wen Chiu (Arick)
     *
     * 開發環境:
     * [1] Windows 2000 Professional + SP4
     * [2] Borland C++ Builder 6.0
     *
     * 參考資料:
     * [1] http://forum.kuanshan.com.tw/read.php?tid=13999
     * [2] LowLevelMouseProc Function, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/lowlevelmouseproc.asp
     * [3] SetWindowsHookEx Function, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindowshookex.asp
     * [4] SetWindowsHookEx Function, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/unhookwindowshookex.asp
     * [5] CallNextHookEx Function, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/callnexthookex.asp
     * [6] http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/usinghooks.asp
     * [7] Jeffrey Richter, "Windows 應用程式設計開發指南"
     *
     * 開發日誌:
     * 2005.11.21  建立
     */
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    #include "windows.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    HHOOK g_hhook;
    // 處理攔截的滑鼠事件
    LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
       if (nCode < 0)  // do not process the message
          return CallNextHookEx(g_hhook, nCode, wParam, lParam);
          switch(wParam){
             case WM_LBUTTONDOWN:
                Form1->Label1->Caption = "按下滑鼠左鍵";
                break;
             case WM_LBUTTONUP:
                Form1->Label1->Caption = "放開滑鼠左鍵";
                break;
             case WM_MOUSEMOVE:
                Form1->Label1->Caption = "滑鼠移動中";
                break;
             case WM_MOUSEWHEEL:
                Form1->Label1->Caption = "捲動滾輪";
                break;
             case WM_RBUTTONDOWN:
                Form1->Label1->Caption = "按下滑鼠右鍵";
                break;
             case WM_RBUTTONUP:
                Form1->Label1->Caption = "放開滑鼠右鍵";
                break;
          }
       return CallNextHookEx(g_hhook, nCode, wParam, lParam);
    }
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
       // 程式結束的時候釋放攔截
       UnhookWindowsHookEx(g_hhook);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
       // 建立滑鼠攔截
       g_hhook = SetWindowsHookEx(
          WH_MOUSE_LL,
          (HOOKPROC) ::LowLevelMouseProc,
          GetModuleHandle (NULL),
          NULL
       );
       // 建立失敗
       if (g_hhook == NULL){
          Application->MessageBoxA("ERROR", "" , 0);
          Application->Terminate();
       }
    }

    說穿了也不過就是在系統中註冊一個函數(SetWindowsHookEx),這個函數會接收攔截到的滑鼠事件(LowLevelMouseProc)。如果要攔截其他的訊息可以參考 MSDN上關於 hook 的資料。
     

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks (1)

    The trackback URL for this entry is:
    http://chuiwenchiu.spaces.live.com/blog/cns!CA5D9227DF9E78E8!374.trak
    Weblogs that reference this entry