Multiple frame windows in SDI application

I have an application where I need to work with two CFrameWnd with
corresponding documents and views (not MDI, more like SDI * 2). But how can
I have two main frame windows? I couldn’t find anything in the docs or here
on www.codeguru.com.

So I fired up Visual Studio, and started to single-step InitInstance of a
regular SDI application. It should probably not be a surprise that it was
the CDocTemplate class that does most of the work.

My test example is called MultiApp, so the standard App-Wizard generated
document is called CMultiAppDoc, and the corresponding view is
CMultiAppView.

It is only necessary to change code in the InitInstance() member of your CWinApp-derived class.

Here is how to do it:

1. Create classes CMainFrame2, CMultiAppDoc2 and MultiAppView2 (the base
classes of these classes are left as an exercise for the reader 🙂 ).
Remember resources (icons, string table, menus etc.)

2. Create four private member variables in your CWinApp-derived class:


CSingleDocTemplate* m_pDoc1Template;
CSingleDocTemplate* m_pDoc2Template;
CMainFrame* m_pMainFrame;
CMainFrame2* m_pMainFrame2;

3. Register document templates in InitInstance():


m_pDoc2Template = new CSingleDocTemplate(
IDR_MAINFRAME2,
RUNTIME_CLASS(CMultiAppDoc2),
RUNTIME_CLASS(CMainFrame2), // main SDI frame window
RUNTIME_CLASS(CMultiAppView2));
AddDocTemplate(m_pDoc2Template);

m_pDoc1Template = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMultiAppDoc),
RUNTIME_CLASS(CMainFrame), // second main SDI frame window
RUNTIME_CLASS(CMultiAppView));
AddDocTemplate(m_pDoc1Template);

4. Create mainframes with corresponding views:


ASSERT(m_pDoc2Template != NULL);
ASSERT_KINDOF(CDocTemplate, m_pDoc2Template);
ASSERT(m_pDoc1Template != NULL);
ASSERT_KINDOF(CDocTemplate, m_pDoc1Template);

m_pDoc2Template->OpenDocumentFile(NULL, FALSE);
ASSERT_KINDOF(CMainFrame2, m_pMainWnd);
m_pMainFrame2 = static_cast(m_pMainWnd);
pTmpMainWnd = m_pMainWnd;
m_pMainWnd = NULL;
m_pDoc1Template->OpenDocumentFile(NULL, FALSE);
ASSERT_KINDOF(CMainFrame, m_pMainWnd);
m_pMainFrame = static_cast(m_pMainWnd);

m_pMainFrame2->ShowWindow(SW_SHOW);
m_pMainFrame2->GetActiveView()->OnInitialUpdate();
m_pMainFrame2->UpdateWindow();

m_pMainFrame->ShowWindow(SW_SHOW);
m_pMainFrame->GetActiveView()->OnInitialUpdate();
m_pMainFrame->UpdateWindow();

5. Remove the call to ProcessShellCommand, and handle command line parameters yourself.

6. When either of the mainframes receives focus, set the m_pMainWnd member
of your CWinApp-derived class to either m_pMainFrame2 or m_pMainFrame.

7. Overload members in your frame windows, documents and views. You may have
to overload further members in your CWinApp-derived class to get the
functionality you desire. Check the demo project, but remember that it is a very simple example.

Download demo project – 76 KB

Date Last Updated: April 3, 1999

More by Author

Must Read