如何使用 VC++ 检测是不是已按下某个键

Posted

技术标签:

【中文标题】如何使用 VC++ 检测是不是已按下某个键【英文标题】:How to detect if a key has been pressed using VC++如何使用 VC++ 检测是否已按下某个键 【发布时间】:2016-09-23 03:59:05 【问题描述】:

所以我正在尝试制作一个键盘记录器,因此显然我需要获取输入的最后一个字符才能执行此操作。到目前为止,我一直在尝试使用 SetWindowsHookEx() 但这没有用,我制作了回调函数,任何人都可以帮助我解决这个问题吗?任何帮助表示赞赏

【问题讨论】:

***.com/questions/6897058/… 那根本没有帮助我 【参考方案1】:

您在使用 SetWindowsHookEx 时走在了正确的轨道上。您可以使用 WH_GETMESSAGE、WH_MSGFILTER、WH_KEYBOARD 或 WH_KEYBOARD_LL 中的任何一种,具体取决于哪一种适合您的需要。只要有 WM_KEYDOWN 或 WM_KEYUP 消息发送到挂钩窗口,WH_KEYBOARD 挂钩就会调用您的回调函数。 WH_KEYBOARD_LL 挂钩将在异步键状态更改之前调用您的回调。你可以看看这里: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx 和 https://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx

您需要创建一个系统范围的挂钩,这就是您需要将回调函数实现到 dll 中的原因。在 dll 中,您可以拥有以下内容:

#pragma data_seg (".HookSection")
HHOOK hHook = NULL; 
#pragma data_seg ()
#pragma comment(linker,"/SECTION:.HookSection,RWS")

HINSTANCE hDLL = NULL;

InstallHook() 

    hHook = SetWindowsHookEx(WH_KEYBOARD, HookProc, hDLL, 0);


UninstallHook()

    UnhookWindowsHookEx( hHook );

注意 hHook 是如何被定义为进程之间的共享变量的。 hDll 是您在 DllMain 函数中收到的 dll hInstance。

WH_KEYBOARD 钩子的回调函数可以定义如下:

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
  
if (nCode < 0)  // do not process message 
    return CallNextHookEx(hHook, nCode, 
        wParam, lParam); 

// The wParam is the Virtual Key code of the button being pressed or released.
// You can use it for your logging purposes
// In order to determine if the key was pressed or released you need to examine the lParam bits as described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644984(v=vs.85).aspx
// If you need to check the state of Shift, Alt, Ctrl then you need to use GetAsyncKeyState function


return CallNextHookEx(hHook, nCode, wParam, lParam); 
 

下一步是创建一个 exe(可以是控制台应用程序)。当您需要开始/停止日志记录时,它将调用 InstallHook 和 UninstallHook 函数。

我给了你一个 WH_KEYBOARD 的例子,但是你也可以尝试使用 WH_GETMESSAGE 或 WH_MSGFILTER 钩子。在 WH_GETMESSAGE 的情况下,回调应该这样定义:

LRESULT CALLBACK GetMsgProc(_In_ int    code, _In_ WPARAM wParam, _In_ LPARAM lParam)

if (nCode < 0) // do not process message 
    return CallNextHookEx(hHook, nCode, wParam, lParam); 

switch (nCode) 
 
    case HC_ACTION: 
        // You can examine the lParam by casting it to PMSG, like this:
        PMSG p = (PMSG)lParam;
        // If p->message is WM_KEYDOWN
        // the virtual keycode will be written in p->wParam
        // If you need to check the state of Shift, Alt, Ctrl then you need to use GetAsyncKeyState function

        break; 

    case PM_NOREMOVE:
        break; 

    default:
        break; 
 


// 
return CallNextHookEx(hHook, nCode, wParam, lParam); 


【讨论】:

以上是关于如何使用 VC++ 检测是不是已按下某个键的主要内容,如果未能解决你的问题,请参考以下文章

如何检测是不是在 HTML 页面上的任意位置按下了某个键?

如何使用 Linux 系统调用检测何时按下某个键

C语言 如何在一段时间内检测键盘是不是按下

如何检测 C++ 中是不是按下了任何键?

如何使用 Ruby 检测在 Windows 平台上是不是按下了 SHIFT 或 ALT 键?

如何检测 Actionscript 3 中是不是按下了删除键?