Programming with Microsoft Visual C++.NET 6ed [Electronic resources]

George Shepherd, David Kruglinski

نسخه متنی -صفحه : 319/ 169
نمايش فراداده

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

MainFrm.h header file:

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

The SwitchToView function (in

MainFrm.cpp ) makes some low-level MFC calls to locate the requested view and activate it. Don't worry about how it works—just adapt it to your own applications when you want the view-switching feature. Add the following code:

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.