getdoc()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild )
return ;
CDocument * pDoc = pChild->GetActiveDocument();
}
getview()
{
}
{
CMainFrame * pFrm = (CMainFrame *)this->GetMainWnd();
CMDIChildWnd * pchildframe = (CMDIChildWnd*)pFrm->GetActiveFrame();
CView* pview = pchildframe->GetActiveView();
}
http://support.microsoft.com/kb/108587
http://www.codeguru.com/forum/showthread.php?t=473808
Q : How to get the active document anywhere in my application?
A : There are several methods, one is to get first the active frame then call CFrameWnd::GetActiveDocument .
In an SDI application the main frame is the main window itself so a function which gets the active document may look like:
CDocument* GetSDIActiveDocument()
{
CDocument* pDoc = NULL;
CWnd* pWndMain = AfxGetMainWnd();
ASSERT(pWndMain);
ASSERT(pWndMain->IsKindOf(RUNTIME_CLASS(CFrameWnd)) &&
!pWndMain->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))); // Not an SDI app.
pDoc = ((CFrameWnd*)pWndMain)->GetActiveDocument();
return pDoc;
}
In MDI applications, we have to additionally get the active MDI child frame.
CDocument* GetMDIActiveDocument()
{
CDocument* pDoc = NULL;
CWnd* pWndMain = AfxGetMainWnd();
ASSERT(pWndMain);
ASSERT(pWndMain->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))); // Not an MDI app.
CFrameWnd* pFrame = ((CMDIFrameWnd*)pWndMain)->MDIGetActive();
if(NULL != pFrame)
{
pDoc = pFrame->GetActiveDocument(); // get the active document
}
return pDoc;
}
Putting them together we can write the following generic function to be used either in SDI or MDI applications.
CDocument* GenericGetActiveDocument()
{
CDocument* pDoc = NULL;
CWnd* pWndMain = AfxGetMainWnd();
if(NULL != pWndMain)
{
if(pWndMain->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
{
// MDI application, so first we have to get the active MDI child frame.
CFrameWnd* pFrame = ((CMDIFrameWnd*)pWndMain)->MDIGetActive();
if(NULL != pFrame)
{
pDoc = pFrame->GetActiveDocument();
}
}
else if(pWndMain->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
{
// SDI appllication so main window is the active frame.
pDoc = ((CFrameWnd*)pWndMain)->GetActiveDocument();
}
else
{
ASSERT(FALSE); // Neither MDI nor SDI application.
}
}
return pDoc;
}
Before casting to a given document type we have to check if indeed the returned pointer is of that type.
CDocument* pDoc = GenericGetActiveDocument();
if((NULL != pDoc) && pDoc->IsKindOf(RUNTIME_CLASS(CMyDocument)))
{
CMyDocument* pMyDoc = (CMyDocument*)pDoc;
// enjoy of ponter to CMyDocument object.
}
To avoid such type of tests in many places, the GenericGetActiveDocument function can be improved, giving to it info about the required document type.
CDocument* GenericGetActiveDocument(CRuntimeClass* pClass)
{
ASSERT(NULL != pClass); // must be not NULL and derived from CDocument.
ASSERT(pClass->IsDerivedFrom(RUNTIME_CLASS(CDocument)));
CDocument* pDoc = NULL;
CWnd* pWndMain = AfxGetMainWnd();
if(NULL != pWndMain)
{
if(pWndMain->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
{
// MDI application, so first we have to get the active MDI child frame.
CFrameWnd* pFrame = ((CMDIFrameWnd*)pWndMain)->MDIGetActive();
if(NULL != pFrame)
{
CDocument* pActiveDoc = pFrame->GetActiveDocument();
if((NULL != pActiveDoc) && pActiveDoc->IsKindOf(pClass))
{
// The found document is of required type
pDoc = pActiveDoc;
}
}
}
else if(pWndMain->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
{
// SDI appllication so main window is the active frame.
pDoc = ((CFrameWnd*)pWndMain)->GetActiveDocument();
}
else
{
ASSERT(FALSE); // Neither MDI nor SDI application.
}
}
return pDoc;
}
With the help of a little macro...
#define GET_ACTIVE_DOC(x) (x*)GenericGetActiveDocument(RUNTIME_CLASS(x))
...all remained to write anywhere in the SDI/MDI MFC application is
CMyDocument* pDoc = GET_ACTIVE_DOC(CMyDocument);