2

Visual C++ 6.0 から VC++2008 の MFC バージョンに移植しているアプリケーションは、次のように多くの get AfxGetMainWnd()-and-do-C-Style-casts を実行します。

  CUserInterfaceDoc *m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())
                            ->GetActiveDocument();

に変換するだけで上記の手順を試すと、プログラムでdynamic_cast<>キャストから a- を介してメイン ウィンドウにアクセスできなくなっていることがわかりますCUserInterfaceDoc。おそらく、MFC が VC++ 6 でキャストを悪用したか、コンパイラが魔法をかけたのではないかと思います。

動的キャストを使用するように上記を書き直すと、次のようになります。最終的には nil ポインターになり、ここで書いた assert() 条件をトリップします。

CUserInterfaceDoc *m_pDoc;
CWnd * mainWnd = AfxGetMainWnd();
assert(mainWnd);
CFrameWnd *frmWnd = dynamic_cast<CFrameWnd *> (mainWnd);
assert(frmWnd);
m_pDoc = dynamic_cast<CUserInterfaceDoc *> (frmWnd);
assert(m_pDoc);

以前にこれを行ったことのある人なら誰でも「もちろん、キャスティングの動作を変更しました....」と言うことができると思いますが、それに関するドキュメントは見つかりません。

可能であれば、C++ クラスをメンバー変数 (フィールド) に変更して、
以前は "多かれ少なかれグローバル" から下に移動して見つけていたものへのリンクを格納しますAfxMainWnd()

ただし、何が変わったのかを知るのに役立つので、上で何が起こっているのかを理解できます。

CUserInterfaceDocは私のアプリケーションの MFC C++ ドキュメント クラスです。これは、実行時に "検索可能" であり、上部に全体的な C スタイルのキャストがある COleServerDoc です。

上記のキャストは最新の C++ でもコンパイルできますが、壊れています。これはおそらく、古い VC++ 6 コンパイラが、ISO C++ 標準に反する C スタイルのキャストを使用して何らかの内部「魔法」を行ったためです。(あくまで私の勝手な推測です。)

私の質問は2つの部分に分かれています:

  1. 現在、メインの CFrameWnd への参照がなく、この質問の上部にあるハックを使用していた別のクラスから CurrentDocument (CFrameWnd::CurrentDocument) を取得する通常の方法は何ですか?

  2. 上記のキャスト式の動作を変更する、非 ISO 準拠の VC++ 6 と多かれ少なかれ ISO 準拠の新しい C++ バージョンとの間で何が変更されたか、または MFC 内部アーキテクチャの変更が原因で破損が発生しましたか?

私のコードの変更:

CUserInterfaceDoc * CMyBrowser::GetUserInterfaceDoc()
{
    CUserInterfaceDoc *m_pDoc;
    // formerly did this, which works in VC++6 and doesn't work anymore:
    //m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())->GetActiveDocument();
    assert(m_pMainFrm);
    m_pDoc = dynamic_cast<CUserInterfaceDoc *> ( m_pMainFrm->GetActiveDocument() );
    assert(m_pDoc);
}
4

2 に答える 2

4

MFC を使用している場合は、基本的に dynamic_cast と同等のキャスティング用の MFC 定義マクロである DYNAMIC_DOWNCAST を使用することもできます。

CFrameWnd* pFrm = DYNAMIC_DOWNCAST(CFrameWnd, AfxGetApp()->m_pMainWnd);

m_pDoc = DYNAMIC_CAST(CUserInterfaceDoc, m_pMainFrm->GetActiveDocument());
于 2012-12-02T20:21:40.817 に答える