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つの部分に分かれています:
現在、メインの CFrameWnd への参照がなく、この質問の上部にあるハックを使用していた別のクラスから CurrentDocument (CFrameWnd::CurrentDocument) を取得する通常の方法は何ですか?
上記のキャスト式の動作を変更する、非 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);
}