【问题标题】:Keyboard Hook... not getting Lower or Upper case characters键盘挂钩...没有得到小写或大写字符
【发布时间】:2008-12-04 21:35:29
【问题描述】:

下面的函数正在记录“0”、“z”和“1” ok...但它没有捕获“Z”(shift-z)...任何帮助将不胜感激...

__declspec(dllexport)
LRESULT CALLBACK HookProc (UINT nCode, WPARAM wParam, LPARAM lParam)
{
    if ((nCode == HC_ACTION) && (wParam == WM_KEYUP))
    {
        // This Struct gets infos on typed key
        KBDLLHOOKSTRUCT hookstruct = *((KBDLLHOOKSTRUCT*)lParam);

        // Bytes written counter for WriteFile()
        DWORD Counter;

        wchar_t Logger[1];

        switch (hookstruct.vkCode)
        {
        case 060: Logger[0] = L'0'; break;
        case 061: Logger[0] = L'1'; break;
        case 90: Logger[0] = L'z'; break;
        case 116: Logger[0] = L'Z'; break;
        }

        // Opening of a logfile. Creating it if it does not exists
        HANDLE  hFile = CreateFile(L"C:\\logfile.txt", GENERIC_WRITE,
            FILE_SHARE_READ, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

        // put the file pointer to the end
        SetFilePointer(hFile,NULL,NULL,FILE_END);

        // Write the hFile typed in logfile
        WriteFile(hFile,&Logger,sizeof(Logger),&Counter,NULL);

        //WriteFile(hFile,&hookstruct.vkCode,sizeof(hookstruct.vkCode),&Counter,NULL);
        // Close the file
        CloseHandle(hFile);
    }
}

【问题讨论】:

    标签: c++ winapi keyboard-hook hook


    【解决方案1】:

    键盘不发送字符。它发送。无论您是在键入 z 还是 Z,您仍然在按同一个键,并且该键两次具有相同的 VK 代码。

    您还应该在按下或释放 Shift 键时收到通知。您可以使用这些通知将击键转换为字符。大写锁定状态也与此相关。您可能还担心死键。

    您可以检查是否按下了 Shift 键。 GetAsyncKeyState 将告诉您密钥的状态现在GetKeyState 将告诉您从消息队列中删除的最后一条消息时密钥的状态。

    【讨论】:

    • 晚了四年,但感谢您的回答。帮了我:)
    • 我想在这个答案中补充一点,如果您要在多语言环境中工作,您可能会遇到更严重的问题,因为您的 kbd 事件的进程和进程源可能有不同的当前语言。例如。你的进程激活了 Eng,如果用户在另一个进程中切换到 Rus 并按“Й” - 你可能会得到“Q”,因为它是键盘上的同一个物理键。另请参阅此答案:stackoverflow.com/questions/10718009/…
    • @IvanDanilov:您将 扫描码虚拟键码 混淆了。 ЙQ 可能具有相同的扫描码,因为它们共享键盘上的相同物理键。这并不意味着相同的虚拟键代码。
    • @IInspectable 据我了解,扫描码依赖于硬件,虚拟键码是操作系统抽象来统一硬件处理。两者都不取决于当前语言,即在同一个键盘上按 QЙ 将给出相同的对 (vk, sc)。你有一些链接可以进一步阅读吗?
    【解决方案2】:

    Z 没有虚拟键码。 试试这样的:

                case 90:
                     if(GetKeyState(VK_LSHIFT|VK_RSHIFT)
                         Logger[0] = L'Z'; break;
                     else
                         Logger[0] = L'z'; break;
    

    【讨论】:

    • 你想要修饰符的同步键状态。如果您以这种质量水平编写键盘记录器,我并不十分担心安全威胁。
    • 您可能会建议进行编辑,而不会溢出您的偏执茶;不,我当然不会编写用户空间键盘记录器。
    • 我建议完全删除答案。它没有添加任何有用的东西,并且完全错过了这个问题。你正在分发枪支和创可贴。上面的Rob Kennedy 正中。键盘与字符或字形无关。虽然您提供了一个(制作不佳的)解决方案来区分大写和小写拉丁字符,但它对每个代理输入都失败了(例如é)。死键只是另一个失败的例子。我否决了这个答案,因为它具有欺骗性。
    • 当没有其他答案时,我也完全回答了问题。我是否应该每周重新审视我的所有答案并针对我不再使用的系统进行验证?请引用我说键盘是关于符文、字符、字形的地方......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    相关资源
    最近更新 更多