WEBINAR: On-demand webcast
How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >
What is a MultiSingle document.
In most applications, it is necessary to have one document with many views. The SDI architecture is for one document and one view and the MDI architecture is for many documents with many views. My goal is to have an MDI architecture with one document and many views connected or not to the document. If a chose the 'new' file command, all views must close and a new document with the fist doc template view must be started. If a chose the 'close' file command, all views must close and the client area must be empty. Views not attached to the document (attached to the main frame) can live. If the system menu 'close' command of a child window is actived, the child window will close. If this is the main view (1st doc template) the effect is the same as if you select the 'close' command of the file menu.
To open these Views, the commands are implemented in the 'View' menu. The document class is responsible to open the document views and the mainframe classe is responsible to open the other views. For the COutView, an other menu is used with new commands to demonstrate the possibilities of MSDI.
The 'New window' command in the 'Window' menu open only new windows if the view is connected to the document. If the view is not attached to the document, it can't open a second view. You can change this as you like, see the CMSDIViewFrame class.
It is not possible to open more than one view of the same class if the view is attached to the document with the 'Create view' command. The function CreateOrActivateFrame checks if the view exist and active it. You can change this if you wish more than one view of the same class.
For independant views (not attached to the document), it is complicate to check if exist because we can't walk trough the views with a document pointer. So we must save the view pointer in the MainFrame and reset it when the COutView::OnDestroy() is called.
The ressource ID will be used to change the view title (the first resource substring). If you have different ressource ID for your views, you can change the menu too. If no menu nor accelerator table is defined for a ressource ID, the derived child window CMSDIViewFrame witch is the base frame class for all child frames exept the fist (CMSDIFirstFrame), will connect to the menu and accelerator of the fist view. It will use the fist ressource substring for the window title.
The CMSDIFirstFrame window class is the base frame class for the main view. It call the application to close all document views if it is closed.
Build MultiSingle (MSDI) document-view with AppWizard.
At this point, the MSDI application work fine. We must now implement the build of multiple views. The best way to do this is to add doc templates like Microsoft in the CHKBOOK sample and make change to the doc string (the third substring) to avoid the MDI Document dialog box.
- With the application studio, add your views creation commands in the 'View' menu.
- Add document string for your views like this "ViewTitle\n\n\n\n\n\n". In this sample IDR_GRAFTYPE & IDR_OUTTYPE are the new ressource-ID.
- Make a copy of the MDI icone for all new ressource-ID. You can change this icone as you like.
- If necessary, make a copy of the main view menu and change it according to the new view commands.
- With appwizard, map the messages to the document classe or the mainframe class.
- Edit the new fuctions and add the view creation. Use NULL for the doc parameter of CreateOrActivateFrame if the view is not a document view.
- Add the include files for your new views in your document class file msdidoc.cpp, in the mainfrm.cpp if necessary and in your application file msdi.cpp for doc template creation.
- Add the doc templates creation in your application file msdi.cpp. Use the CMSDIViewFrame classe to have a new frame title for all views. Give the new ressource-ID for all views.
MSDI with Visual C++4.0.
For Visual C++ 4.0, we must remove two functions and make litle change (see WIN32). These functions exist in the Win32 implementation of MFC.
Change between Versions.
Version 1.0. Uploaded as MSDI.ZIP
First implementation of the MSDI Multi(View) Single(Doc) Document Interface.
Version 1.1 (Oct 19 1996) (Uploaded as MSDI32.ZIP
Adding OnDestroy() in the COutView and call the CMainFrame::OnDestroyView() to clear the view pointer.
Version 1.2 (Oct 22 1996) Uploaded as MSDI1632.ZIP
Change name of classe CMSDIFrame to CMSDIFirstFrame.
Change name of classe CViewFrame to CMSDIViewFrame and files viewfrm.* to msdivfrm.*
Implement OnSysCommand() in the CMSDIFirstFrame to close all views if the main view is closed. Call an override function in the class CMSDIWinApp. You can change the behaviour of the first frame system menu close.
Implement OnCreate() in the CMSDIViewFrame for frame with no menu nor accelerator table.
Implement OnUpdateViewView2() to disable the create menu command if the view exist.
Set read only to TRUE in OnInitialUpdate() for the COutView.
Replace the CMSDIWinApp::SaveModified() function name with the name CloseDocument() and make the fuction virtual.
Replace the name CMultiSingleDocTemplate with CMSDITemplate.
Implement the ON_WINDOW_NEW message to create new windows for all view connected to the document. Implement the OnUpdateFrameTitle() to update the frame titel accordingly.
Add a new function GetDocTemplate() to the CMSDIWinApp to retreive the CMSDITemplate* with a CView* as parameter.
For all child windows, a new icon is defined, but the framework display the MFC icon for the main view and the same icon for the graf and output view. I have tryed to change the class and connect the right icon, but the code is to complicate for a generic application.
I'm sure you will have many applications with the MSDI interface. If you have some questions or if you have significant generic add on, please contact me.