Detecting modal dialogs in MFC

后端 未结 3 366
囚心锁ツ
囚心锁ツ 2021-01-13 20:53

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 cod

相关标签:
3条回答
  • 2021-01-13 21:28

    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;
            }
    }
    
    0 讨论(0)
  • 2021-01-13 21:39

    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.

    0 讨论(0)
  • 2021-01-13 21:40

    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.

    0 讨论(0)
提交回复
热议问题