zoukankan      html  css  js  c++  java
  • 全局键盘钩子(WH_KEYBOARD)

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

    KeyBoardHook.dll代码

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

    TestKeyBoardHook主程序代码

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

    运行结果

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

  • 相关阅读:
    chmod
    How to Mount an NTFS Filesystem
    关于三层架构和AJAX的一点联系
    Visual Studio开启.NET Framework源代码调试(Debug the Source Code for the .NET Framework Libraries)
    SQL语句中的子查询应用
    .NET中总共有多少种类型、多少个命名空间呢?
    Visual Studio中的《C# 语言规范》
    Visual Studio “类视图”和“对象浏览器”图标含义
    .NET程序员必备参考图片
    Microsoft Visual Studio Learning Pack 2.0
  • 原文地址:https://www.cnblogs.com/findumars/p/5001978.html
Copyright © 2011-2022 走看看