添加多个视图与单文件

在使用 Microsoft (SDI) 基础类 (MFC)库创建的单文档界面 (mdi) 应用程序,每个文件类型与一个视图类型。有时,可以切换到文档的当前视图具有新视图适用。

提示提示

对于实现多个视图的其他程序的单文档,请参见 CDocument::AddView集合 MFC 示例。

可以通过将新的 CView实现此功能派生的类和其他代码动态切换到的视图现有的 MFC 应用程序。

步骤如下所示:

  • 修改现有应用程序类

  • 创建和修改新的视图类

  • 创建并附加新视图

  • 实现开关函数

  • 添加对切换视图支持

本主题其余部分假设您具备以下条件:

  • CWinApp的名称派生的对象是 CMyWinApp,并且, CMyWinApp 在 MYWINAPP.H 和 MYWINAPP.CPP 声明和定义。

  • CNewView 是新 CView的名称派生的对象和 CNewView 在 NEWVIEW.H 和 NEWVIEW.CPP 声明和定义。

修改现有应用程序类

对于切换的应用程序在视图间,需要通过添加成员变量存储视图和方法修改应用程序类切换到它们。

将以下代码添加到 CMyWinApp 的说明。 MYWINAPP.H 的:

CView* m_pOldView;
CView* m_pNewView;
CView* SwitchView( );

新成员变量, m_pOldView 和 m_pNewView,指向当前视图和新创建一个。新的方法 (SwitchView) 切换视图,则必须由用户。方法的主体在 实现开关函数的本主题后面讨论。

对应用程序类上次修改需要包括定义了开关函数。的 windows 消息的新头文件 (WM_INITIALUPDATE)

将以下代码行插入到 MYWINAPP.CPP 的部分包括:

#include <AFXPRIV.H>

保存更改并继续下一步。

创建和修改新的视图类

创建新的视图类由类视图还通过使用可用 新建类 的命令。此类的唯一要求是它从 CView派生。将此新类添加到应用程序。有关添加新类的具体信息添加到项目,请参见 添加类

在添加了类添加到项目,需要更改某些视图类成员的可访问性。

通过更改访问说明符修改 NEWVIEW.H 从 protected 到构造函数和析构函数的 公共 。,它可见之前,允许类动态创建和销毁此和修改视图的外观。

保存更改并继续下一步。

创建并附加新视图

若要创建并附加新的视图,需要修改应用程序类的 InitInstance 功能。修改将创建新的视图对象并初始化 m_pOldView 和 m_pNewView 与两个现有视图对象的新代码。

由于新视图。 InitInstance 函数中,创建新的和现有视图用于应用程序的生存期仍存在。但是,应用程序可以轻松地动态创建新的视图。

插入在调用后此代码为 ProcessShellCommand:

CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView*) new CNewView;
if (NULL == m_pNewView)
   return FALSE;

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, _T("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);

保存更改并继续下一步。

实现开关函数

在前面的步骤中,您将添加用于创建并初始化新的视图对象的代码。最后一个主要部分是执行切换方法, SwitchView。

在应用程序类 (MYWINAPP.CPP) 实现文件末尾,添加以下方法定义:

CView* CMyWinApp::SwitchView( )
{
   CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();

   CView* pNewView = NULL;
   if(pActiveView == m_pOldView)
      pNewView = m_pNewView;
   else
      pNewView = m_pOldView;

   // 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;
} 

保存更改并继续下一步。

添加对切换视图支持

最后一步中添加 SwitchView 调用方法的代码,当应用程序需要在视图间时切换。这可以执行的方法有多种:通过内部添加用户的新菜单项可以选择或切换视图,如果某些条件。

有关添加新菜单项和命令处理程序函数的更多信息,请参见 命令和控件通知的处理程序

请参见

概念

文档/视图结构