Window钩子,qt调用实测,跨DLL回调

相关知识:window钩子注册

1、项目结构:

Window钩子,qt调用实测,跨DLL回调_第1张图片

2、MouseKeyboardHook.h MouseKeyboardHook.cpp

#ifndef MOUSEKEYBOARDHOOK_H
#define MOUSEKEYBOARDHOOK_H


#ifdef HOOK_EXPORTS
#define MOUSEKEYBOARDHOOK_API __declspec(dllexport)  
#else
#define MOUSEKEYBOARDHOOK_API __declspec(dllimport)  
#endif


#include 

extern "C" MOUSEKEYBOARDHOOK_API int SetHook(HWND main);
extern "C" MOUSEKEYBOARDHOOK_API int UnSetHook(void);
extern "C" MOUSEKEYBOARDHOOK_API void pro(void(*f1) (WPARAM wParam, LPARAM lParam));

#endif //MOUSEKEYBOARDHOOK
#include "MouseKeyboardHook.h"  
HMODULE hDll = ::GetModuleHandle(LPCTSTR("HOOK.dll"));
typedef void(*f1) (WPARAM wParam, LPARAM lParam);
void(*pFunc) (WPARAM wParam, LPARAM lParam);

//共享内存变量
#pragma data_seg("MouseKeyboardHook")  
HHOOK g_hMouseHook = NULL;
HHOOK g_hKeyboardHook = NULL;
HWND g_lhDisplayWnd = NULL;
#pragma data_seg()  

int UnSetHook(void);
int SetHook(HWND main);

//钩子函数的格式 LRESULT CALLBACK 函数名(int 钩子类型, WPARAM wParam, LPARAM lParam);
//处理鼠标的钩子函数  
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam);
//处理键盘的钩子函数
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);

//这个是获取DLL的内存地址,可以重复使用,当做模版  
HMODULE WINAPI ModuleFromAddress(PVOID pv);

HWND m_hCursorWnd;
void CreateCursonIcon();
long __stdcall WindowProcedure(HWND hwnd, unsigned int msg, WPARAM wp, LPARAM lp);

LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (wParam == WM_MOUSEMOVE) //只处理WM_MOUSEMOVE消息
	{

		MOUSEHOOKSTRUCT *mhookstruct; //鼠标HOOK结构体

		mhookstruct = (MOUSEHOOKSTRUCT*)lParam;

		POINT pt = mhookstruct->pt;

		//将当前鼠标坐标点的x,y坐标作为参数向主程序窗口发送消息

		PostMessage(g_lhDisplayWnd, WM_MOUSEMOVE, MK_CONTROL, MAKELPARAM(pt.x, pt.y));
		//SetWindowPos(m_hCursorWnd, 0, pt.x - 20, pt.y - 20, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
	}
	pFunc(wParam, lParam);
	//PostMessage(g_lhDisplayWnd, WH_MOUSE_LL, wParam, lParam);
	
	return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}

LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	pFunc(wParam, lParam);
	//PostMessage(g_lhDisplayWnd, WM_KEYDOWN, wParam, lParam);
	return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}

//安装钩子函数  
MOUSEKEYBOARDHOOK_API int SetHook(HWND main)
{
	g_lhDisplayWnd = main;
	g_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, hDll, 0);
	g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hDll, 0);

	//CreateCursonIcon();
	return g_hMouseHook && g_hKeyboardHook ? 1 : 0;
}

MOUSEKEYBOARDHOOK_API int UnSetHook(void)
{
	g_lhDisplayWnd = NULL;
	BOOL b1 = UnhookWindowsHookEx(g_hMouseHook);
	BOOL b2 = UnhookWindowsHookEx(g_hKeyboardHook);
	//::DestroyWindow(m_hCursorWnd);
	return b1 && b2 ? 1 : 0;		
}

HMODULE WINAPI ModuleFromAddress(PVOID pv)
{
	MEMORY_BASIC_INFORMATION mbi;
	if (VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) {
		return (HMODULE)mbi.AllocationBase;
	} else {
		return NULL;
	}
}

void pro(void(*f1) (WPARAM wParam, LPARAM lParam))
{
	pFunc = f1;
}

void CreateCursonIcon()
{

	WNDCLASSEX wndclass = { sizeof(WNDCLASSEX), CS_DBLCLKS, (WNDPROC)WindowProcedure,
		0, 0, GetModuleHandle(0), LoadIcon(0, IDI_APPLICATION),
		LoadCursor(0, IDC_ARROW), CreateSolidBrush(RGB(0, 255, 0)),
		0, L"cursor", LoadIcon(0, IDI_APPLICATION) };

	if (!::GetClassInfoEx(GetModuleHandle(0), L"cursor", &wndclass))
		RegisterClassEx(&wndclass);

	POINT p;
	GetCursorPos(&p);
	m_hCursorWnd = CreateWindowEx(WS_EX_TOOLWINDOW, L"cursor", L" 是", WS_POPUP | WS_VISIBLE,
		p.x - 20, p.y - 20, 40, 40,
		NULL, NULL, GetModuleHandle(0), NULL);

	//starthook(m_windowHandl);

	RECT rect;
	GetClientRect(m_hCursorWnd, &rect);
	HRGN hRgn = CreateEllipticRgn(rect.left, rect.top, rect.right, rect.bottom);
	SetWindowRgn(m_hCursorWnd, hRgn, TRUE);


	SetWindowLong(m_hCursorWnd, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOACTIVATE);
	SetLayeredWindowAttributes(m_hCursorWnd, RGB(255, 255, 255), 155, LWA_ALPHA);

	SetWindowPos(m_hCursorWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

long __stdcall WindowProcedure(HWND hwnd, unsigned int msg, WPARAM wp, LPARAM lp)
{
	
	return DefWindowProc(hwnd, msg, wp, lp);
}

3、main.cpp  widget.h widget.cpp

#include "widget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}
#ifndef WIDGET_H
#define WIDGET_H

#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    bool setGlobalHook(bool b);
signals:
    void mousekeyboardAction();

protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
//#include "test.hpp"

#include 

#ifdef Q_OS_WIN
#include 
#include 

typedef int(*FUN1)(HWND);
typedef int(*FUN2)();
typedef void(*fq)(void(*f1)(WPARAM wParam, LPARAM lParam));
void(*f) (void(*f1)(WPARAM wParam, LPARAM lParam));
#endif

#include 

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    qDebug() << (setGlobalHook(true) ? "set ok" : "set failed");

    connect(this, &Widget::mousekeyboardAction,
            [this](){
        static int i = 0;
        QString debug = QString::number(i++) + "\tmouse_keyboard_action\n";
        qDebug() << debug;
        //ui->textBrowser->insertPlainText(debug);
    });
    connect(ui->textBrowser->verticalScrollBar(), &QScrollBar::rangeChanged,
            [this](int min, int max) {
        ui->textBrowser->verticalScrollBar()->setValue(max);
    });
}

Widget::~Widget()
{
    qDebug() << (setGlobalHook(false) ? "unset ok" : "unset failed");

    delete ui;
}

bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
#ifdef Q_OS_WIN
    if (eventType == "windows_generic_MSG") {
        MSG *msg = static_cast(message);
        switch (msg->message) {
            //emit mousekeyboardAction();
		case WM_KEYDOWN:
			qDebug() << "wParam"<< msg->wParam;
			qDebug() << "lParam" << msg->lParam;
            break;
		case WM_SYSKEYDOWN:
			//emit mousekeyboardAction();
			qDebug() << "wParam" << msg->wParam;
			qDebug() << "lParam" << msg->lParam;
			break;
        default:
            break;
        }
    }
#endif
    return false;
}
void fff(WPARAM wParam, LPARAM lParam)
{
	KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *)lParam;
	qDebug() << pkbhs->vkCode;
// 	qDebug()<<"wParam" << wParam;
// 	qDebug() << "lParam" << lParam;
// 	qDebug() << "load ok!Q!!!";
}

bool Widget::setGlobalHook(bool b)
{
#ifdef Q_OS_WIN
    static FUN1 SetHook = NULL;
	static FUN2 UnSetHook = NULL;
    if (b) {
        QLibrary lib("HOOK.dll");
        if (lib.load()) {
            qDebug() << "load ok!";
			f = (fq)lib.resolve("pro");
            SetHook = (FUN1)lib.resolve("SetHook");
            UnSetHook = (FUN2)lib.resolve("UnSetHook");
			f(fff);
            if (SetHook) {
                qDebug() << "load SetHook ok!";
                SetHook((HWND)this->winId());
            }
            if (UnSetHook) {
                qDebug() << "load UnSetHook ok!";
            }
			if (f)
			{

			}
            return true;
        } else {
            qDebug() << "load error!";
            return false;
        }
    } else {
        if (UnSetHook)
            return UnSetHook();
        else
            return false;
    }
#endif
}

 

Demo下载

 

你可能感兴趣的:(Qt)