views:

325

answers:

2

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?

A: 

If you are only detecting windows within your application then you could derive your own CDialog and CPropertySheet and put a simple bool in there that keeps track of whether it is modal or not.

bool HasModalDialog(const CWnd* pWnd)
{
   const CWnd* pChildWnd = pWnd ? pWnd->GetNextWindow(GW_HWNDPREV) : NULL;
   while (pChildWnd)
   {
      if (pWnd == pChildWnd->GetTopLevelParent() )
      {
         if ( pChildWnd->IsKindOf(RUNTIME_CLASS(CMyDialog) )
         {
             return ((CMyDialog*)pChildWnd)->IsModal();
         }

         if ( pChildWnd->IsKindOf(RUNTIME_CLASS(CMyPropertySheet) )
         {
             return ((CMyPropertySheet*)pChildWnd)->IsModal();
         }
      }
      pChildWnd = pChildWnd->GetNextWindow(GW_HWNDPREV);
   }

   return false;
}

There must be another way to do it but thats the only way I can think of off the top of my head.

Goz
Unfortunately that requires all dialogs to be derived from these new classes, and that won't work for the dialog classes already in MFC.
dalle
indeed not. You would have to make your own class wrappers for them too ... would be a hell of a faff ...
Goz
+1  A: 

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.

Alan