Download demo project - 7 Kb
Download source files - 18 Kb
Introduction
MFC, out of the box, supports three interface models, MDI, SDI, and dialog based. What it doesn't have is support for MTLW (ok, so MS probably has a different acronym for it, but what I mean is Multiple Top Level Windows). This is the model popularized by those web browsers we all know and love, Netscape Navigator and Internet Explorer.
Problem
The main problem with MTLW and MFC is the main window (aka CWinApp::m_pMainWnd
).
- MFC expects there to be one.
- MFC will close the application as soon as the main window is closed.
Solution
So what we need is a way to keep CWinApp::m_pMainWnd
pointed at a valid TLW and switch it from one window to another as needed to make sure that the app doesn't shut down except when the last TLW is closed.
Two classes will help you do this:
CMultiTopApp
- should be used as the base class for your app object.
CTopLevelFrame
- should be used as the base class for CMainFrame
.
Derive from these classes and wire up the message maps properly, and that's it. You're app now supports MTLW. Of course you need to have ways of creating new TLWs and probably you want to have a command to close all the windows and shut down your app, so the demo project includes those functions.
First, a handler for the "New Window" menu item creates new TLWs.
void CMultiTopSample::OnFileNewwindow()
{
CMainFrame* pFrame = new CMainFrame;
pFrame->LoadFrame(IDR_MAINFRAME,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
NULL);
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
}
Second, unless you want your users to have to close each window individually, you may want to have an "Exit" menu item which does the following:
void CMultiTopSample::OnAppExit()
{
CloseAllFrames() ;
}
Is this easy, or what!
How it works (briefly), and a BONUS member function:
CMultiTopApp
has an STL list for keeping track of TLWs...
list< CTopLevelFrame* > m_listMainFrames ;
... and a few functions for manipulating them:
void AddFrame( CTopLevelFrame* pFrame ) ;
void KillFrame( CTopLevelFrame* pFrame ) ;
void ReplaceMainFrame( CTopLevelFrame* pFrame ) ;
Plus a special bonus function. I use this to do print preview in YATLW and disable all the regular TLWs while I do so.
void EnableFrames( BOOL bEnable );
CTopLevelFrame
uses the CMultiTopApp
member functions in response to window creation and destruction messages.
MESSAGE |
Handler |
Action |
WM_CREATE |
OnCreate() |
calls AddFrame() after default processing |
WM_CLOSE |
OnClose() |
calls ReplaceMainFrame() before default processing |
WM_DESTROY |
OnDestroy() |
calls KillFrame() after default processing |