An application I'm porting from Visual C++ 6.0 to the MFC version in VC++2008, does a lot of get-AfxGetMainWnd()
-and-do-C-Style-casts on it like this:
CUserInterfaceDoc *m_pDoc = (CUserInterfaceDoc*)((CFrameWnd *)AfxGetMainWnd())
->GetActiveDocument();
When I try the steps above, simply converting to dynamic_cast<>
, I find that the Main Window is no longer accessible via casting-to-a-CUserInterfaceDoc
in my program. I think that perhaps MFC had abused casts in VC++ 6, or that the compiler did some magic.
Rewriting the above to use dynamic casts would go like this, and it ends up with a nil pointer, which trips the assert() conditions I wrote here, as I want it to:
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);
I'm assuming that everybody who has done this before will be able to say "Yeah, of course, they changed that casting behaviour...." but I can't find the documentation for it.
Where possible I'm changing my C++ classes to have a member variable (field) where I store
links to things that it was formerly finding by walking down from the "more or less global" AfxMainWnd()
.
It would help me to know what changed though, so I can understand what's going on above.
CUserInterfaceDoc
is my application's MFC C++ Document class, it is a COleServerDoc which used to be "findable" at runtime with the gross C-style cast at the top.
The above cast still compiles in modern C++ but it's broken, probably due to the fact that the old VC++ 6 compiler did some kind of internal 'magic' with C-style casts that was against the ISO C++ standards. (That's purely a guess on my part).
My question is in two parts:
What's the usual way to get at the CurrentDocument (CFrameWnd::CurrentDocument) from another class that currently has no reference to the main CFrameWnd and had been using the hack I show at the top of this question?
What changed between the non-ISO-compliant VC++ 6 and the more-or-less ISO-compliant later C++ versions that would change the behaviour of the cast expressions above, or did the breakage occur due to MFC internal architecture changes?
My code change:
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);
}