The Ex18c Example: Switching View Classes Without a Splitter
Sometimes you'll just want to switch view classes under program control and not be bothered with a splitter window. The Ex18c example is an SDI application that switches between CStringView and CHexView in response to commands on the View menu. Starting with what the MFC Application Wizard generates, all you need to do is add two new menu commands and then add some code to the CMainFrame class. You also need to change the CStringView and CHexView constructors from protected to public.
Resource Requirements
The following two commands have been added to the View menu in the IDR_MAINFRAME menu resource.
Caption | Command ID | CMainFrame Function |
---|---|---|
St&ring View | ID_VIEW_STRINGVIEW | OnViewStringView |
&Hex View | ID_VIEW_HEXVIEW | OnViewHexView |
The Class View's Properties window was used to add the command-handling functions and corresponding update command user interface handlers to the CMainFrame class.
CMainFrame
The CMainFrame class gets a new private helper function, SwitchToView, which is called from the two menu command handlers. The enum parameter tells the function which view to switch to. Here are the two added items in the

private:
enum eView { STRING = 1, HEX = 2 };
void SwitchToView(eView nView);
The SwitchToView function (in

void CMainFrame::SwitchToView(eView nView)
{
CView* pOldActiveView = GetActiveView();
CView* pNewActiveView = (CView*) GetDlgItem(nView);
if (pNewActiveView == NULL) {
switch (nView) {
case STRING:
pNewActiveView = (CView*) new CStringView;
break;
case HEX:
pNewActiveView = (CView*) new CHexView;
break;
}
CCreateContext context;
context.m_pCurrentDoc = pOldActiveView->GetDocument();
pNewActiveView->Create(NULL, NULL, WS_BORDER,
CFrameWnd::rectDefault, this, nView, &context);
pNewActiveView->OnInitialUpdate();
}
SetActiveView(pNewActiveView);
pNewActiveView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
pOldActiveView->SetDlgCtrlID(
pOldActiveView->GetRuntimeClass() ==
RUNTIME_CLASS(CStringView) ? STRING : HEX);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
RecalcLayout();
}
Finally, here are the menu command handlers and update command user interface handlers that the code wizard available from Class View's Properties window initially generated (along with message map entries and prototypes). The update command user interface handlers test the current view's class.
void CMainFrame::OnViewStringView()
{
SwitchToView(STRING);
}
void CMainFrame::OnUpdateViewStringView(CCmdUI* pCmdUI)
{
pCmdUI->Enable(
!GetActiveView()->IsKindOf(RUNTIME_CLASS(CStringView)));
}
void CMainFrame::OnViewHexView()
{
SwitchToView(HEX);
}
void CMainFrame::OnUpdateViewHexView(CCmdUI* pCmdUI)
{
pCmdUI->Enable(
!GetActiveView()->IsKindOf(RUNTIME_CLASS(CHexView)));
}
Testing the Ex18c Application
The Ex18c application initially displays the CStringView view of the document. You can toggle between the CStringView and CHexView views by choosing the appropriate command from the View menu. Both views of the document are shown side by side in Figure 18-2.

Figure 18-2: The CStringView view and the CHexView view of the document.