检测MFC中的模态对话框

问题描述 投票:4回答:3

如何以编程方式检测我的MFC应用程序当前是否显示模式对话框或属性表?目前我正在使用以下内容,但我觉得代码也会触发无模式对话框。

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;
}

用法:

HasModalDialog(AfxGetMainWnd())

任何人都有另一种方法来检测模态对话框?

mfc modal-dialog
3个回答
5
投票

你试过CWnd::GetLastActivePopup吗?

我没有对此进行测试,看它是否仅适用于模态对话框。


编辑1:根据Raymond ChenGetLastActivePopup应返回当前活动的模态对话框。

编辑2:也许另一种检索当前模态窗口的方法是修改代码以检查禁用的父/所有者 - 模式对话框在显示之前应始终为disable their owner


0
投票

如果您只是在应用程序中检测窗口,那么您可以派生自己的CDialog和CPropertySheet并在其中放置一个简单的bool来跟踪它是否是模态的。

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;
}

必须有另一种方法来做到这一点,但这是我能想到的唯一方法。


0
投票

我已经尝试了很多方法来解决这个问题,为什么我需要这个,因为我正在处理代码,声明所有对话框都是在堆存储器中分配的指针(TDialog * d =新的TDialog)这是OWL代码我将它转换为MFC我只想在对话框是模态的时候自动删除那些指针,它没有在堆中分配,所以我需要检查它我的解决方案很容易覆盖我继承的类中的DoModal并将标志isModal设置为true如果它是没有显示使用DoModal标志isModal仍然是null_ptr,因为它在构造函数中初始化

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;
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.