VB.net中全局键盘钩子(Keyboard Hook)

楔子

    网上关于Hook(钩子)的例子有很多,本文旨在简单且详细的介绍一下全局键盘的钩子,适合对钩子没有任何概念的人群,选用的IDE环境为VB.net和BCB6.0。

 

1.钩子的本质

 

    什么是钩子(Hook)?

    Windows的应用程序全部都是基于消息驱动的,而钩子,是一段用来处理系统消息的程序,是Windows消息的处理平台,从种类上可以分为多种,如键盘(WH_KEYBOARD),鼠标(WH_MOUSE)等,从监听的级别上又分为系统级和线程级,不过所谓的系统级其实也可以认为是线程级,稍后解释。

   

    系统钩子,监听当前系统中所有指定的消息。但是系统钩子会影响到系统中的所有应用程序的运行,因此需要将钩子函数放入到独立的动态链接库当中,也就是要写一个独立的DLL文件来完成。系统会自动将包含钩子回调函数的DLL映射到受钩子函数影响的所有进程的地址空间当中。

 

2.用到的Windows的API

    SetWindowsHookEx(int idHook, HooKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)

    作用:

        安装钩子

    具体参数含义为:

        idHook:

            钩子的类型,如WH_KEYBOARD,就是想要监听什么消息

        lpfn:

            钩子过程的指针,就是回调函数,拦截到了消息之后处理函数的指针(函数在内存中的入口地址)

        hMod:

            应用程序实例的句柄。0表示自己

        dwThreadId:

            安装钩子的线程ID。0的话表示全局,即系统钩子,说到这里,提一下为什么说系统钩子实际上也是个线程够子,因为安装的钩子的线程ID是0,而Windows系统当中的线程ID为0的是谁?不错,就是桌面这个大窗口~,因为我们绝大部分的操作都是基于窗口消息的,而所有窗口的父窗口都是桌面这个大窗口,因此这个全局是相对与其他窗口程序的。

 

    UnHookWindowsHookEx(HHOOK hkk)

    作用:

            注销钩子

    具体参数含义为:

            hKK:

                钩子实例的名称

 

3.在VB.net中的实现

 

    实现需要三个步骤:

        (1)    了解什么是钩子

        (2)    编写独立的钩子的dll

        (3)    在VB.net中调用

    我们已经完成了第一个,下面说第二个步骤

    

    大家可以选用任何一种可以编写dll的工具,这里选用BCB6.0

    

    (1)新建一个DLL

    (2)代码如下:

 

DLL名称:

    KeyHook.dll

  1. #include <vcl.h>
  2. #include <windows.h>
  3. #include "windef.h"
  4. #pragma hdrstop
  5. #pragma argsused
  6. typedef LRESULT ( CALLBACK *HookProc)(int code, WPARAM w, LPARAM l);
  7. typedef  void (__stdcall  CALLBACK *Bakfun)(WPARAM w,KBDLLHOOKSTRUCT* k);
  8. //变量定义
  9. HookProc g_lpfnkeyboardProc;
  10. Bakfun g_bakProc;
  11. HINSTANCE hins=NULL;
  12. static HHOOK hkb=NULL;
  13. int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
  14. {
  15.         hins=hinst;
  16.         return 1;
  17. }
  18. //回调函数
  19. LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
  20. {
  21.         KBDLLHOOKSTRUCT* pstruct=(KBDLLHOOKSTRUCT*)lParam;
  22.         g_bakProc(wParam,pstruct); //回调函数,进入vb.net处理函数中
  23.         return CallNextHookEx( hkb, nCode, wParam, lParam );
  24. }
  25. //钩子启动函数
  26. extern "C"  __declspec(dllexportbool __stdcall  installhook(Bakfun lp)
  27. {
  28.         g_bakProc=lp;
  29.         hkb=SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyboardProc,hins,0);
  30.         return TRUE;
  31. }
  32. //卸载钩子函数
  33. extern "C"  __declspec(dllexportBOOL __stdcall  UnHook()
  34. {
  35.     BOOL unhooked = UnhookWindowsHookEx(hkb);
  36.     return unhooked;
  37. }

在VB.net中的代码

 

  1.     Public Declare Function installhook Lib "KeyHook.dll" (ByVal lp As HookProc) As Boolean
  2.     Public Declare Sub UnHook Lib "KeyHook.dll" ()
  3.     Public Delegate Sub HookProc(ByVal a As System.UIntPtr, ByVal ks As System.IntPtr)
  4.     Public Structure KBDLLHOOKSTRUCT
  5.         Dim vkCode As Integer
  6.         Dim scanCode As Integer
  7.         Dim flags As Integer
  8.         Dim time As Integer
  9.         Dim dwExtraInfo As Integer
  10.     End Structure
  11.     Public Enum KEYACTION
  12.         ACTION_KEYDOWN = WM_KEYDOWN
  13.         ACTION_KEYUP = WM_KEYUP
  14.         ACTION_SYSKEYDOWN = WM_SYSKEYDOWN
  15.         ACTION_SYSKEYUP = WM_SYSKEYUP
  16.     End Enum
  17.     Public Const WM_KEYDOWN = 
  18.     Public Const WM_KEYUP = 
  19.     Public Const WM_SYSKEYDOWN = 
  20.     Public Const WM_SYSKEYUP = 
  21.     Public Const DT_LEFT = 
  22.     Private Keys As Integer = 0
  23.     Public Sub HookProc1(ByVal a As System.UIntPtr, ByVal ks As System.IntPtr)
  24.         Dim kk As KBDLLHOOKSTRUCT
  25.         Dim KeyboardEvent As KEYACTION = CType(a.ToUInt32, KEYACTION)
  26.         If KeyboardEvent = KEYACTION.ACTION_KEYUP Then
  27.             kk = System.Runtime.InteropServices.Marshal.PtrToStructure(ks, kk.GetType())
  28.             Select Case kk.vkCode
  29.                 Case 88 'a的ASCII编码
  30.                     MessageBox.Show("a")
  31.             End Select
  32.         End If
  33.     End Sub

在主窗口当中

  1.     Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
  2.         Static hkproc As HookProc
  3.         hkproc = AddressOf HookProc1
  4.         installhook(hkproc)
  5.     End Sub

 

运行程序即可,在任何窗口下按下键盘上的"A"键,都可以看到弹出一个对话框

 

PS:

    程序代码摘自http://www.ihome99.com/xiaowu/html/88/165788-32337.html

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C#使用全局鼠标、键盘Hook需要使用Win32 API来实现,以下是一个简单的示例代码: ```csharp using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace GlobalHookDemo { class Program { private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", SetLastError = true)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); private const int WH_KEYBOARD_LL = 13; private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; static void Main(string[] args) { _hookID = SetHook(_proc); Console.WriteLine("Global keyboard hook installed."); Console.WriteLine("Press any key to exit."); Console.ReadKey(); UnhookWindowsHookEx(_hookID); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)0x100) { int vkCode = Marshal.ReadInt32(lParam); Console.WriteLine((Keys)vkCode); } return CallNextHookEx(_hookID, nCode, wParam, lParam); } } } ``` 这个示例代码可以监听全局键盘事件并输出键码。如果需要监听鼠标事件,可以使用`SetWindowsHookEx`函数的第一个参数`idHook`设置为`WH_MOUSE_LL`。需要注意的是,全局Hook会影响系统性能,使用时需要谨慎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值