modeless dialog in wtl
-
I have a CDialogImpl-based class, implementing a modeless dialog. My application can have a number of such dialogs, so I'm using this code to create one:
CMyDialog *pDlg = new CMyDialog;
pDlg->Create(NULL);
pDlg->ShowWindow(SW_SHOW);When user will press the close-button in the upper right corner of my dialog - I must destroy the object and the window, so I'm using DestroyWindow(); in WM_CLOSE handler and delete this; in OnFinalMessage(). The problem is that the program falls with ASSERT(pThis->m_pCurrentMsg == &msg) in atlwin.h, line 2281. Btw, if I close the main application - these dialogs are destroying without any ASSERTs... How can I delete the class after the window have been destroyed? With the best regards, Vitaly.
-
I have a CDialogImpl-based class, implementing a modeless dialog. My application can have a number of such dialogs, so I'm using this code to create one:
CMyDialog *pDlg = new CMyDialog;
pDlg->Create(NULL);
pDlg->ShowWindow(SW_SHOW);When user will press the close-button in the upper right corner of my dialog - I must destroy the object and the window, so I'm using DestroyWindow(); in WM_CLOSE handler and delete this; in OnFinalMessage(). The problem is that the program falls with ASSERT(pThis->m_pCurrentMsg == &msg) in atlwin.h, line 2281. Btw, if I close the main application - these dialogs are destroying without any ASSERTs... How can I delete the class after the window have been destroyed? With the best regards, Vitaly.
Surely if you've called DestroyWindow then that is all you need to do. Have you traced back to see what was called to cause the ASSERT? I'm betting on delete this. Christian #include "std_disclaimer.h" The careful application of terror is also a form of communication. Eagles may soar, but weasels don't get sucked into jet engines.
-
I have a CDialogImpl-based class, implementing a modeless dialog. My application can have a number of such dialogs, so I'm using this code to create one:
CMyDialog *pDlg = new CMyDialog;
pDlg->Create(NULL);
pDlg->ShowWindow(SW_SHOW);When user will press the close-button in the upper right corner of my dialog - I must destroy the object and the window, so I'm using DestroyWindow(); in WM_CLOSE handler and delete this; in OnFinalMessage(). The problem is that the program falls with ASSERT(pThis->m_pCurrentMsg == &msg) in atlwin.h, line 2281. Btw, if I close the main application - these dialogs are destroying without any ASSERTs... How can I delete the class after the window have been destroyed? With the best regards, Vitaly.
The problem is this code near the bottom of that function in atlwin.h
pThis->OnFinalMessage(hWnd);
You can't call delete this from a function that's being called by this. I hope that makes sense. The way I would solve this is to create a WM_USER function which does the delete from the main app such as:
#define WM_USER_DELETE_DIALOG WM_USER+1
// call deleteme from onclose after calling destory
CMyDialog::DeleteMe()
{
// can add info to describe which dialog to delete as a param
// must be post and not send
PostMessage(parent, WM_USER_DELETE_DIALOG , 0, 0);
}CApp::OnDeleteDialog()
{
delete pDlg;
} -
The problem is this code near the bottom of that function in atlwin.h
pThis->OnFinalMessage(hWnd);
You can't call delete this from a function that's being called by this. I hope that makes sense. The way I would solve this is to create a WM_USER function which does the delete from the main app such as:
#define WM_USER_DELETE_DIALOG WM_USER+1
// call deleteme from onclose after calling destory
CMyDialog::DeleteMe()
{
// can add info to describe which dialog to delete as a param
// must be post and not send
PostMessage(parent, WM_USER_DELETE_DIALOG , 0, 0);
}CApp::OnDeleteDialog()
{
delete pDlg;
}That's odd, though. The docs on
CDialogImpl::OnFinalMessage()
say:Called after receiving the last message (typically
WM_NCDESTROY
). Note that if you want to automatically delete your object upon the window destruction, you can calldelete this;
here.--Mike-- http://home.inreach.com/mdunn/ "Make sure that if you are using a blow torch that you don't set anything on fire." -- Chris Maunder
-
That's odd, though. The docs on
CDialogImpl::OnFinalMessage()
say:Called after receiving the last message (typically
WM_NCDESTROY
). Note that if you want to automatically delete your object upon the window destruction, you can calldelete this;
here.--Mike-- http://home.inreach.com/mdunn/ "Make sure that if you are using a blow torch that you don't set anything on fire." -- Chris Maunder
-
Surely if you've called DestroyWindow then that is all you need to do. Have you traced back to see what was called to cause the ASSERT? I'm betting on delete this. Christian #include "std_disclaimer.h" The careful application of terror is also a form of communication. Eagles may soar, but weasels don't get sucked into jet engines.
-
The problem is this code near the bottom of that function in atlwin.h
pThis->OnFinalMessage(hWnd);
You can't call delete this from a function that's being called by this. I hope that makes sense. The way I would solve this is to create a WM_USER function which does the delete from the main app such as:
#define WM_USER_DELETE_DIALOG WM_USER+1
// call deleteme from onclose after calling destory
CMyDialog::DeleteMe()
{
// can add info to describe which dialog to delete as a param
// must be post and not send
PostMessage(parent, WM_USER_DELETE_DIALOG , 0, 0);
}CApp::OnDeleteDialog()
{
delete pDlg;
}Yes, I've though about this way. The problem is that I will have many windows like this. Different windows, different classes... So I must implement some kind of window manager for them. But I still hope that delete this; will work somewhere :) With the best regards, Vitaly.
-
Yes, I've though about this way. The problem is that I will have many windows like this. Different windows, different classes... So I must implement some kind of window manager for them. But I still hope that delete this; will work somewhere :) With the best regards, Vitaly.
From the WTL newsgroup (sign up! -- http://groups.yahoo.com/group/wtl) From: "Tim Smith" Date: Thu Jan 18, 2001 11:41 am Subject: Re: DestroyWindow and OnFinalMessage ? Here is a basic roadmap of what you need to do. First, inside your dialog box class, you need make a new version of DialogProc. I just copied the DialogProc from ATL. Next, add a flag to your class called m_fDeferDelete. Initialize it to false. Inside your new DialogProc, in the WM_NCDESTROY clause after the call to OnFinalMessage, add the following lines: if (pThis ->m_pCurrentMsg == NULL) delete pThis; else pThis ->m_fDeferDelete = true Then in your new DialogProc, after the call to ProcessWindowMessage, add the code: if (pThis ->m_fDeferDelete && pOldMsg == NULL) { delete pThis; return FALSE; } There might be a better way to do it, but this will work. In my real code, I created a new base class that included an auto delete flag. All my dialogs are based on this class. If the auto delete flag is not set, then the dialog works normally. If it is set, then the class self deletes as expected.