检测MFC中的模态对话框

时间:2009-08-19 10:15:10

标签: mfc modal-dialog

如何以编程方式检测我的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())

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

3 个答案:

答案 0 :(得分:5)

你试过CWnd::GetLastActivePopup吗?

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


修改1:根据Raymond ChenGetLastActivePopup应返回当前有效的模式对话框。

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

答案 1 :(得分: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;
}

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

答案 2 :(得分:0)

我已经尝试了很多方法来解决这个问题,为什么我需要它,因为我正在处理代码,它声明所有对话框都是在堆存储器中分配的指针(TDialog * d = new 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;
        }
}