How do I destroy a Window correctly?
I'm programming a little game, and I set the lpfnWndProc to DefWindowProc and after that, I made a loop in that way:
MSG lastMessage;
while (true)
{
if (PeekMessage(
&lastMessage,
this->getWindow(),
0, 开发者_JS百科0,
PM_REMOVE))
{
TranslateMessage(&lastMessage);
DispatchMessage(&lastMessage);
}
}
So how do I handle the Close Window event in that case?
First of all, this is not how you write a message loop: it will take 100% CPU while waiting for messages, and won't remove messages for other windows from the queue. It will also never terminate. See here for an example of a message loop.
About closing windows: DefWindowProc
will handle WM_CLOSE
automatically and destroy your window. If you want your application to terminate when the window is closed, you need to handle WM_DESTROY
and call PostQuitMessage(0)
from it. This means you will need your own window procedure instead of DefWindowProc
.
If you want WindowProc to be handled by a class, you do something like
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; } }
Making sure of course to pass 'this' as the last parameter to CreateWindow(Ex).
Next, In your message loop, you MUST check for WM_QUIT messages and use that as a cue to exit the loop. Also, NEVER do a filter on hwnd as that will prevent your application loop from dispatching messages for other windows on your thread. And many windows libraries create message windows on threads to facilitate inter process (and thread) comms. If you dont process all windows messages then (a) your game will eventually run out of memory, and (b) the entire system may start to act funny as your application will make IPC messages deadlock, or time out.
Also, WM_CLOSE is (usually) sent via SendMessage, not PostMessage. Sent messages are delivered straight to the window proc and can't be filtered in the app loop.
精彩评论