闲来无事,在WIN2K下用BCB5做了个键盘挂钩小程序,监视全局按键情况。Hook安放和回调函数放在一个单独DLL中,DLL原码如下:
//---------------------------------------------------------------------------------------------------- extern "C" __declspec(dllexport) void __stdcall SetHook(HWND,bool); LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam) //---------------------------------------------------------------------------------------------------- static HINSTANCE hInstance; // 应用实例句柄 static HWND hWndMain; // MainForm句柄 static HHOOK hKeyHook; // HOOK句柄 static const myMessage=2000; // 自定义消息号 static const SecondPar=1; // 自定义消息第2参数 //---------------------------------------------------------------------------------------------------- int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { hInstance=hinst; return 1; } //---------------------------------------------------------------------------------------------------- void __stdcall SetHook(HWND hMainWin,bool nCode) { if(nCode) // 安放HOOK { hWndMain=hMainWin; hKeyHook=SetWindowsHookEx(WH_JOURNALRECORD,(HOOKPROC)HookProc,hInstance,0); } else // 卸下HOOK UnhookWindowsHookEx(hKeyHook); } //---------------------------------------------------------------------------------------------------- LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam) { EVENTMSG *keyMSG=(EVENTMSG *)lParam; if((nCode==HC_ACTION)&&(keyMSG->message==WM_KEYUP)) PostMessage(hWndMain,myMessage,(char)(keyMSG->paramL),SecondPar); // 向调用窗体发消息myMessage和虚拟键码(char)(keyMSG->paramL) return((int)CallNextHookEx(hKeyHook,nCode,wParam,lParam)); } //----------------------------------------------------------------------------------------------------
应用代码如下:(调DLL) //---------------------------------------------------------------------------------------------------- static HINSTANCE hDLL; // DLL句柄 typedef void __stdcall (*DLLFUN)(HWND,bool); DLLFUN DLLSetHook; static const myMessage=2000; static const SecondPar=1; //---------------------------------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) {} //---------------------------------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { hDLL=LoadLibrary((LPCTSTR)"Project1.dll"); // DLL文件名:Project1.dll if(hDLL==NULL) { ShowMessage("DLL: 不能加载!程序退出。"); exit(1); } DLLSetHook =(DLLFUN)GetProcAddress(hDLL,"SetHook"); if(DLLSetHook==NULL) { ShowMessage("DLL: 函数没找到!程序退出。"); FreeLibrary(hDLL); exit(1); } DLLSetHook(this->Handle,true); } //---------------------------------------------------------------------------------------------------- void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { DLLSetHook(NULL,false); // 卸下HOOK FreeLibrary(hDLL); // 卸下DLL } //---------------------------------------------------------------------------------------------------- void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,bool &Handled) { // BCB5.0 的ApplicationEvents元件 if((Msg.message==myMessage)&&(Msg.lParam==SecondPar)) ShowMessage(" 收到HOOK按键消息!\n\n 【键虚拟码】:"+IntToStr(Msg.wParam)); } //----------------------------------------------------------------------------------------------------
用 WH_JOURNALRECORD 类型HOOK可简单实现.
|