共用方式為


將多個檢視新增至單一檔

在以 Microsoft Foundation Class (MFC) Library 建立的單一檔介面 (SDI) 應用程式中,每個文件類型都與單一檢視類型相關聯。 在某些情況下,最好具備將文件的目前檢視替換為新檢視的能力。

小提示

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

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

這些步驟如下:

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

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

  • CNewView 是新 CView 衍生對象的名稱,而 CNewView 則是在 NEWVIEW.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>

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

建立和修改新的檢視類別

使用 [類別檢視] 提供的 [ 新增類別 ] 命令,即可輕鬆建立新的檢視類別。 這個類別的唯一需求是其衍生自 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;
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 方法。 這可以透過數種方式來完成:例如為使用者新增一個選單項目以供選擇,或當符合特定條件時在內部切換檢視。

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

另請參閱

檔/檢視架構