Introduction
The example code has a OpenGL view which is derived from CView
and also a Dialog View that was created by the App Wizard upon the project's creation.
How do I get multiple views with my MDI MFC application? Well, first I read an article here which used a tab control and created instances of CView
derived classes and placed them within the tab dialog. That worked, but I didn't want my views in a tab dialog. Here is another way to do it, without building your own initialization code.
I wanted to have an OpenGL View and a Dialog View on my MDI application. Normally, the MDI app just has one view derived from CView
and we all know you can make multiple instances of that view by going File-New. But what if you want to have two windows, etc., OpenGL and a dialog view? You have to make two classes derived from CView
and place them into the CMultiDocTemplate
.
So startup the App Wizard and choose the CFormView
View class instead of CView
and make sure you selected MDI instead of SDI. Always use MDI because, hey why not? You can limit the windows the user creates but you can also add new views easily if later needed. Now, add in the OpenglEnabledView
class by adding the .h and .cpp. (Sample is available on CodeProject, check for details on the usage. The files are also in my project but not mine.)
In your project, find the app class, then go to the initinstance
method. Search for this:
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_NeuralNetTwoTYPE,
RUNTIME_CLASS(CNeuralNetTwoDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CGLEnabledView));
AddDocTemplate(pDocTemplate);
So what you want to do is add a new template to the template manager. To do that just duplicate that and add in your other view class derived from CView
.
CMultiDocTemplate* pDocTemplate2;
pDocTemplate2 = new CMultiDocTemplate(IDR_NeuralNetTwoTYPE,
RUNTIME_CLASS(CNeuralNetTwoDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CNeuralNetTwoView));
AddDocTemplate(pDocTemplate2);
Now, at this point, when you go File-New, you will get a choice of what document template you want to use. This doesn't look very professional and if you want both dialogs views to open automatically, you will have to add some code. To remove that stupid box, add this after the command info line on the app class' initinstance
method:
CCommandLineInfo cmdInfo;
cmdInfo.m_nShellCommand=CCommandLineInfo::FileNothing ;
Now, override file_new
message handler from the CDocument
class. To do that, add a message map for File_new
to your mainframe class. In VS.NET, you change the properties by right clicking on the class in class view and selecting Properties, then hit the lightning icon. In VS6, you use the class wizard to map messages.
void CMainFrame::OnFileNew()
{
for(POSITION tPos =
theApp.m_pDocManager->GetFirstDocTemplatePosition();tPos!=NULL;)
{
CDocTemplate * ptempDocTemplate =
theApp.m_pDocManager->GetNextDocTemplate (tPos);
ptempDocTemplate->OpenDocumentFile(NULL);
}
}
The document templates hold the frame, doc, and view, and you can access those objects through the DocTemplate pointer which we got from the document manager pointer from our theApp
global. The OpenDocumentFile
method of CDocument
will init the objects for you and also store them in the document manager which has a pointer to it from the derived class CwinApp
.
You also will have to add message handler code for the File_New
message on your doc class. You will add the exact same code so that the child frame will also open both the views.
void CNeuralNetTwoDoc::OnFileNew()
{
for(POSITION tPos =
theApp.m_pDocManager->GetFirstDocTemplatePosition();tPos!=NULL;)
{
CDocTemplate * ptempDocTemplate =
theApp.m_pDocManager->GetNextDocTemplate (tPos);
ptempDocTemplate->OpenDocumentFile(NULL);
}
}
That code will call OpenDocumentFile
on all the documents you have in the template list which will init everything for you.
Questions and comments: please email r_jay_thompson@hotmail.com.