新建SDI工程
在插入菜单增加多两个CView类,进入这两个类的.h文件,把构造函数和析构函数都放到Public区
在APP的类.h文件中,增加下面几个public成员
CView* m_pOldView;
CView* m_pNewView; //在多少个视图就要加多少个这样的指针
CView* m_pNewView3; //这是第三个视图的指针
CView* SwitchView( ); //这个是以后要用到切换视图的指针
CView* m_CurrentView; //表示当前视图指针
在App类的.cpp文件中
添加引用头文件:
#include <AFXPRIV.H>
在InitInstance添加代码,加在 if (!ProcessShellCommand(cmdInfo)) return FALSE; 的后面
//New Add
CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView*) new View2;
m_pNewView3 = (CView*) new View3;
CDocument* pCurrentDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();
// Initialize a CCreateContext to point to the active document.
// With this context, the new view is added to the document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = pCurrentDoc;
// The ID of the initial active view is AFX_IDW_PANE_FIRST.
// Incrementing this value by one for additional views works
// in the standard document/view case but the technique cannot
// be extended for the CSplitterWnd case.
UINT viewID = AFX_IDW_PANE_FIRST + 1;
CRect rect(0, 0, 0, 0); // Gets resized later.
// Create the new view. In this example, the view persists for
// the life of the application. The application automatically
// deletes the view when the application is closed.
m_pNewView->Create(NULL, "AnyWindowName", WS_CHILD, rect, m_pMainWnd, viewID, &newContext); //创建第二个新视图
m_pNewView3->Create(NULL, "AnyWindowName", WS_CHILD, rect, m_pMainWnd, viewID, &newContext); //创建第三个新视图
// When a document template creates a view, the WM_INITIALUPDATE
// message is sent automatically. However, this code must
// explicitly send the message, as follows.
m_pNewView->SendMessage(WM_INITIALUPDATE, 0, 0); //第二个视图对象发送消息
m_pNewView3->SendMessage(WM_INITIALUPDATE, 0, 0); //第三个视图对象发送消息
// 以上是手工新加的code
可以大家会问:上面这么长的代码为什么没有第一个视图相关操作的?因为第一个视图是默认的,MFC会自动完成构造和创建,不用你操心了
继续下一步:
在App类的.cpp文件后面加多一个事件,
CView* CMy019App::SwitchView()
{
CView* pActiveView =
((CFrameWnd*) m_pMainWnd)->GetActiveView();
CView* pNewView= m_CurrentView; // m_CurrentView还记得否?是前面定义的类全局变量,public 型的
// Exchange view window IDs so RecalcLayout() works.
#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
#endif
pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd*) m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}
当然,也要在对应的.h文件加上这个事件的声明。这个事件就是负责切换视图的。
我们现在用菜单的方式来触发切换视图事件。
在原有菜单新加三项,分别为视图1,视图2,视图3.
为菜单添加触发事件,具体操作相信大家都识了吧,无非就是在App类的cpp文件中添加ON_COMMAND(ID_MENUITEM32772,OngoView3)
然后就是添加上事件的声明和定义
下面是定义的一个例:
void CMy019App::OngoView3()
{
m_CurrentView=m_pNewView3; // 先要切换到哪一个view
SwitchView();
}
OK,完成,
总结一下:
大体步骤就是:
1.添加新View类,
2.App.h中添加对应的视图指针
3.在InitInstance()中创建视图的实例。
4.添加 SwitchView();事件
5.触发 SwitchView();事件
注:上面创建创建视图的实例步骤也可以放到其它地方的,只要放在触发 SwitchView();事件之前就行了。