I have a class named Dialog and AboutDialog. Dialog calls CreateDialogParam, has HandleMessage (DLGPROC, basically) in it, etc, AboutDialog inherits from Dialog. Now, somewhere in my program I'm creating a new Dialog class.
LRESULT SystemTrayWindow::HandleTrayMessage(LPARAM lParam)
{
...
case WM_LBUTTONDBLCLK:
AboutDialog *About;
About = new AboutDialog(m_hInstance, ABOUTDIALOG);
About->MakeDialog();
return 0;
...
Now, obviously the about dialog will be closed, which'll make the program do the following in it's HandleMessage:
BOOL AboutDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
...
case WM_CLOSE:
DestroyWindow(m_hWnd);
return FALSE;
...
}
Now how can I delete that AboutDialog that I created? Obviously I could do delete About; but how do I know when WM_DESTROY was sent so it's ok to delete it? In my message loop, I tried catching WM_DESTROY but that doesn't work at all because the message is never WM_DESTROY:
BOOL WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
...
while(!StopLoop) {
if(MsgWaitForMultipleObjectsEx(0, 0, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE) == WAIT_OBJECT_0) {
while(PeekMessage(&Msg, 0, 0, 0, PM_REMOVE)) {
if(Msg.message == WM_QUIT)
StopLoop = true;
if(Msg.message == WM_DESTROY) {
Dialog *ToDelete = reinterpret_cast<Dialog*>(GetWindowLongPtr(Msg.hwnd, GWLP_USERDATA));
delete ToDelete;
}
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
}
...
BOOL AboutDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_DESTROY:
PostMessage(NULL, WM_DESTROY, 0, 0);
return FALSE;
...
In ProfileLauncher.cpp:
...
while(!StopLoop) {
if(MsgWaitForMultipleObjectsEx(0, 0, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE) == WAIT_OBJECT_0) {
while(PeekMessage(&Msg, 0, 0, 0, PM_REMOVE)) {
if(Msg.message == WM_QUIT)
StopLoop = true;
if(Msg.message == WM_DESTROY) {
Dialog *ToDelete = reinterpret_cast<Dialog*>(GetWindowLongPtr(Msg.hwnd, GWLP_USERDATA));
delete ToDelete;
}
...
Special thanks: MyndFyre
Note that I advocated that the call be:
PostMessage(NULL, WM_DESTROY, m_hWnd, 0);
...and the processing of the message be...
if (Msg.message == WM_DESTROY)
{
if ((HWND)Msg.wParam == m_aboutDlgHwnd)
{
delete m_aboutDialog;
m_aboutDlgHwnd = NULL;
}
}
Another, more efficient (probably), less messy, alternative:
case WM_NCDESTROY:
lres = DefWindowProc(m_hwnd, uMsg, wParam, lParam);
SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
delete this;
return lres;