2009-08-19 17 views
4

MFCアプリケーションが現在モーダルダイアログまたはプロパティシートを表示しているかどうかをプログラムで検出できますか?現在、私は以下を使用していますが、このコードはモードレスダイアログのトリガーとも感じています。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()) 

+0

に初期化されたとして真isModalはまだNULL_PTRます。 CDialogまたはCPropertySheetが "作成"されていれば、それはモードレスであり、コードはまだtrueを返します。 – Goz

+0

@ Goz:それはコードが苦しんでいる問題です。 – dalle

答えて

3

CWnd::GetLastActivePopupを試しましたか?

これはモーダルダイアログだけで動作するかどうかをテストしていません。


編集1:Raymond Chenによると、GetLastActivePopupは、現在アクティブなモーダルダイアログを返す必要があります。

編集2:おそらく、現在のモーダルウィンドウを取得するための別の方法が無効になって親/所有者を確認するためにあなたのコードを変更するだろう - 表示する前にモーダルダイアログがなければならない、常にdisable their owner

0

アプリケーション内のウィンドウのみを検出している場合は、独自のCDialogおよびCPropertySheetを導出し、モーダルであるかどうかを追跡する簡単なブールをそこに配置できます。

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

あり、それを行うための別の方法であることが、私は私の頭の上から考えることができる唯一の方法のthats必要があります。

+0

残念ながら、これらの新しいクラスからすべてのダイアログを派生させる必要があります。これは、既にMFCのダイアログクラスでは機能しません。 – dalle

+0

実際にはありません。あなたは彼らのために自分のクラスラッパーを作っていなければならないでしょう...ファフの地獄になるでしょう... – Goz

0

私はヒープメモリ(TDialog * d = new TDialog)に割り当てられたポインタとしてすべてのダイアログを宣言するコードを扱っているので、これを解決するには何が必要なのですか?これはOWLコードですそれをMFCに変換しました。ダイアログがモーダルである場合にのみ自動的にそれらのポインタを削除したいので、ヒープに割り当てられていないので、私の解決策は私の継承クラスのDoModalをオーバーライドしてフラグisModalをそれはDoModalのを使用してフラグが示されていない場合、それは私はあなたのコードは、実際にモーダルダイアログの検出方法が表示されないコンストラクタ

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; 
     } 
} 
関連する問題