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