代码之家  ›  专栏  ›  技术社区  ›  dalle

MFC中模态对话框的检测

  •  5
  • dalle  · 技术社区  · 16 年前

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

    有人有其他检测模态对话框的方法吗?

    4 回复  |  直到 16 年前
        1
  •  5
  •   Dan Roger Lipscombe    6 年前

    CWnd::GetLastActivePopup

    我还没有测试它是否只适用于模态对话框。


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

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

        2
  •  1
  •   ahmedsafan86    12 年前

    我尝试了很多方法来解决这个问题,为什么我需要它,因为我处理的是将所有对话框声明为指向堆内存中分配的指针的代码(TDialog*d=new TDialog),这是OWL代码,我将其转换为MFC,我想只有当对话是模态的,它没有在堆中分配时,才自动删除这些指针,所以我需要检查它。我的解决方案很容易覆盖继承类中的DoModal,并将标志isModal设置为true,如果它没有使用DoModal显示,标志isModals在构造函数中初始化时仍将为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;
            }
    }
    
        3
  •  0
  •   Goz    16 年前

    如果你只检测应用程序中的窗口,那么你可以导出自己的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;
    }
    

    一定有别的办法,但这是我唯一能想到的办法。