向单个文档添加多个视图

在单文档界面 (MDI) (SDI) 应用程序创建与 Microsoft 基础类 (MFC) (MFC) 库,每个文档类型与一个视图类型。 在某些情况下,可以切换一文档的当前的视图与新视图的是必需的。

提示

有关实现多视图的其他过程单个文件,请参见 CDocument::AddView收集 和 MFC 示例。

可以通过添加新的 CView实现此功能 (类派生和辅助代码动态切换的视图对现有 MFC 应用程序。

步骤如下所示:

  • 修改现有应用程序类

  • 创建和修改新的视图类

  • 创建并将新视图

  • 实现转换函数。

  • 添加切换支持的视图

本主题的其余部分假定以下操作:

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

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

修改现有应用程序类

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

在 CMyWinApp 的声明后,将下面的代码添加到类:

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

新成员变量、m_pOldView 和 m_pNewView),指向当前的视图和新创建一个。 新的方法 (SwitchView) 切换视图,则需要用户。 方法的主体位于 实现 Transform 功能中添加本主题后面讨论。

对类应用程序的最后修改要求包括定义了转换功能。的窗口消息的新头文件 (WM_INITIALUPDATE)

插入到 MYWINAPP.CPP 的包含节的代码行:

#include <AFXPRIV.H>

保存更改并继续下一步。

创建和修改新的视图类

创建新视图类从类视图可以轻松使用 新类 提供的命令。 此类的唯一要求是从 CView派生。 将此新类添加到应用程序中。 关于添加新类的具体信息。项目,请参见 添加类

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

通过将从 protected 中访问说明符 NEWVIEW.H 修改语句构造函数和析构函数的 public。 在可见之前,类允许动态创建和销毁这和修改视图的外观。

保存更改并继续下一步。

创建并将新视图

若要创建和附加新的视图,需要修改应用程序类的 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 方法的代码,则应用程序需要切换视图时。 这可以用几种方法:通过内部添加用户的新菜单项可以选中或切换视图,在某些条件。

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

请参见

概念

文档/视图体系结构