首页 > 解决方案 > 如何安装没有环的钩子

问题描述

我写了这个动态库来安装一个钩子,但是为了让钩子正常工作,程序需要它处于一个while循环中。有没有一种方法可以在不使用 while 循环的情况下安装钩子,并且能够类似于下面显示的称为“解锁”的方法来卸载它?该库稍后将在 C# 程序中使用,其目的是阻止来自键盘的任何字母,只让数字通过。谢谢

#pragma once
#include "Header.h"
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <fstream>
#include <ShlObj.h>


#define _WIN32_WINNT 0x050
HHOOK hhkLowLevelKybd = NULL;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    BOOL duckx = FALSE;
    BOOL ducky = FALSE;

    if (nCode == HC_ACTION)
    {
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYUP:
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            if ((duckx = (p->vkCode >= 0x3a)) || (duckx = (p->vkCode <= 0x28 && p->vkCode > 0x08))) {

                break;
            }
            break;
        }
    }
    return(duckx ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam));
}

void lock() {

    HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);

}
void unlock() {

    UnhookWindowsHookEx(hhkLowLevelKybd);

}
myClass::myClass(int x) {
    if (x == 1) {

        lock();
        MSG msg;
        while (!GetMessage(&msg, NULL, NULL, NULL)) {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }
    }
    if (x == 0) {

        unlock();
        MSG msg;
        while (!GetMessage(&msg, NULL, NULL, NULL)) {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }
    }


}

标签: c++dllhook

解决方案


提供的许多钩子SetWindowsHookEx()都要求安装线程有一个消息循环,因为它们的钩子回调在调用时被委托回该线程,这需要同步,消息循环可以处理。

阅读SetWindowsHookEx()文档,它具体告诉您哪些钩子需要消息循环。

提示 -WH_KEYBOARD_LL是其中之一:

这个钩子在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环

由于您正在编写库,因此您不能保证调用应用程序具有消息循环。因此,您应该让您的库运行自己的具有消息循环的工作线程。该线程可以(卸载)安装钩子并处理回调。已lock()创建该线程并unlock()停止它。


推荐阅读