1

我正在编写一个小游戏,我将lpfnWndProc设置为DefWindowProc ,然后,我以这种方式制作了一个循环:

    MSG lastMessage;
 while (true)
 {
  if (PeekMessage(
   &lastMessage, 
   this->getWindow(), 
   0, 0, 
   PM_REMOVE))
  {
   TranslateMessage(&lastMessage);
   DispatchMessage(&lastMessage);
  }
 }

那么在这种情况下我该如何处理关闭窗口事件呢?

4

2 回答 2

2

首先,这不是您编写消息循环的方式:等待消息时将占用 100% CPU,并且不会从队列中删除其他窗口的消息。它也永远不会终止。有关消息循环的示例,请参见此处。

关于关闭窗口:DefWindowProcWM_CLOSE自动处理并销毁您的窗口。如果您希望您的应用程序在窗口关闭时终止,您需要处理并从中WM_DESTROY调用。PostQuitMessage(0)这意味着您将需要自己的窗口过程而不是DefWindowProc.

于 2009-11-01T10:34:47.247 回答
0
  1. 如果您希望 WindowProc 由一个类处理,您可以执行类似的操作

    class CWindow 
    {
      static LRESULT WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
      { 
        CWindow* self;
        if(uMsg == WM_CREATE)
        {
          self = (CWindow*)((LPCREATESTRUCT)lParam)->lplpCreateParams;
        }
        else
          self = GetWindowLong(hwnd,GWL_USERDATA);
        if(self){
          switch(uMsg){
          case WM_CREATE:
            return self->OnCreate(hwnd,(LPCREATESTRUCT)lParam);
          case WM_CLOSE:
            self->OnClose();
            return 0;
          // etc.
          }
        }
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
      }
      int OnCreate(HWND hwnd,LPCREATESTRUCT lpcs)
      {
        m_hwnd = hwnd;
        SetWindowLong(m_hwnd,GWL_USERDATA,this);
        return 0;
      }
    }
    

当然要确保将“this”作为最后一个参数传递给 CreateWindow(Ex)。

接下来,在您的消息循环中,您必须检查 WM_QUIT 消息并将其用作退出循环的提示。此外,永远不要对 hwnd 进行过滤,因为这会阻止您的应用程序循环为线程上的其他窗口分派消息。许多 Windows 库在线程上创建消息窗口以促进进程间(和线程)通信。如果您不处理所有 Windows 消息,那么 (a) 您的游戏最终会耗尽内存,并且 (b) 整个系统可能会开始变得有趣,因为您的应用程序会使 IPC 消息死锁或超时。

此外,WM_CLOSE(通常)是通过 SendMessage 发送的,而不是 PostMessage。发送的消息直接传递到窗口进程,不能在应用程序循环中过滤。

于 2009-11-01T21:38:04.130 回答