共用方式為


將多個檢視加入至單一文件

在以 Microsoft Foundation Class (MFC) Library 建立的單一檔介面 (SDI) 應用程式中,每個檔案類型都與單一檢視類型相關聯。 在某些情況下,最好能夠使用新檢視來切換檔的目前檢視。

提示

如需針對單一檔實作多個檢視的其他程式,請參閱 CDocument::AddView COLLECT MFC 範例。

您可以新增 CView 衍生類別和其他程式碼,以動態方式將檢視切換至現有的 MFC 應用程式,以實作這項功能。

步驟如下:

本主題的其餘部分假設如下:

  • 衍生物件的名稱 CWinAppCMyWinApp ,並在 CMyWinApp MYWINAPP 中 宣告和定義。H MYWINAPP。CPP

  • CNewView 是新 CView 衍生物件的名稱,並在 CNewView NEWVIEW 中 宣告和定義。H NEWVIEW。CPP

修改現有的應用程式類別

若要讓應用程式在檢視之間切換,您必須藉由新增成員變數來儲存檢視,以及用來切換這些檢視的方法來修改應用程式類別。

將下列程式碼新增至 MYWINAPP 中的 宣告 CMyWinApp 。H

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

新的成員變數 m_pOldViewm_pNewView ,指向目前的檢視和新建立的成員變數。 新的方法 ( SwitchView ) 會在使用者要求時切換檢視。 本主題稍後會在實作切換函 式中 討論方法的本文。

對應用程式類別的最後一個修改需要包含定義切換函式中使用的 Windows 訊息 ( WM_INITIALUPDATE ) 的新標頭檔。

在 MYWINAPP 的 include 區段中插入下一行。CPP

#include <AFXPRIV.H>

儲存您的變更,並繼續下一個步驟。

建立和修改新的檢視類別

使用 [類別檢視] 提供的 [新增類別] 命令,即可輕鬆建立新的檢視類別 。 這個類別的唯一需求是其衍生自 CView 。 將這個新類別新增至應用程式。 如需將新類別新增至專案的特定資訊,請參閱 新增類別

將 類別新增至專案之後,您必須變更某些檢視類別成員的存取範圍。

修改 NEWVIEW。針對建構函式和解構函式,將存取規範從 protected 變更為 , public 以使用 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 方法。 這可以透過數種方式來完成:藉由為使用者新增功能表項目,以在符合特定條件時,在內部切換檢視。

如需新增功能表項目和命令處理常式函式的詳細資訊,請參閱 命令和控制通知的 處理常式。

另請參閱

檔/檢視架構