0

我正在尝试制作一个基于对话框的 MFC 应用程序,其中两个对话框需要按顺序显示。

这意味着,一旦显示并关闭第一个对话框(模式)(按确定),就需要调出第二个对话框。我的要求是第二个对话框应该是无模式的。

但我观察到的是显示了第二个对话框,但没有调用任何消息处理函数来响应用户消息。我认为消息映射本身不起作用,而正在调用覆盖的函数(如 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()

我认为我在做一些概念上错误的事情。请分享您对解决这种情况需要做些什么的想法。

4

3 回答 3

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;
}
于 2013-04-15T09:13:24.423 回答
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 框架完成的。

于 2013-04-13T12:38:24.067 回答
0

当您创建一个无模式对话框时,控制将立即返回到您的调用函数,因此您需要dlgModeLess在全局范围内声明变量并确保您的程序/范围仍然处于活动状态,直到对话框完成

于 2013-04-13T10:52:40.833 回答