天天看點

C++Builder實作滑鼠鈎子

DLL中的代碼:

#define WM_KEY_HOOK    WM_USER+200  //自定義消息

extern "C" {

  __declspec(dllexport)  BOOL APIENTRY StartHook(); //安裝鍵盤鈎子

  __declspec(dllexport)  BOOL APIENTRY EndHook();   //删除鍵盤鈎子

  LRESULT WINAPI KeyProc(int nCode,WPARAM wparam,LPARAM lparam);

}

HHOOK     hHook=NULL;           //滑鼠鈎子函數句柄

HINSTANCE hInstance=NULL;       //DLL執行個體句柄

#pragma argsused

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)

{

        hInstance=hinst;

        return 1;

}

//---------------------------------------------------------------------------

__declspec(dllexport)  BOOL APIENTRY StartHook()

{

        hHook=SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyProc,hInstance,0);

        return (bool)hHook;

}

__declspec(dllexport)  BOOL APIENTRY EndHook()

{

        if(hHook&&UnhookWindowsHookEx(hHook))

           hHook=NULL;

        return (bool)hHook;

}

__declspec(dllexport) LRESULT WINAPI KeyProc(int nCode,WPARAM wparam,LPARAM lparam) {

        HWND hwnd;

        hwnd=FindWindow(NULL,"鍵盤鈎子測試");

        KBDLLHOOKSTRUCT *keyMSG=(KBDLLHOOKSTRUCT *)lparam;

        if(nCode==HC_ACTION && (WM_KEYDOWN == wparam || wparam == WM_SYSKEYDOWN))

        {

                DWORD dwMsg = 1;

                dwMsg += keyMSG->scanCode << 16;

                dwMsg += keyMSG->flags << 24;

                SendMessage(hwnd,WM_KEY_HOOK,(WPARAM)(dwMsg), lparam);

        }

        return CallNextHookEx(hHook,nCode,wparam,lparam); //繼續傳遞滑鼠消息

}

測試程式中的代碼:

頭檔案中:自定義消息類型和消息映射函數

#define WM_KEY_HOOK    WM_USER+200  //自定義消息

void __fastcall OnKeyHook(TMessage &Msg);

BEGIN_MESSAGE_MAP

        MESSAGE_HANDLER(WM_KEY_HOOK, TMessage, OnKeyHook);

END_MESSAGE_MAP(TForm);

源碼中:

首先,聲明需要調用外部方法,用于安裝和解除安裝鈎子(按鈕事件觸發):

extern "C" {

 BOOL APIENTRY StartHook(); //安裝滑鼠鈎子

 BOOL APIENTRY EndHook();   //删除鈎子

}

再實作OnKeyHook方法:

void __fastcall TForm1::OnKeyHook(TMessage &Msg)

{

        AnsiString  str;

        //擷取最前端視窗的句柄

        HWND hwnd = GetForegroundWindow();

        char windowTitle[50] = {0};

        GetWindowText(hwnd,windowTitle,sizeof(windowTitle));

        AnsiString result = AnsiString(windowTitle[0]);

        str += windowTitle;

        str += ":按下按鍵[" ;

        char key[20]={0};

        GetKeyNameText(Msg.WParam, key, 20);//根據滑鼠資訊擷取按鍵名

        str += key;

        str += "]";

        Memo1->Lines->Add(str);

}

源碼雲盤位址:http://pan.baidu.com/s/1bn2Yi67