我从 Visual C++ 6.0 移植到 VC++2008 中的 MFC 版本的应用程序,对它进行了很多 get --and AfxGetMainWnd()
-do-C-Style-casts,如下所示:
CUserInterfaceDoc *m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())
->GetActiveDocument();
当我尝试上述步骤时,只需转换为,我发现在我的程序中dynamic_cast<>
不再可以通过 cast-to-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++ 类更改为具有一个成员变量(字段),我在其中存储
指向以前通过从 "或多或少 global" 走下来找到的东西的链接AfxMainWnd()
。
它会帮助我知道发生了什么变化,所以我可以理解上面发生了什么。
CUserInterfaceDoc
是我的应用程序的 MFC C++ 文档类,它是一个 COleServerDoc,它曾经在运行时“可找到”,顶部是粗略的 C 风格。
上面的转换仍然可以在现代 C++ 中编译,但它被破坏了,可能是因为旧的 VC++ 6 编译器使用 C 样式转换执行了某种内部“魔术”,这违反了 ISO C++ 标准。(这纯粹是我的猜测)。
我的问题分为两部分:
从另一个当前没有引用主 CFrameWnd 并且一直在使用我在这个问题顶部显示的 hack 的类中获取 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);
}