Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

MFC MDI Application Glue

3.25/5 (13 votes)
24 Jul 2010CPOL3 min read 1   986  
Retrieving the correct pointer anytime and anywhere in MFC MDI applications

Introduction

The MfcMdiAppGlue class is an abstract class which implements several static methods for retrieving the pointer to the created documents, views or frame windows as well as for getting the currently active document/view/frame pointers.

Background

The MFC framework provides the CWinApp* AFXAPI AfxGetApp( ); method for retrieving the pointer to the application object anywhere inside your MFC application. There is another method CView::GetDocument() to get the pointer to the currently active document within a CView derived class. When developing MFC applications, you shouldn’t need anything else in order to develop your application if you did follow the pattern behind the framework. But once you are working with multiple document types in combination with non-modal dialogs which should operate on these document instances, you will come across the problem that you can't get the pointer of the documents and views by simply calling a single method. I came across this problem multiple times and the third time I did implement nearly the same method, I decided to add this functionality to my class libraries.

Class Description

The class header is shown below:

C#
class ACMfcMdiAppGlue
{
public:
  virtual ~ACMfcMdiAppGlue();

  //Get the current active view window
  static CView* GetActiveViewWnd();
    
  //Get the current active document
  static CDocument* GetActiveDoc();
    
  //create a new instance of the document with a doc/view/frame triple 
  static BOOL CreateNewDocumentInstanceTriple(CDocument*& pDoc);

  // Function fills a list of all document objects in the application
  static void GetAllDocuments(t_DocumentList &Docs);

  // Function fills a list of all views in the application
  static void GetAllViews(t_ViewList &Views);

  // Function fills a list of all Child frames in the application
  // i.e. all CFrameWnd's except that returned by AfxGetMainWnd().
  static void GetAllFrameWnds(t_FrameList &Frames);
};

The first method of this class GetActiveViewWnd() returns a pointer to the currently active view window if there is one. Otherwise, this method returns a NULL pointer.

The implementation of this method is straight forward with the usage of the GetActiveView() method of the CMDIChildWnd class.

GetActiveDoc() is implemented in the same way as its counterpart for retrieving the active document with the usage of the GetActiveDocument() method of the CMDIChildWnd class.

C++
CView* ACMfcMdiAppGlue::GetActiveViewWnd()
{
  CWinApp* pApp = AfxGetApp();
    
  if((!pApp) || (!pApp->m_pMainWnd))
    return(NULL);

  // Get a pointer to the CMDIChildWnd by casting the main window pointer
  CMDIChildWnd * pChild = ((CMDIFrameWnd*)(pApp->m_pMainWnd))->MDIGetActive();

  if ( !pChild )
    return NULL;
      
  // Get the active view window
  CView* pView = pChild->GetActiveView();

  if(!pView)
    return(NULL);

  return(pView);
}

Simple, isn’t it? The MFC framework provides everything you need… Let’s take a look at the other methods of this class.

The method:

C++
static BOOL CreateNewDocumentInstanceTriple(CDocument*& pDoc) 

is used to create a new document with a new view window correctly embedded into its child frame window.

The parameter of this method is a reference to a pointer of the type CDocument which is used as output parameter of this method.

The method returns the first document template found within the MFC- MDI document manager CDocManager. If you did add additional document templates, you may want to modify this method in order to return the correct one.

Additional information about the document/view/frame- window architecture can be found on CodeProject or on MSDN.

The methods GetAllDocuments, GetAllViews and GetAllFrameWnds can be used in order to get the pointers to all currently opened documents views or frame- windows.

Let’s just look at one of these three methods as this is enough to understand how to implement all three of them.

C++
void ACMfcMdiAppGlue::GetAllViews(t_ViewList &Views)
{
  // Get the MFC application pointer
  CWinApp *pApp = AfxGetApp();
    
  // Get the pointer to the document manager of this application
  CDocManager *pDocMgr = pApp->m_pDocManager;

  // For all document templates
  for(POSITION TmplPos = pDocMgr->GetFirstDocTemplatePosition();TmplPos;)
  {
    // Get the next doc- template
    CDocTemplate *pTmpl = pDocMgr->GetNextDocTemplate(TmplPos);

    ASSERT_VALID(pTmpl);  
    if(pImpl == NULL)
      continue;
    
    // For All open documents of this document template type.
    for(POSITION Pos = pTmpl->GetFirstDocPosition();Pos;) 
    {
      CDocument *pDoc = pTmpl->GetNextDoc(Pos);            
      // For all views of this document
      POSITION ViewPos = pDoc->GetFirstViewPosition();
      while(ViewPos)
      {
        CView *pView =  pDoc->GetNextView(ViewPos);         
        Views.AddTail(pView);
      }
    }
  }
}

Using the Class

To use this class within your MFC- MDI application, simply include the two files within the zip archive into your project and include the MfcMdiAppGlue.h header file.

Once you have included the header, you can use the methods of the abstract class by simply calling the method with the use of the ACMfcMdiAppGlue namespace.

To get the currently active view of the type CScrollView, simply call the method and cast the pointer like shown below:

C++
CScrollView* pView = (CScrollView*)ACMfcMdiAppGlue::GetActiveViewWnd(); 

To create a new document / view / frame- window triple, just create a pointer of the type CDocument and pass it to the method. The triple will be added correctly to the MFC document manager.

C++
CDocument* pDoc = NULL;

ACMfcMdiAppGlue::CreateNewDocumentInstanceTriple(pDoc);

//do what every you need to do with your new document, view, frame window triple
//...

License

The class is licensed under the terms of the The Code Project Open License (CPOL) 1.02 and is free for private and commercial use, modification and distribution with your own source code.

If you have additional questions, do not hesitate to contact us by visiting our homepage.

Please feel free to give some constructive feedback if there is something in your mind.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)