我正在尝试创建一个基于对话框的MFC应用程序,其中需要按顺序显示两个对话框。
这意味着,一旦第一个对话框(模态)被显示和解除(按OK),第二个对话框就需要显示出来。我的要求是第二个对话框应该是无模式的。
但是我观察到的是第二个对话框显示但没有消息处理函数被响应用户消息。我认为消息映射本身不起作用,而被覆盖的函数(如OnInitdialog)被调用。我尝试用模态替换这个无模式对话框,唉,doModal()本身失败了。 这是小代码:
CFirstDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
CSecondDlg *dlgModeLess = new CSecondDlg();
dlgModeLess->Create(CSecondDlg::IDD,NULL);
m_pMainWnd = dlgModeLess;
dlgModeLess->ShowWindow(SW_SHOW);
dlgModeLess->UpdateWindow();
}
以下是第二个对话框的消息映射:
BEGIN_MESSAGE_MAP(CSecondDlg, CDialog)
ON_MESSAGE(TRAY_MESSAGE,OnTrayMessage)
ON_BN_CLICKED(IDOK, &CSecongDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_RADIO1, &CSecondDlg::OnBnClickedRadio1)
END_MESSAGE_MAP()
我认为我在做一些概念错误的事情。请分享您对解决此类情况需要采取的措施的看法。
答案 0 :(得分:1)
正如我在上一篇文章中提到的,第二个对话框没有必要是非模态的。
做这样的事情:
BOOL CMyTestApp::InitInstance()
{
CMyTestDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
COtherDlg Dlg ;
m_pMainWnd = &dlg;
if (Dlg.DoModal() == IDCANCEL)
{
...
}
}
else if (nResponse == IDCANCEL)
{
...
}
return FALSE;
}
答案 1 :(得分:0)
当您创建无模式对话框时,控件将立即返回到您的调用函数,因此您需要在全局范围内声明变量dlgModeLess
并确保您的程序/范围仍然有效,直到对话框饰面
答案 2 :(得分:0)
我已经解决了这个问题,结果证明这很有趣。
似乎Cdialog :: Create()本身不足以创建一个完全可操作的无模式对话框。我们必须为它提供一个win32样式的消息循环。 所以这有效地在程序中产生两个消息循环,一个提供我的MFC框架,以及我从IDOK返回后写的那个。这是修改后的代码。
CSecondDlg *dlgModeLess = new CSecondDlg();
dlgModeLess->Create(CSecondDlg::IDD,NULL);
CTrayIconDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
MSG leftmsg;
PeekMessage(&leftmsg,m_pMainWnd->m_hWnd,0,0,PM_REMOVE);
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, dlgModeLess->m_hWnd, 0, 0)) != 0)
{
if (bRet == -1)
{
// Handle the error and possibly exit
}
else if (!IsWindow(hWnd) || !IsDialogMessage(hWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
这段代码按预期工作,这里需要注意的有趣的是PeekMessage函数,它删除了第一个对话框被解除时插入到线程消息队列中的WM_QUIT消息,因为我们不想在那个时间段完成。我相信这是由MFC框架完成的。