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

先声明下,这篇文章是翻译其他地方的,也不知道作者允不允许翻译,在文章页面没找到相关说明。只是原文是英文版本的。如若,原作者看到,不希望这个存在,可以联系我或者平台删除此文。

在使用Microsoft基础类(MFC)库创建的单文档界面(SDI)应用程序中,每种文档类型都与单个视图类型相关联。在某些情况下,希望能够使用新视图切换文档的当前视图。

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

步骤如下:

本主题的其余部分假定以下内容:

  • -DerivedCWinApp对象的名称是CMyWinApp,并CMyWinAppMYWINAPP.HMYWINAPP.CPP中声明和定义。

  • CNewView是新CView起源对象的名称,CNewViewNEWVIEW.HNEWVIEW.CPP中声明和定义。

修改现有的应用程序类

要使应用程序在视图之间切换,您需要通过添加成员变量来存储视图以及切换它们的方法来修改应用程序类。

下面的代码添加到的声明CMyWinAppMYWINAPP.H

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

新成员变量,m_pOldViewm_pNewView指向当前视图和新创建的变量。新方法(SwitchView)在用户请求时切换视图。该方法的主体将在本主题后面的“ 实现切换功能”中讨论

对应用程序类的最后一次修改需要包含一个新的头文件,该文件定义了在切换函数中使用的Windows消息(WM_INITIALUPDATE)。

MYWINAPP.CPP的include部分插入以下行:

#include <AFXPRIV.H>

保存更改并继续下一步。

创建和修改新视图类

使用Class View中提供的New Class命令可以轻松创建新的视图类。这个类的唯一要求是它来源于CView。将此新类添加到应用程序。有关向项目添加新类的特定信息,请参阅添加类

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

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

保存更改并继续下一步。

创建并附加新视图

要创建和附加新视图,您需要修改InitInstance应用程序类的功能。修改补充说,创建一个新的查看对象,然后初始化两个新的代码m_pOldViewm_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在应用程序需要在视图之间切换时调用该方法的代码。这可以通过多种方式完成:通过添加新菜单项供用户选择或在满足某些条件时在内部切换视图。

示例下载

附加了一个示例小程序,但是不是根据这篇文章写的,但是大致思路是一致的,只是细节有些区分。下载地址https://download.csdn.net/download/yishang44/11686130

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值