c++ - 如何安装没有环的钩子
问题描述
我写了这个动态库来安装一个钩子,但是为了让钩子正常工作,程序需要它处于一个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);
}
}
}
解决方案
提供的许多钩子SetWindowsHookEx()
都要求安装线程有一个消息循环,因为它们的钩子回调在调用时被委托回该线程,这需要同步,消息循环可以处理。
阅读SetWindowsHookEx()
文档,它具体告诉您哪些钩子需要消息循环。
提示 -WH_KEYBOARD_LL
是其中之一:
这个钩子在安装它的线程的上下文中被调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。
由于您正在编写库,因此您不能保证调用应用程序具有消息循环。因此,您应该让您的库运行自己的具有消息循环的工作线程。该线程可以(卸载)安装钩子并处理回调。已lock()
创建该线程并unlock()
停止它。
推荐阅读
- python - 使用 pyspark.ml 从 LDA 模型中获取推荐的主题数量
- reactjs - 如何在 Gatsby 和 GraphQL 中正确使用 formatString?
- javascript - 如何仅在javascript中单击按钮时才播放视频
- python - 同时具有卷积层和循环层的模型如何表现?
- c# - 在 .net 核心中分离业务域
- sql - PostgreSQL - 正则表达式约束,以便 varchar 仅包含数字
- amazon-web-services - 如何在 MediaLive 和 MediaStore 上实现低延迟
- ruby-on-rails - Shopify RecurringApplicationCharge 的确认 URL 为 nil
- javascript - 在 nodejs 和 typescript 中使用 dotenv 模块
- google-bigquery - 在 BigQuery 中回填预定查询