MDI Multiple Document Interface

In this article we will see how to enable the user to open more that one document at a time.
In an MDI application there is a top-level frame window. This window is derived from CMDIFrameWnd rather than CFrameWnd. Every document that we open would contain a three-way splitter window. The view of every document that we open would be housed in MDI child windows whose functionality is encapsulated in MFC’s CMDIChildWnd class.

The MDI version of myapp::InitInstance( ) is similar to the SDI version, but it differs in several important respects. To begin with, the class from which the document template is created is CMultiDocTemplate instead of CSingleDocTemplate.

The resource id passed to the document template’s constructor is IDR_CHILDFRAME instead of IDR_MAINFRAME. There are separate menus, icons and document strings for each of these resource ids. For example, the menu associated with IDR_MAINFRAME contains only two menu items ‘File’ and ‘About’. As against this, the menu associated with IDR_CHILDFRAME contains items like ‘File’, ‘Width’, ‘Colors’, ‘Brush’ and ‘Shapes’. Similarly, the document strings of IDR_MAINFRAME and IDR_CHILDFRAME are different. These are shown below: 

IDR_MAINFRAME        Shapes App
IDR_CHILDFRAME        \nNoname\n\nShape Files(*.shp) \n.shp
                        Shapes Document

Note that IDR_MAINFRAME’s document string now contains only the caption of the top-level frame window. The other 6 substrings have now been shifted to IDR_CHILDFRAME’s document string. We have dropped the first subsrting from IDR_CHILDFRAME’s document string. This is because for every new document that we open, a new window to house its view is created. The title of this window is same as the name of the document. This means that for every new document that we open a new title would appear in the caption bar. The framework manages the displaying of this title internally. Even if we mention the first substring, framework will simply ignore it. What would be the title if we open a new document? In this case the framework uses the name mentioned in the second substring of IDR_CHILDFRAME’s document string. In our case this name would he ‘Noname’.
The IDR_MAINFRAME’s icon is displayed in the title bar of the top-level MDI frame window. The IDR_CHILDFRAME’s icon is displayed in the title bars of the each document’s frame windows.
Another difference that you all will find in myapp::InitInstance( ) is the way the top-level frame window is created. In a SDI application, to create a frame window dynamically we just had to pass the RUNTIME_CLASS information about myframe while creating the CSingleDocTemplate object. However, in a MDI application we have passed the RUNTIME_CLASS information of mychildwnd (rather than myframe) while creating the CMultiDocTemplate object. Hence it is necessary to create the top-level MDI frame window ourselves. We have done this through the statements:

myframe *f = new myframe ;
f -> LoadFrame ( IDR_MAINFRAME ) ;
m_pMainWnd = f ;

This code would create the top-level frame window and load its icon, menu, accelerator and the document string, all in one step.
Imagine a situation where we have already opened a document in our application. If we now double click a ‘.shp’ document in the explorer window another instance of our application would begin. To prevent this we have called CWinApp::EnableShellOpen( ). Now the double-clicked document will be opened in the existing instance of our application rather than causing another instance to be started.
In a MDI application we  want splitter windows in MDI child windows. Hence we have created splitter windows in mychildwnd::OnCreateClient( ). The process of creation of splitter windows is same as in SDI applications.