c - 如何同时运行一个钩子和一个计时器?
问题描述
我正在尝试用 C 编写一个宏程序,并且我已经设法使用以下代码获取密钥:
#include <windows.h>
#include <stdio.h>
HHOOK _hook;
KBDLLHOOKSTRUCT kbdStruct;
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
printf("Key %lu pressed.\n", kbdStruct.vkCode);
} else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
printf("Key %lu released.\n", kbdStruct.vkCode);
}
}
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
void main() {
if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0))) {
MessageBox(NULL, "Failed to install hook!", "Error", MB_ICONERROR);
}
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {}
}
我希望程序在按下特定键时在特定时间按下一系列键并具有SendInput()
功能。当WH_KEYBOARD_LL
while 循环设置为无限时,不再调用钩子。对我来说,使用GetMessage(&msg, NULL, 0, 0)
似乎也不干净。
我已经搜索了一个钩子方法来在给定的时间间隔内调用一个函数,但没有成功。
我使用 GNU GCC 编译器。
我几乎没有在计算机上用 C 语言编程的经验,但我确实有用 C 语言为微控制器编程的经验。
编辑:
我已经尝试过使用 SetTimer() 的方法,但它没有被调用。我使用了此页面中的示例:http: //www.equestionanswers.com/vcpp/set-timer.php
#include <windows.h>
#include <stdio.h>
#define TimerID 85
HHOOK _hook;
KBDLLHOOKSTRUCT kbdStruct;
VOID __stdcall MyTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) {
printf("Timer call\n");
}
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
printf("Key %lu pressed.\n", kbdStruct.vkCode);
} else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
printf("Key %lu released.\n", kbdStruct.vkCode);
}
}
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
void main() {
if (!(_hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0))) {
MessageBox(NULL, "Failed to install hook!", "Error", MB_ICONERROR);
}
SetTimer(NULL, TimerID, 1000, MyTimerProc);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {}
}
解决方案
我没有使用过它,但据我SetTimer
所知,它依赖于查找WM_TIMER
消息的 Wndproc 或 Timerproc 回调。不过,“Windows 计时器”总体上相当粗糙,所以我会远离它们。
相反,您应该做的是创建一个完成这项工作的线程。你可以让它在大多数时候有效地睡着WaitForMultipleObjects
,这样你就可以定义一个超时。当它超时时,执行应该循环重复的任务。您还应该创建两个自定义事件(CreateEvent
等),一个从钩子回调发送,通知线程更新(“下次你工作,做工作 x”),另一个告诉威胁优雅地关闭自己(程序结束等)。有了这种设计,您也不必担心重新进入。
推荐阅读
- css - 如何为移动视图自定义 ngx-bootstrap datepicker 的位置?
- r - 在 R 中带来长到宽的数据而不会丢失值
- r - 用 lavaan 估计观测变量的协方差
- python - Numpy - 使用满足条件的数组值
- django - Django Apache2 VirtualEnv - 服务器没有响应
- vue.js - 未在 SFC 中定义的组件不使用 Vue3 Router 显示?
- python - 将数据框绘制为条形图,每列在单独的 y 轴上
- php - PHP - Symfony 的 CSRF 保护
- r - 如何在r中的条件匹配中使用管道?
- reactjs - 没有 css/less 的活动选项卡的 AntD 自定义颜色,