Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting modal dialogs in MFC

How can I programmatically detect if my MFC application currently is displaying a modal dialog or property sheet? Currently I'm using the following, but I feel that the code also triggers for modeless dialogs.

bool HasModalDialog(const CWnd* pWnd)
{
   const CWnd* pChildWnd = pWnd ? pWnd->GetNextWindow(GW_HWNDPREV) : NULL;
   while (pChildWnd)
   {
      if (pWnd == pChildWnd->GetTopLevelParent() &&
         (pChildWnd->IsKindOf(RUNTIME_CLASS(CDialog)) ||
         pChildWnd->IsKindOf(RUNTIME_CLASS(CPropertySheet))))
      {
         return true;
      }

      pChildWnd = pChildWnd->GetNextWindow(GW_HWNDPREV);
   }

   return false;
}

Usage:

HasModalDialog(AfxGetMainWnd())

Anyone got a alternative way of detecting modal dialogs?

like image 414
dalle Avatar asked Aug 19 '09 10:08

dalle


People also ask

How do I create a modal dialog box in MFC?

To create a modal dialog box, call either of the two public constructors declared in CDialog. Next, call the dialog object's DoModal member function to display the dialog box and manage interaction with it until the user chooses OK or Cancel. This management by DoModal is what makes the dialog box modal.

Are dialogs and modals the same?

Since the dialogs place the system in a different mode, users cannot continue what they are doing until they acknowledge the dialog. They interrupt the user's workflow. Modal dialogs force users away from the tasks they were working on in the first place.

Is modal dialog is blocking window?

A modal window creates a mode that disables the main window but keeps it visible, with the modal window as a child window in front of it. Users must interact with the modal window before they can return to the parent application. This avoids interrupting the workflow on the main window.

What is the difference between modal dialog and modeless dialog box explain with an example?

You can use class CDialog to manage two kinds of dialog boxes: Modal dialog boxes, which require the user to respond before continuing the program. Modeless dialog boxes, which stay on the screen and are available for use at any time but permit other user activities.


2 Answers

Have you tried CWnd::GetLastActivePopup?

I haven't tested this to see if it'll work for modal dialogs only.


Edit 1: According to Raymond Chen, GetLastActivePopup should return the current active modal dialog.

Edit 2: Perhaps another method to retrieve the current modal window would be to modify your code to check for a disabled parent/owner - modal dialogs should always disable their owner before displaying.

like image 122
Alan Avatar answered Sep 30 '22 14:09

Alan


I've tried many ways to solve that, why i needed that because i'm dealing with code that declare all the dialog as pointers to allocated in the heapmemory (TDialog* d = new TDialog) this was OWL code I converted it to MFC I want to delete those pointers automatically only if the dialog is modal it is not allocated in the heap, so i need to check for it my solution was easy to override the DoModal in my inherited class and set a flag isModal to true if it is not shown using DoModal the flag isModal will still null_ptr as it was initialized in the constructor

class  : public CDialog
{
    private:
        bool isModal
    public:
        CMyDlg(int id, CWnd* parent = NULL) : CDialog(id, parent), isModal(false)
        {

        }

        virtual INT_PTR DoModal()
        {
            isModal = true;
            return CDialog::DoModal();//return __super::DoModal();
        }

        bool IsModal()
        {
            return isModal;
        }

        virtual void OnCancel()
        {
            if(isModal)
            {
                CDialog::OnCancel();
            }
            else
            {
                DestroyWindow();
            }
        }

        virtual void OnOk()
        {
            if(isModal)
            {
                CDialog::OnCancel();
            }
            else
            {
                DestroyWindow();
            }
        }
        virtual void PostNcDestroy()
        {
            delete this;
        }
}
like image 38
ahmedsafan86 Avatar answered Sep 30 '22 14:09

ahmedsafan86