C++ Windows键盘日志记录。WM_CHAR消息在各种应用中的一个特点

C++ Windows键盘日志记录。WM_CHAR消息在各种应用中的一个特点,c++,windows,hook,keyboard-hook,C++,Windows,Hook,Keyboard Hook,你好。有必要监视键入的文本(即没有击键,而是派生字符) 开始时,我使用原始输入法获取按键的虚拟键代码,但由于无法正确地将虚拟键代码转换为字符,因此不得不放弃此决定 MapVirtualKeyboardLayout+LoadKeyboardLayout-未达到预期效果,即如果通过调用LoadKeyboardLayout加载俄文布局,则MapVirtualKeyboardLayout仍然返回拉丁语A,代码为0x41 所以我开始使用hook WM_GETMESSAGE if (nCode < 0

你好。有必要监视键入的文本(即没有击键,而是派生字符)

开始时,我使用原始输入法获取按键的虚拟键代码,但由于无法正确地将虚拟键代码转换为字符,因此不得不放弃此决定

MapVirtualKeyboardLayout+LoadKeyboardLayout-未达到预期效果,即如果通过调用LoadKeyboardLayout加载俄文布局,则MapVirtualKeyboardLayout仍然返回拉丁语A,代码为0x41

所以我开始使用hook WM_GETMESSAGE

if (nCode < 0)
    return CallNextHookEx(NULL, nCode, wParam, lParam);

// WH_GETMESSAGE
if (nCode == HC_ACTION)
{
    PMSG pMsg = (PMSG)lParam;
    if (pMsg != NULL)
    {
        if ((pMsg->message == WM_CHAR)||(pMsg->message == WM_UNICHAR))
        {
            keyEntry.character = pMsg->wParam;
            ipc->SendData(&keyEntry, sizeof(CHARENTRY));
        };
    };
};

return CallNextHookEx(NULL, nCode, wParam, lParam);
if(nCode<0)
返回CallNextHookEx(NULL、nCode、wParam、lParam);
//什么消息
如果(nCode==HC\U动作)
{
PMSG PMSG=(PMSG)LPRAM;
如果(pMsg!=NULL)
{
如果((pMsg->message==WM_CHAR)| |(pMsg->message==WM_UNICHAR))
{
keyEntry.character=pMsg->wParam;
ipc->SendData(&keyEntry,sizeof(CHARENTRY));
};
};
};
返回CallNextHookEx(NULL、nCode、wParam、lParam);
一切正常,包括带有死键的角色

但当我尝试在visual studio的编辑器中键入文本时,出现了以下问题:

  • 按下一个键,会出现两条相同的消息WM_CHAR
  • 对于西里尔文字符,WM_CHAR->wParam的值与键入的拉丁语字符不匹配-好的
如何将虚拟密钥代码转换为字符,考虑到文本输入过程的输入语言+能够招募复合字符(例如:字符)。或者告诉我如何用钩子解决版本中的问题


(提前感谢)

当用户键入一个键时,键盘会生成两个扫描代码-一个是当用户按下键时,另一个是当用户释放键时

资料来源:关于键盘输入-

如果应用程序编译为Unicode as,则WM_CHAR将仅为UTF-16 字符编码(即MBCS和UNICODE之间的差异)。如果 您的应用程序是用MBCS(多字节字符集)构建的,然后 系统将使用当前系统代码页转换Unicode 字符到“Ansi”(引号中)并发送该字符

因此,请检查应用程序使用的字符编码的构建设置 配置为

来源:Unicode和多字节字符集(MBCS)支持: