【小沐学C++】C++ 实现鼠标键盘钩子HOOK

这篇具有很好参考价值的文章主要介绍了【小沐学C++】C++ 实现鼠标键盘钩子HOOK。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、简介

https://learn.microsoft.com/zh-cn/windows/win32/winmsg/about-hooks

挂钩是应用程序截获消息、鼠标操作和击键等事件的机制。 截获特定类型的事件的函数称为 挂钩过程。 挂钩过程可以对其接收的每个事件执行操作,然后修改或放弃该事件。
【小沐学C++】C++ 实现鼠标键盘钩子HOOK,C/C++,c++,计算机外设,开发语言,钩子,hook,鼠标,键盘

挂钩是系统消息处理机制中的一个点,其中应用程序可以安装子例程来监视系统中的消息流量,并在某些类型的消息到达目标窗口过程之前对其进行处理。
【小沐学C++】C++ 实现鼠标键盘钩子HOOK,C/C++,c++,计算机外设,开发语言,钩子,hook,鼠标,键盘

以下一些示例使用 挂钩:

  • 监视用于调试的消息
  • 支持录制和播放宏
  • 为帮助密钥 (F1) 提供支持
  • 模拟鼠标和键盘输入
  • 实现基于计算机的训练 (CBT) 应用程序

【小沐学C++】C++ 实现鼠标键盘钩子HOOK,C/C++,c++,计算机外设,开发语言,钩子,hook,鼠标,键盘

2、相关函数

2.1 SetWindowsHookEx

将应用程序定义的挂钩过程安装到挂钩链中。 你将安装挂钩过程来监视系统的某些类型的事件。 这些事件与特定线程或与调用线程位于同一桌面中的所有线程相关联。

HHOOK SetWindowsHookExA(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);

HHOOK SetWindowsHookExW(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);
  • WH_KEYBOARD
    安装用于监视击键消息的挂钩过程。 有关详细信息,请参阅 KeyboardProc 挂钩过程。
LRESULT CALLBACK KeyboardProc(
  _In_ int    code,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
  • WH_KEYBOARD_LL
    安装用于监视低级别键盘输入事件的挂钩过程。 有关详细信息,请参阅 [LowLevelKeyboardProc] (/windows/win32/winmsg/lowlevelkeyboardproc) 挂钩过程。
LRESULT CALLBACK LowLevelKeyboardProc(
  _In_ int    nCode,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
// 其中lParam指向 KBDLLHOOKSTRUCT 结构的指针。
  • WH_MOUSE
    安装监视鼠标消息的挂钩过程。 有关详细信息,请参阅 MouseProc 挂钩过程。
LRESULT CALLBACK MouseProc(
  _In_ int    nCode,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
  • WH_MOUSE_LL
    安装用于监视低级别鼠标输入事件的挂钩过程。 有关详细信息,请参阅 LowLevelMouseProc 挂钩过程。
LRESULT CALLBACK LowLevelMouseProc(
  _In_ int    nCode,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
// 其中lParam指向 MSLLHOOKSTRUCT 结构的指针。

2.2 UnhookWindowsHookEx

删除 SetWindowsHookEx 函数安装在挂钩链中的挂钩过程。

BOOL UnhookWindowsHookEx(
  [in] HHOOK hhk
);

2.3 CallNextHookEx

将挂钩信息传递给当前挂钩链中的下一个挂钩过程。 挂钩过程可以在处理挂钩信息之前或之后调用此函数。

LRESULT CallNextHookEx(
  [in, optional] HHOOK  hhk,
  [in]           int    nCode,
  [in]           WPARAM wParam,
  [in]           LPARAM lParam
);

3、相关结构体

3.1 KBDLLHOOKSTRUCT

包含有关低级别键盘输入事件的信息。

typedef struct tagKBDLLHOOKSTRUCT {
  DWORD     vkCode;
  DWORD     scanCode;
  DWORD     flags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;

3.2 MSLLHOOKSTRUCT

包含有关低级别鼠标输入事件的信息。

typedef struct tagMSLLHOOKSTRUCT {
  POINT     pt;
  DWORD     mouseData;
  DWORD     flags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;

4、挂钩过程

  • 定义挂钩过程
    为了利用特定类型的挂钩,开发人员提供了一个挂钩过程,并使用 SetWindowsHookEx 函数将其安装到与挂钩关联的链中。 挂钩过程必须具有以下语法:
LRESULT CALLBACK HookProc(
  int nCode, 
  WPARAM wParam, 
  LPARAM lParam
)
{
   // process event
   ...

   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

SetWindowsHookEx 函数始终在挂钩链的开头安装挂钩过程。 当发生由特定类型的挂钩监视的事件时,系统会在与挂钩关联的挂钩链的开头调用过程。 链中的每个挂钩过程确定是否将事件传递给下一个过程。 挂钩过程通过调用 CallNextHookEx 函数将事件传递给下一过程。

  • 安装和释放挂钩过程
    SetWindowsHookEx 传递模块句柄、指向挂钩过程入口点的指针,以及线程标识符的 0,指示挂钩过程应与调用线程位于同一桌面中的所有线程相关联。 以下示例中显示了此序列。
HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL; 
static HHOOK hhookSysMsg; 
 
hinstDLL = LoadLibrary(TEXT("c:\\myapp\\sysmsg.dll")); 
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); 

hhookSysMsg = SetWindowsHookEx( 
                    WH_SYSMSGFILTER,
                    hkprcSysMsg,
                    hinstDLL,
                    0);

可以通过调用 UnhookWindowsHookEx 函数来释放特定于线程的挂钩过程, (从挂钩链) 中删除其地址,并指定要释放的挂钩过程的句柄。 一旦应用程序不再需要挂钩过程,就立即释放它。

5、代码测试

5.1 代码1


#include "pch.h"
#include <Windows.h>
#include <iostream>

std::string get_time()
{
	SYSTEMTIME sys;
	GetLocalTime(&sys);
	char time[255] = { 0 };
	sprintf_s(time, "[%4d/%02d/%02d %02d:%02d:%02d]", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond);

	return std::string(time);
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	/*
	typedef struct tagKBDLLHOOKSTRUCT {
	DWORD     vkCode;		// 按键代号
	DWORD     scanCode;		// 硬件扫描代号,同 vkCode 也可以作为按键的代号。
	DWORD     flags;		// 事件类型,一般按键按下为 0 抬起为 128。
	DWORD     time;			// 消息时间戳
	ULONG_PTR dwExtraInfo;	// 消息附加信息,一般为 0。
	}KBDLLHOOKSTRUCT,*LPKBDLLHOOKSTRUCT,*PKBDLLHOOKSTRUCT;
	*/
	KBDLLHOOKSTRUCT* ks = (KBDLLHOOKSTRUCT*)lParam;		// 包含低级键盘输入事件信息
	char buffer[255];
	DWORD code = ks->vkCode;
	std::string t = get_time();
	char state[20];

	if (wParam == WM_KEYDOWN)
	{
		strcpy_s(state, "按下");
	}
	else if (wParam == WM_KEYUP)
	{
		strcpy_s(state, "抬起");
	}

	sprintf_s(buffer, "[键盘]%s 键代码:%d %s", t.c_str(), code, state);
	std::cout << buffer << std::endl;

	//return 1;	// 拦截消息
	return CallNextHookEx(NULL, nCode, wParam, lParam);
}

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	/*
	typedef struct tagMOUSEHOOKSTRUCT {
		POINT   pt;					// Point数据
		HWND    hwnd;				// 接收鼠标消息的窗体的句柄
		UINT    wHitTestCode;		// 指定点击测试值
		ULONG_PTR dwExtraInfo;		// 指定和该消息相关联的附加信息。
	} MOUSEHOOKSTRUCT, FAR* LPMOUSEHOOKSTRUCT, * PMOUSEHOOKSTRUCT;
	*/

	MOUSEHOOKSTRUCT* ms = (MOUSEHOOKSTRUCT*)lParam;
	POINT pt = ms->pt;
	std::string time = get_time();
	char buffer[1024];
	char state[20] = "未知";

	if (wParam == WM_LBUTTONDOWN)
	{
		strcpy_s(state, "左键按下");
	}
	else if (wParam == WM_LBUTTONUP)
	{
		strcpy_s(state, "左键抬起");
	}
	else if (wParam == WM_RBUTTONDOWN)
	{
		strcpy_s(state, "右键按下");
	}
	else if (wParam == WM_RBUTTONUP)
	{
		strcpy_s(state, "右键抬起");
	}
	else if (wParam == WM_MOUSEMOVE)
	{
		strcpy_s(state, "移动");
	}

	sprintf_s(buffer, "[鼠标]%s 键代码:x:%d y:%d %s", time.c_str(), pt.x, pt.y, state);
	std::cout << buffer << std::endl;

	//return 1;	// 拦截消息
	return CallNextHookEx(NULL, nCode, wParam, lParam);

}

int main()
{
	HINSTANCE hM = GetModuleHandle(NULL), hK = GetModuleHandle(NULL);
	HHOOK g_Hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, hK, 0);
	HHOOK g_Hook2 = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, hM, 0);

	// 消息循环
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	UnhookWindowsHookEx(g_Hook);

	return 0;
}


【小沐学C++】C++ 实现鼠标键盘钩子HOOK,C/C++,c++,计算机外设,开发语言,钩子,hook,鼠标,键盘

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!文章来源地址https://www.toymoban.com/news/detail-784601.html

到了这里,关于【小沐学C++】C++ 实现鼠标键盘钩子HOOK的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# 实现全局鼠标钩子操作以及发送键盘事件

    全局钩子定义 winfrom窗体代码: 效果截图:

    2024年02月05日
    浏览(40)
  • C#使用SnsSharp实现鼠标键盘钩子,实现全局按键响应

    CSDN下载地址:https://download.csdn.net/download/sns1991sns/88041637 gitee下载地址:https://gitee.com/linsns/snssharp 一、键盘事件,使用 SnsKeyboardHook 按键事件共有3个:         KeyDown (按键按下)                 KeyUp (按键松开)                  KeyPress (按键按下并松开) 以

    2024年02月14日
    浏览(41)
  • 【小沐学C++】C++ 捕获程序异常奔溃minidump

    并不是所有的bug都可以在发布前找到,也就是说并不是所有的抛出异常的bug都可以在发布前找到。幸运的是,微软在 Platform SDK 中包含了一个功能,可以帮助开发人员收集用户发现的异常信息。MiniDumpWriteDump函数将必要的故障转储信息写入文件,而不节省整个进程空间。此故障

    2024年02月06日
    浏览(62)
  • winform C#键盘钩子(Hook)拦截器,屏蔽键盘深入解析

    钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。  钩子实际上是一个

    2024年02月02日
    浏览(39)
  • 【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)

    官网地址: https://cmake.org CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。 (1)官网下载地址

    2024年02月13日
    浏览(34)
  • 【小沐学Python】Python实现语音识别(SpeechRecognition)

    https://pypi.org/project/SpeechRecognition/ https://github.com/Uberi/speech_recognition SpeechRecognition用于执行语音识别的库,支持多个引擎和 API,在线和离线。 Speech recognition engine/API 支持如下接口: 以上几个中只有 recognition_sphinx()可与CMU Sphinx 引擎脱机工作, 其他六个都需要连接互联网。另

    2024年02月04日
    浏览(60)
  • 【小沐学Python】Python实现语音识别(Whisper)

    https://github.com/openai/whisper Whisper 是一种通用的语音识别模型。它是在包含各种音频的大型数据集上训练的,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别。 Open AI在2022年9月21日开源了号称其英文语音辨识能力已达到人类水准的Whisper神经网络,且它亦支

    2024年02月04日
    浏览(153)
  • 【小沐学C++】C++ MFC中嵌入web网页控件(WebBrowser、WebView2、CEF3)

    WebBrowser控件最常见的用途之一是向应用程序添加 Internet 浏览功能。使用 IWebBrowser2 接口,可以浏览到本地文件系统、网络或万维网上的任何位置。可以使用IWebBrowser2::Navigate 方法告知控件要浏览到哪个位置。第一个参数是包含位置名称的字符串。要浏览到本地文件系统或网络

    2024年02月05日
    浏览(52)
  • 【小沐学Web】Rust实现Web服务器

    https://www.rust-lang.org/ Rust: 一种使每个人都能够构建可靠且高效的软件的语言。 如今,全球有数百家公司在生产环境中使用 Rust,以提供快速、资源少、跨平台的解决方案。您熟悉和喜爱的软件,例如Firefox、 Dropbox和Cloudflare,都使用 Rust。从初创公司到大公司,从嵌入式设备到

    2024年02月07日
    浏览(56)
  • 12.1 使用键盘鼠标监控钩子

    本节将介绍如何使用 Windows API 中的 SetWindowsHookEx 和 RegisterHotKey 函数来实现键盘鼠标的监控。这些函数可以用来设置全局钩子,通过对特定热键挂钩实现监控的效果,两者的区别在于 SetWindowsHookEx 函数可以对所有线程进行监控,包括其他进程中的线程,而 RegisterHotKey 函数只能

    2024年02月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包