QT全局钩子监控鼠标和键盘

本文详细介绍了如何利用全局钩子DLL来捕获窗口失去焦点时的鼠标和键盘消息,并通过QT窗口进行信息接收。首先创建包含全局钩子的DLL,接着设置鼠标和键盘钩子,当检测到鼠标点击右键或键盘按键时,通过PostMessage发送消息到QT主程序。在QT应用中,通过安装QAbstractNativeEventFilter来接收并处理这些消息。最后展示了如何在QT程序中安装和卸载DLL钩子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、前言

      想要在窗口失去焦点的情况下获取鼠标和键盘消息,需要用到钩子技术,API函数为:SetWindowsHookEx()。而且必须是全局钩子,全局钩子需要使用DLL注入。即首先生成一个带有全局钩子的DLL,DLL获取鼠标位置和键盘按键消息再发送给QT主程序。

2、全局钩子DLL

// myHookMouseAndKeybord.cpp : 定义 DLL 应用程序的导出函数。
//
#include <windows.h>
#include "stdafx.h"

//HINSTANCE g_hInstance;
HHOOK g_hMouseHook;
HHOOK g_hKeybordHook;
HWND g_hMainWND;
//安装鼠标钩子(要生成lib文件需要加上extern "C" __declspec(dllexport) )
extern "C" __declspec(dllexport) BOOL InstallMouseHook(HWND hWnd);
//卸载鼠标钩子
extern "C" __declspec(dllexport) BOOL UnInstallMouseHook();
//安装键盘钩子
extern "C" __declspec(dllexport) BOOL InstallKeybordHook();
//卸载键盘钩子
extern "C" __declspec(dllexport) BOOL UnInstallKeybordHook();

//鼠标钩子处理函数声明
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
//键盘钩子处理函数声明
LRESULT CALLBACK keyBordProc(int nCode, WPARAM wParam, LPARAM lParam);

//安装鼠标钩子
BOOL InstallMouseHook(HWND hWnd)
{
	g_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(L"myHookMouseAndKeybord"), 0);
	g_hMainWND = hWnd;
	if (g_hMouseHook != NULL)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

//卸载鼠标钩子
BOOL UnInstallMouseHook()
{
	return UnhookWindowsHookEx(g_hMouseHook);
}


//安装键盘钩子
BOOL InstallKeybordHook()
{
	g_hKeybordHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyBordProc, GetModuleHandle(L"myHookMouseAndKeybord"), 0);
	if (g_hKeybordHook != NULL)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

//卸载键盘钩子
BOOL UnInstallKeybordHook()
{
	return UnhookWindowsHookEx(g_hKeybordHook);
}

//鼠标钩子处理函数
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (wParam == WM_RBUTTONDOWN) //当鼠标点击右键时发送信息给QT主窗口
	{

		MOUSEHOOKSTRUCT *mhookstruct;   //鼠标HOOK结构体
		mhookstruct = (MOUSEHOOKSTRUCT*)lParam;
		POINT pt = mhookstruct->pt;  //将当前鼠标坐标点的x,y坐标作为参数向主程序窗口发送消息
		PostMessage(g_hMainWND, WM_RBUTTONDOWN, MK_CONTROL, MAKELPARAM(pt.x, pt.y));
	}
	return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

//键盘钩子处理函数
LRESULT CALLBACK keyBordProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (wParam == WM_KEYDOWN)
	{
		tagKBDLLHOOKSTRUCT *keyhookstruct;   //键盘HOOK结构体
		keyhookstruct = (tagKBDLLHOOKSTRUCT*)lParam;
		PostMessage(g_hMainWND, WM_KEYDOWN, keyhookstruct->vkCode, keyhookstruct->scanCode);
	}

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

3、发送鼠标键盘消息

      上面代码已经贴出来了,就在钩子处理函数中。鼠标发送的是位置信息,键盘发送的是键码

4、QT窗口接收信息

QT要接收消息,需要在QApplication中安装QAbstractNativeEventFilter,

#include "LOLdesk.h"
#include <QtWidgets/QApplication>
#include <QAbstractNativeEventFilter>
#include <QDebug>

class MyAppNativeEventFilter : public QAbstractNativeEventFilter
{
	virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *longMsg) override
	{
		if (eventType == "windows_generic_MSG" || eventType == "windows_dispatcher_MSG")
		{
			MSG* pMsg = reinterpret_cast<MSG*>(message);
			if (pMsg->message == WM_RBUTTONDOWN)
			{
				POINT pt = pMsg->pt;
				qDebug() << "x="<<pt.x << "y=" << pt.y;
			}
			if (pMsg->message == WM_KEYDOWN)
			{
				qDebug() << pMsg->wParam;
			}
		}
		return false; // 注意返回值
	};

};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    LOLdesk w;
	MyAppNativeEventFilter filter;
	a.installNativeEventFilter(&filter); //在APP上安装EventFilter
    w.show();
    return a.exec();
}

5、调用DLL钩子

//链接lib文件
#pragma  comment(lib, "myHookMouseAndKeybord.lib") 
//安装鼠标钩子声明
extern "C" __declspec(dllimport) BOOL InstallMouseHook(HWND hWnd);
//卸载鼠标钩子声明
extern "C" __declspec(dllimport) BOOL UnInstallMouseHook();
//安装键盘钩子
extern "C" __declspec(dllimport) BOOL InstallKeybordHook();
//卸载键盘钩子
extern "C" __declspec(dllimport) BOOL UnInstallKeybordHook();

//安装钩子
BOOL LOLdesk::installHook()
{
	HMODULE hDll = NULL;
	HWND m_hWnd = (HWND)this->winId();
	BOOL hookMouseState = InstallMouseHook(m_hWnd);
	BOOL hookKeybordState = InstallKeybordHook();
	if (!hookMouseState && !hookKeybordState)
	{
		qDebug() << "hook failed!";
	}
	else
	{
		qDebug() << "hook success!";
	}
	return 0;
}

//卸载钩子
BOOL LOLdesk::uninstallHook()
{
	BOOL hookMouseState = UnInstallMouseHook();
	BOOL hookKeybordState = UnInstallKeybordHook();
	if (!hookMouseState && !hookKeybordState)
	{
		qDebug() << "unhook failed!";
	}
	else
	{
		qDebug() << "unhook success!";
	}
	return 0;
}
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值