键盘输入和Win32消息循环

Tom*_*ell 4 c++ winapi

如何在Windows消息循环中处理按键和键入事件?我需要能够调用两个函数OnKeyUp(char c);OnKeyDown(char c);.

我从google搜索中找到的当前文献让我对WM_CHAR或WM_KEYUP和WM_KEYDOWN感到困惑,并且通常针对PDA或托管代码,而我使用的是C++.

Joh*_*ler 11

典型的C++消息循环如下所示

MSG msg;
while (GetMessage(&msg, null, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
Run Code Online (Sandbox Code Playgroud)

TranslateMessage的功能是从WM_KEYDOWN消息生成WM_CHAR消息,因此如果要查看WM_CHAR消息,则需要确保将WM_KEYDOWN消息传递给它.如果您不关心WM_CHAR消息,可以跳过它,并执行类似的操作.

extern void OnKeyDown(WPARAM key);
extern void OnKeyUp(WPARAM key);

MSG msg;
while (GetMessage(&msg, null, 0, 0))
{
    if (msg.message == WM_KEYDOWN)
       OnKeyDown (msg.wParam);
    else if (msg.message == WM_KEYUP)
       OnKeyUp(msg.wParam);
    else
    {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,OnKeyDown和OnKeyUp消息被定义为采用WPARAM而不是char.这是因为WM_KEYDOWN和WM_KEYUP的值不限于适合char的值.见WM_KEYDOWN


Tom*_*ell 7

使用char c = MapVirtualKey(param,MAPVK_VK_TO_CHAR);转换虚拟键码为char和处理WM_KEYUP和WM_KEYDOWN及其wParams.

if (PeekMessage (&mssg, hwnd, 0, 0, PM_REMOVE))
{
    switch (mssg.message)
    {
        case WM_QUIT:
            PostQuitMessage (0);
            notdone = false;
            quit = true;
            break;

        case WM_KEYDOWN:
            WPARAM param = mssg.wParam;
            char c = MapVirtualKey (param, MAPVK_VK_TO_CHAR);
            this->p->Input ()->Keyboard ()->Listeners ()->OnKeyDown (c);
            break;

        case WM_KEYUP:
            WPARAM param = mssg.wParam;
            char c = MapVirtualKey (param, MAPVK_VK_TO_CHAR);
            this->p->Input ()->Keyboard ()->Listeners ()->OnKeyUp (c);
            break;
    }
    // dispatch the message
    TranslateMessage (&mssg);
    DispatchMessage (&mssg);
}
Run Code Online (Sandbox Code Playgroud)