参考:
- wine 8.14
-
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-translatemessage
函数作用:将vtirtual-key message 转换为character message, 并将character message放入消息队列。
BOOL WINAPI NtUserTranslateMessage(const MSG *msg, UINT flags)
{
UINT message;
WCHAR wp[8];
BYTE state[256];
INT len;
......
if(msg->message < WM_KEYFIRST || msg->message > WM_KEYLAST) return FALSE;
if(msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYDOWN) return TRUE;
......
switch(msg->wParam)
{
case VK_PACKET:
message = (msg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
NtUserPostMessage(msg->hwnd, message, HIWORD(msg->lParam), LOWRD(msg->lParam));
return TRUE;
case VK_PROCESSKEY:
return ImmTranslateMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
}
NtUserGetKeyboardState(state);
len = NtUserToUnicodeEx(msg->wParam, HIWORD(msg->lParam), state, wp, ARRAY_SIZE(wp), 0,
NtUserGetKeyboardLayout(0));
if(len == -1)
{
message = msg->message == WM_KEYDOWN ? WN_DEADCHAR : WM_SYSDEADCHAR;
NtUserPostMessage(msg->hwnd, message, wp[0], msg->lParam);
}
else if(len > 0)
{
INT i;
message = msg->message = WM_KEYDOWN ? WN_CHAR : WN_SYSCHAR;
for(i = 0; i<len; i++)
NtUserPostMessage(msg->hwnd, message, wp[i], msg->lParam);
}
return TRUE;
}
此函数的作用是将virtual-key message 转换为character message。 因此只有消息结构中包含virtual-key code的消息才需要此函数进行处理。消息结构中包含virtual-key code 的消息都包含在WM_KEYFIRST 与WM_KEYLAST 这两个宏的范围内。且对于此范围内除WM_KEYDOWN 与WM_SYSKEYDOWN外,其它的消息都默认处理完成(赞不知道这么做的原因)。
对于virtual-key,由两个特殊情况 VK_PACKET和VK_PROCESSKEY不需要进行virtual-key到 character 的转换。
接下来调用NtUserToUnicodeEx进行转换,并将转换完成的 character message 通过函数NtUserPostMessage放入对应窗口的消息队列。