将AfxGetMainWnd上的C风格系列转换从VC6 / MFC6转换为现代MFC版本(VC ++ 2008及更高版本)

时间:2012-12-02 17:44:51

标签: visual-c++ mfc vc6

我正在将一个应用程序从Visual C ++ 6.0移植到VC ++ 2008中的MFC版本,它上面有很多get - AfxGetMainWnd() - 和 - 做 - C-Style-casts: / p>

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

当我尝试上述步骤时,只需转换为dynamic_cast<>,我发现在我的程序中,不再可以通过转换为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 ++ Document类,它是一个COleServerDoc,它曾经在运行时“可查找”,顶部有粗略的C风格。

上面的演员程序仍然在现代C ++中编译,但它已经破碎了,可能是由于旧的VC ++ 6编译器使用C风格的演员表符合ISO C ++标准做了某种内部“魔术”。 (这纯粹是我的猜测。)

我的问题分为两部分:

  1. 从另一个当前没有引用主CFrameWnd的类中获取CurrentDocument(CFrameWnd :: CurrentDocument)并使用我在此问题顶部显示的hack的常用方法是什么?

  2. 非ISO兼容的VC ++ 6与或多或少符合ISO标准的后续C ++版本之间发生了什么变化,这些版本会改变上面的强制转换表达式的行为,或者由于MFC内部而发生破坏架构变化?

  3. 我的代码更改:

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

2 个答案:

答案 0 :(得分:4)

如果你正在使用MFC,你可能只是咬紧牙关并使用DYNAMIC_DOWNCAST这是一个MFC定义的宏来进行投射,它基本上等同于dynamic_cast。

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

m_pDoc = DYNAMIC_CAST(CUserInterfaceDoc, m_pMainFrm->GetActiveDocument());

答案 1 :(得分:1)

在你的第一次改写中:

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-Style演员阵容中的GetActiveDocument()调用。所以它应该像这样工作:

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

DYNAMIC_DOWNCAST是soo oldschool,如果启用RTTI(默认情况下处于启用状态),实际上不再需要它。 另见:MFC DYNAMIC_DOWNCAST vs. dynamic_cast