2

It is about a MFC-MDI application. I have added a popup window, which should be closed after some duration. Therefore, I create a non-modal dialog

CPopupDlg* pDlg = new CPopupDlg(this);
if (pDlg)
{
    pDlg->Create(IDD, this);
    pDlg->ShowWindow(SW_SHOW);
}

It will be closed by a Timer and destroyed in OnNcDestroy()

void CPopupDlg::OnTimer(UINT_PTR nIDEvent)
{
    if (nIDEvent == m_CounterEventID)
    {
        KillTimer(nIDEvent);
        EndDialog(IDCANCEL);
        DestroyWindow();
    }
}

void CPopupDlg::OnNcDestroy()
{
    __super::OnNcDestroy();
    delete this;
}

My problem are many other (modal) dialogs and message boxes, which may appear, while the CPopupDlg is open. These modal dialogs often does not specify a parent window in my project (CDialogconstructor with pParentWnd=NULL). Hence, the method CDialog::DoModal() use ::GetLastActivePopup() to determine its parent window. The CPopupDlg dialog is chosen as the parent window. As a consequence, DoModal() crashes, when the CPopupDlg window is closed by the timer.

How can I tackle this problem?

  1. Is there a way to exclude the CPopupDlg dialog from the results of ::GetLastAcitvePopup()?

  2. Sometimes I have seen, that non-modal dialogs uses RunModalLoop(). Would this be the solution?

    popupDlg.Create(IDD, this);
    popupDlg.RunModalLoop(MLF_SHOWONIDLE);
    popupDlg.DestroyWindow();
  1. What would happen, if the popup dialog would never be closed and destroyed, but only hidden. Would other modal dialog windows, which are undesired childs of the CPopupDlg wnd, also disappear, if popupDlg.ShowWindow(SW_HIDE) is called?
  • I guess providing the actual parent pointer is not viable? We have similar situations in our app, but we realized the importance of providing the actual desired parent to modal dialogs (vs. always using default NULL). I've even tweaked CDialog derived ctor signatures to take a *reference* to a CWnd instead of a pointer, i.e. REQUIRING a parent to be provided. – franji1 Jul 09 '21 at 14:51
  • @franji1 This is not an option, but thank you. I have found a solution. – Christian Sattlecker Jul 12 '21 at 07:19

1 Answers1

0

My solution is to create the popup window as a separate desktop child window. It is not a child window of the application and will not be chosen by ::GetLastActivePopup().

CPopupDlg* pDlg = new CPopupDlg(this);
if (pDlg)
{
    pDlg->Create(IDD, GetDesktopWindow());
    pDlg->ShowWindow(SW_SHOW);
}