上次提了这个问题,我描述的不清楚,重新描述一下:
我有一个基于对话框的程序,程序起来后点击一个按钮创建一个无模式对话框A
{
m_pDlgModeless = new CModelessDlg();
m_pDlgModeless->Create(IDD_MODALESS, this);
m_pDlgModeless->ShowWindow(SW_SHOW); SetTimer(1, 30000, NULL);
}30秒后销毁该对话框
{
if (m_pDlgModeless != NULL && IsWindow(m_pDlgModeless->m_hWnd))
{
m_pDlgModeless->DestroyWindow();
m_pDlgModeless = NULL;
}
}A上有一个按钮,点击后弹出一个模态对话框B。所以有可能B存在时A被销毁了。
我通过把B对象做成A的成员变量,并重载A的DestroyWindow()函数,在DestroyWindow中这样销毁B窗口
{
if(::IsWindow(m_modalDlg.m_hWnd))
m_modalDlg.EndDialog(IDCANCEL);
}
可是这样也不行。这中情况该如何处理?
我有一个基于对话框的程序,程序起来后点击一个按钮创建一个无模式对话框A
{
m_pDlgModeless = new CModelessDlg();
m_pDlgModeless->Create(IDD_MODALESS, this);
m_pDlgModeless->ShowWindow(SW_SHOW); SetTimer(1, 30000, NULL);
}30秒后销毁该对话框
{
if (m_pDlgModeless != NULL && IsWindow(m_pDlgModeless->m_hWnd))
{
m_pDlgModeless->DestroyWindow();
m_pDlgModeless = NULL;
}
}A上有一个按钮,点击后弹出一个模态对话框B。所以有可能B存在时A被销毁了。
我通过把B对象做成A的成员变量,并重载A的DestroyWindow()函数,在DestroyWindow中这样销毁B窗口
{
if(::IsWindow(m_modalDlg.m_hWnd))
m_modalDlg.EndDialog(IDCANCEL);
}
可是这样也不行。这中情况该如何处理?
b为a的子窗口
所以不能DestroyWindow(),自然也就不能执行你重载后的操作了。
所以应该先结束子对话框,再调用父对话框的DestroyWindow()//如下
30秒后销毁该对话框
{
if (m_pDlgModeless != NULL && IsWindow(m_pDlgModeless->m_hWnd))
{
if(HWND hwnd=::FindWindow( ,"B对话框title")) //利用findwindow
{
sendmessage(hwnd,WM_CLOSE, , );//利用消息函数
}
m_pdlgmodeless->destroy();
}
}也可以把m_modeDlg声明为全局的。然后直接调用destroywindow();
if(::IsWindow(m_modalDlg.m_hWnd))
m_modalDlg.EndDialog(IDCANCEL);
换成
if (m_modalDlg!= NULL && IsWindow(m_modalDlg->m_hWnd))
{
m_modalDlg->DestroyWindow();
m_modalDlg= NULL;
}把m_modalDlg.DoModal();换成
m_modalDlg= new CModalDlg();
m_modalDlg->Create(IDD_DIALOG1, this);
m_modalDlg->ShowWindow(SW_SHOW);
EnableWindow(false);
GetParent()->EnableWindow(false);
m_modalDlg->EnableWindow(true);在我这,代码是测试通过的,可以的,你试试看
if (m_modalDlg!= NULL && IsWindow(m_modalDlg->m_hWnd))
{
m_modalDlg->DestroyWindow();
m_modalDlg= NULL;
EnableWindow(true);
}
B窗口该成非模态的是可以,但是我程序里B只能是模态的。
如果我在A上弹出一个MessageBox就没有问题,我想要的就是类似这样的窗口。
----------------------------------
m_modalDlg= new CModalDlg();
m_modalDlg->Create(IDD_DIALOG1, this);
m_modalDlg->ShowWindow(SW_SHOW);
EnableWindow(false);
GetParent()->EnableWindow(false);
m_modalDlg->EnableWindow(true);
这段代码就是产生模态的B窗口阿vc的DoModal的实现代码就是这样的,因此这产生的对话框和DoModal产生的一样
你试试看吧
GetParent()->EnableWindow(false);
m_modalDlg->EnableWindow(true);这三句是实现模态的关键代码
First-chance exception in PopupWindow.exe (MFC42D.DLL): 0xC0000005: Access Violation.
程序停在
if (!ContinueModal())
goto ExitModal;
其二:m_modalDlg不一定非的每次重新创建,因为一个普通的dlg占不了太多的内存,当然如果考虑gdi资源是另外一回事
m_modalDlg.ShowWindow(SW_HIDE);
delete m_modalDlg;
m_modalDlg = NULL;
非模态对话框A,如果需要在运行一段时间自动退出的话,建议由A自己实现,而不是由调用者实现。
譬如你可以在A::OnInitDialog时SetTimer,然后在OnTimer中DestoryWindow.而不是由A的ParentWindow来SetTimer.