Как правильно уничтожить окно? - PullRequest
1 голос
/ 01 ноября 2009

Я программирую небольшую игру, и я установил lpfnWndProc на DefWindowProc и после этого я сделал цикл таким образом:

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

Так как мне обработать событие Close Window в этом случае?

Ответы [ 2 ]

2 голосов
/ 01 ноября 2009

Прежде всего, это не то, как вы пишете цикл сообщений: он будет занимать 100% ЦП при ожидании сообщений и не удалит сообщения для других окон из очереди. Это также никогда не закончится. См. здесь для примера цикла сообщений.

О закрытии окон: DefWindowProc автоматически обработает WM_CLOSE и разрушит ваше окно. Если вы хотите, чтобы ваше приложение закрывалось при закрытии окна, вам нужно обработать WM_DESTROY и вызвать PostQuitMessage(0) из него. Это означает, что вам понадобится ваша оконная процедура вместо DefWindowProc.

0 голосов
/ 02 ноября 2009
  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, то (а) вашей игре в конечном итоге не хватит памяти, и (б) вся система может начать работать смешно, поскольку ваше приложение сделает сообщения IPC тупиковыми или заблокированными.

Кроме того, WM_CLOSE (обычно) отправляется через SendMessage, а не PostMessage. Отправленные сообщения доставляются прямо в процесс окна и не могут быть отфильтрованы в цикле приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...