Win32 WM_KEYDOWN和WM_KEYUP以及状态越来越"stuck"

Win32 WM_KEYDOWN and WM_KEYUP and statuses getting "stuck"

本文关键字:WM 状态 越来越 stuck KEYUP KEYDOWN Win32      更新时间:2023-10-16

下面是我用来捕获键被按下或未按下的代码,并根据它们的状态更新键的状态。我将雕像保存在值为0,1,2,3的简单数组中。格式为:keyboardmap[256] = {0};

问题是,无论我怎么做,钥匙总是卡在某个点上。它们永远不会被重置回零,就好像WM_KEYUP不能正常启动一样。

  while (true)
  {
    if ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      if (msg.message == WM_QUIT)
      {
        break;
      }
      // Check for keystates and update them.
      if (msg.message == WM_KEYDOWN)
      {
        // Fetch the key state.
        unsigned int keycode = msg.wParam;
        unsigned int cstate = engine.GetKeyState(msg.wParam);
        if (engine.GetKeyState(keycode) == 0)
        {
          engine.SetKeyState(keycode, 1); // Just started pressing.
        }
        else
        {
          engine.SetKeyState(keycode, 2); // Actively pressed down.
        }
      }
      else if (msg.message == WM_KEYUP)
      {
        // Fetch the key state.
        unsigned int keycode = msg.wParam;
        unsigned int cstate = engine.GetKeyState(msg.wParam);
        if ( engine.GetKeyState(keycode) == 2)
        {
          engine.SetKeyState(keycode, 3);
        }
        else
        {
          engine.SetKeyState(keycode, 0);
        }
      }
    }
  }

消息循环不应该是这样的。使用下面的游戏引擎的例子,你需要不断更新游戏/屏幕:

WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
CreateWindow(...);
MSG msg = { 0 };
//while (msg.message != WM_QUIT) <=== removed in edit
while(true)  //<=== **** edit **** 
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if(msg.message == WM_QUIT) //<=== **** edit **** 
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        engine.update();
    }
}

窗口的消息应该在单独的窗口过程中处理:

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_KEYDOWN:
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}