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



Comments

  • One CMDIFrameWnd , One CFrameWnd

    Posted by guzhenghong on 11/18/2006 12:31am

    I want to create a multi-frame MFC application with Visual C++ 6.0 on Windows 2000 Pro. One frame is CMDIFrameWnd ,and the other frame is CFrameWnd. The application runs as AutoCAD 2000 (Autodesk inc), My problem is : When I switch frame windows by method of clicking frame windows on Windows Task Bar, the frame clicked don't bring to top. Why. Thanks. zhenghong gu from CHINA 11.18.2006

    Reply
  • ???

    Posted by Legacy on 07/17/2003 12:00am

    Originally posted by: Leon

    hallo ,
    Are you forget to put in your dsw file ??? Can't open your workspace...

    Reply
  • Problem to create the docking toolbar in both frames

    Posted by Legacy on 12/17/2002 12:00am

    Originally posted by: Efim Bassis

    I tried to create a docking toolbar by traditional method in both frames and it brings me error. Do you know what's a problem?

    Reply
  • Multi-MDI: problem with maximized child frames - don't forget hMDIMenu

    Posted by Legacy on 05/30/2002 12:00am

    Originally posted by: Stephan

    to make this work with MDI - even with maximized ChildWnd's - switch hMDIMenu and hMDIAccel in OnFrameFocus:

    m_pMainWnd = m_pFrame1;
    m_hMDIAccel = m_hMDIAccel1 ;
    m_hMDIMenu = m_hMDIMenu1 ;

    ok, hMDIAccel may not be necessary. But I wanted to avoid any trouble.

    • one CMDIFrame , one CFrameWnd

      Posted by guzhenghong on 11/18/2006 12:29am

      I want to create a multi-frame MFC application with Visual C++ 6.0 on Windows 2000 Pro. One frame is CMDIFrameWnd ,and the other frame is CFrameWnd. The application runs as AutoCAD 2000 (Autodesk inc), My problem is : When I switch frame windows by method of clicking frame windows on Windows Task Bar, the frame clicked don't bring to top. Why. Thanks. zhenghong gu from CHINA 11.18.2006

      Reply
    Reply
  • You must complete the OnFrameFocus methode

    Posted by Legacy on 01/11/2000 12:00am

    Originally posted by: laurent

    very fine sample, but, I've tried the same exercice with multi-MDIFrame and I think, it's necessary to change, in your methode SetFocus the attribut of the thread App to :
    
    

    HRESULT CMultiAppApp::OnFrame1Focus(WPARAM /* wParam */, LPARAM /* lParam */)
    {
    m_pMainWnd = m_pMainFrame;
    AfxGetThread()->m_pMainWnd = m_pMainFrame;

    return 0;
    }

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds