我写了这个动态库来安装一个钩子,但是为了使钩子正常运行,程序要求它处于while循环中。有没有一种方法可以在不使用while循环的情况下安装该钩子,并且可以将其卸载,类似于下面显示的称为“ unlock”的方法?该库稍后将在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);
}
}
}
答案 0 :(得分:1)
SetWindowsHookEx()
提供的许多钩子都要求安装线程具有消息循环,因为它们的钩子回调在调用时被委托回该线程,并且需要同步,消息循环可以处理。 / p>
阅读SetWindowsHookEx()
文档,它专门告诉您哪些挂钩需要消息循环。
提示-WH_KEYBOARD_LL
是其中之一:
此挂钩在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。 因此,安装挂钩的线程必须具有消息循环。
由于您正在编写库,所以不能保证调用的应用程序具有消息循环。因此,您应该使您的库运行自己的具有消息循环的工作线程。该线程可以(取消)安装钩子并处理回调。让lock()
创建该线程,然后unlock()
停止它。