我正在为我的按键记录器工作以获取个人兴趣,并在昨天问了一个与此相关的问题; While loop using a lot of CPU
该程序的问题在于它耗费了太多的CPU使用率,并且人们已经建议将输入设置为基于键的事件。
由于我是Win32 API的新手,我尝试寻找能够告诉我如何创建基于事件而非基于轮询的键盘输入的参考和教程。但问题是我找不到任何可靠的例子或参考文献,因为对于一个完整的新手来说很难理解。
他们中的大多数人都提到基于事件的编程存在于GUI应用程序中,但我希望这个击键记录器应用程序成为控制台应用程序。
我的两个主要问题是:
和
如果需要其他信息,我使用Windows XP下的代码块和GCC编译器。
答案 0 :(得分:7)
密钥记录器应用程序使用Win32 Hooks等机制。具体而言,您需要设置WH_KEYBOARD
挂钩。
有移动高级技术,比如创建自己的键盘驱动程序,但启动挂钩是一个不错的选择。
编辑:为了了解钩子程序的外观,我发布了个人实用程序中的片段。
// ...
thehook = SetWindowsHookEx( WH_KEYBOARD_LL, hook_proc, hwnd, 0 );
// ...
/**
*
* wParam, one of the: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP
lParam: pointer to a KBDLLHOOKSTRUCT structure
(*) "The hook procedure should process a message in less time than the
data entry specified in the LowLevelHooksTimeout value in the following registry key:
HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure does not
return during this interval, the system will pass the message to the next hook."
*
*/
LRESULT CALLBACK
hook_proc( int code, WPARAM wParam, LPARAM lParam )
{
static long ctrl_cnt = 0;
static bool mmode = false;
static DWORD time;
KBDLLHOOKSTRUCT* kbd = (KBDLLHOOKSTRUCT*)lParam;
if ( code < 0
|| (kbd->flags & 0x10) // ignore injected events
) return CallNextHookEx( thehook, code, wParam, lParam );
long ret = 1; // by default I swallow the keys
if ( mmode ) { // macro mode is ON
if ( WM_KEYDOWN == wParam )
PostMessage(mainwnd, WM_MCR_ACCUM, kbd->vkCode, 0);
if ( WM_KEYUP == wParam )
switch (kbd->vkCode) {
case VK_ESCAPE:
mmode = false;
keys.removeall();
PostMessage(mainwnd, WM_MCR_HIDE, 0, 0);
break;
case VK_RETURN:
PostMessage(mainwnd, WM_MCR_EXEC, 0, 0);
break;
case VK_LCONTROL:
mmode = false;
PostMessage(mainwnd, WM_MCR_HIDE, 0, 0);
PostMessage(mainwnd, WM_MCR_EXEC, 0, 0);
break;
}
/* Which non printable keys allow passing? */
switch( kbd->vkCode ) {
case VK_LCONTROL:
case VK_CAPITAL:
case VK_LSHIFT:
case VK_RSHIFT:
ret = CallNextHookEx( thehook, code, wParam, lParam );
}
}
else { // macro mode is OFF
/* Ctrl pressed */
if ( kbd->vkCode == VK_LCONTROL && WM_KEYDOWN == wParam ) {
ctrl_cnt = 1;
time = kbd->time;
}
/* Prevent ctrl combinations to activate macro mode */
if ( kbd->vkCode != VK_LCONTROL )
ctrl_cnt = 0;
/* Ctrl released */
if ( ctrl_cnt == 1 && WM_KEYUP == wParam ) {
if ( kbd->time - time > 40 ) {
mmode = true;
PostMessage(mainwnd, WM_MCR_SHOW, 0, 0);
}
}
ret = CallNextHookEx( thehook, code, wParam, lParam ); // let it pass
}
return ret;
}
答案 1 :(得分:4)