全局键盘钩子(WH_KEYBOARD)

为了显示效果,在钩子的DLL中我们会获取挂钩函数的窗体句柄,这里的主程序窗体名为"TestMain",通过FindWindow查找。

KeyBoardHook.dll代码

  1. library KeyBoardHook;
  2. { Important note about DLL memory management: ShareMem must be the
  3. first unit in your library's USES clause AND your project's (select
  4. Project-View Source) USES clause if your DLL exports any procedures or
  5. functions that pass strings as parameters or function results. This
  6. applies to all strings passed to and from your DLL--even those that
  7. are nested in records and classes. ShareMem is the interface unit to
  8. the BORLNDMM.DLL shared memory manager, which must be deployed along
  9. with your DLL. To avoid using BORLNDMM.DLL, pass string information
  10. using PChar or ShortString parameters. }
  11. uses
  12. SysUtils,Windows,Messages,
  13. Classes;
  14. var
  15. fHook:HHOOK;
  16. //执行挂钩程序的窗体句柄
  17. CallHandle:HWND;
  18. {$R *.res}
  19. //回调过程
  20. function HookProc(code:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
  21. var
  22. processid:Cardinal;
  23. begin
  24. //如果有键盘动作
  25. if code = HC_Action then
  26. begin
  27. //获取注入进程的进程id
  28. processid := GetCurrentProcessId;
  29. //如果CallHandle,则查找TestMain窗体句柄
  30. if CallHandle = 0 then
  31. CallHandle := FindWindow(nil,'TestMain');
  32. //获取按键状态 小于0表示按下,如果不做判断,按键按下或抬起都会执行SendMessage
  33. //下面发送WM_USER+101消息,此消息可以用自定义的消息标识发送
  34. if GetKeyState(wParam) < 0 then
  35. SendMessage(CallHandle,WM_USER+101,wParam,processid);
  36. end
  37. else
  38. //下一个钩子
  39. Result := CallNextHookEx(fHook,code,wParam,lParam);
  40. end;
  41. procedure SetHook;stdcall;
  42. begin
  43. //挂钩,这里没有做挂钩失败的提示
  44. fHook := SetWindowsHookEx(WH_KEYBOARD,@HookProc,HInstance,0);
  45. end;
  46. procedure StopHook;stdcall;
  47. begin
  48. //摘钩
  49. if fHook <> 0 then
  50. UnhookWindowsHookEx(fHook);
  51. end;
  52. exports
  53. SetHook name 'SetHook',
  54. StopHook name 'StopHook';
  55. begin
  56. //初始CallHandle为0
  57. CallHandle := 0;
  58. end.

TestKeyBoardHook主程序代码

  1. {
  2. 此窗体用来执行挂钩,为了方便起见,我们把系统的按键返回到该窗体的Memo组件中进行
  3. 显示,所以在dll中,做了获取主窗体的句柄的工作,以便发消息给主窗体,告诉它是哪个
  4. 按键被按下
  5. }
  6. unit TestMain;
  7. interface
  8. uses
  9. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  10. Dialogs, StdCtrls,TlHelp32;
  11. type
  12. TfrmTestMain = class(TForm)
  13. Memo1: TMemo;
  14. btn_SetHook: TButton;
  15. btn_StopHook: TButton;
  16. procedure btn_SetHookClick(Sender: TObject);
  17. procedure btn_StopHookClick(Sender: TObject);
  18. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  19. private
  20. { Private declarations }
  21. procedure WndProc(var Message: TMessage);override;
  22. public
  23. { Public declarations }
  24. end;
  25. var
  26. frmTestMain: TfrmTestMain;
  27. implementation
  28. procedure SetHook;stdcall;external 'KeyBoardHook';
  29. procedure StopHook;stdcall;external 'KeyBoardHook';
  30. {$R *.dfm}
  31. procedure TfrmTestMain.btn_SetHookClick(Sender: TObject);
  32. begin
  33. SetHook;
  34. end;
  35. procedure TfrmTestMain.btn_StopHookClick(Sender: TObject);
  36. begin
  37. StopHook;
  38. end;
  39. procedure TfrmTestMain.WndProc(var Message: TMessage);
  40. var
  41. hSnapShot:THandle;
  42. pEntry:TProcessEntry32;
  43. find:Boolean;
  44. proName:string;
  45. begin
  46. if Message.Msg = WM_USER+101 then
  47. begin
  48. //创建进程快照
  49. hSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  50. pEntry.dwSize := SizeOf(pEntry);
  51. find := Process32First(hSnapShot,pEntry);
  52. while find do
  53. begin
  54. //取进程名字
  55. proName := pEntry.szExeFile;
  56. if pEntry.th32ProcessID = Message.LParam then Break;
  57. find := Process32Next(hSnapShot,pEntry);
  58. end;
  59. Memo1.Lines.Add('进程:' + proName + ',ID:' +IntToStr(Message.LParam)+'按下按键:'+Chr(Message.WParam));
  60. CloseHandle(hSnapShot);
  61. end;
  62. inherited;
  63. end;
  64. procedure TfrmTestMain.FormClose(Sender: TObject;
  65. var Action: TCloseAction);
  66. begin
  67. StopHook;
  68. end;
  69. end.

运行结果

全局键盘钩子(WH_KEYBOARD)

http://blog.csdn.net/bdmh/article/details/6124127

上一篇:VMware workstation 10.0的永久key


下一篇:iOS--tableview分组