将多个视图添加到单个文档

    在用 Microsoft 基础类库 (MFC) 创建的单文档接口 (SDI) 应用程序中,每个文档类型与单个视图类型关联。在一些情况中,最好具有在当前文档视图与新视图之间切换的能力。

提示   有关实现单文档的多个视图的其他过程,请参见 tabindex="0" keywords="_mfc_CDocument.3a3a.AddView"> CDocument::AddView 和下列 MFC 示例: tabindex="0" keywords="_sample_mfc_ENROLL">ENROLL 和 tabindex="0" keywords="_sample_mfc_COLLECT">COLLECT。

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

步骤如下:

  • 修改现有应用程序类
  • 创建和修改新视图类
  • 创建并附加新视图
  • 实现切换函数
  • 添加视图切换支持

本主题的其余部分假定下列情况:

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

修改现有应用程序类

    为使应用程序能在视图间切换,需要修改应用程序类,方法是添加存储视图的成员变量和添加切换视图的方法。

将下列代码添加到 MYWINAPP.H 中的 CMyWinApp 声明:

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

    新成员变量 m_pOldViewm_pNewView 指向当前视图和新创建的视图。新方法 (SwitchView) 在用户请求时切换视图。

    对应用程序类的最后修改要求包括一个新的头文件来定义用在切换函数中的 Windows 消息 (WM_INITIALUPDATE)。

将下行插到 MYWINAPP.CPP 的 include 部分:

#include <AFXPRIV.H>

保存所做更改后继续进行下一步操作。

创建和修改新视图类

    通过使用类视图中可用的新建类命令使创建新视图类变得容易。对此类的唯一要求是它从 CView 派生。将此新类添加到应用程序。

    将类添加到项目后,需要更改一些视图类成员的可访问性。

    修改 NEWVIEW.H,将构造函数和析构函数的访问说明符从 protected 更改为 public。这使得可以动态创建和销毁类,并且允许类在视图可见前修改视图外观。

    保存所做更改后继续进行下一步操作。

创建并附加新视图

    若要创建和附加新视图,需要修改应用程序类的 InitInstance 函数。该修改添加创建新视图对象的新代码,然后用现有的两个视图对象初始化 m_pOldViewm_pNewView

因为新视图是在 InitInstance 函数内创建的,因此新视图和现有视图在应用程序的生存期内一直保持。但是,应用程序可以很容易地动态创建新视图。

在调用 ProcessShellCommand 后插入此代码:

...
CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView*) new CNewView;

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);

// 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 方法的代码。该操作可以通过几种方式来完成:添加供用户选择的新菜单项,或在符合某些条件时从内部切换视图。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值