加入多重檢視至單一文件

在單一文件介面 (SDI) 應用程式中使用 (MFC) 程式庫所建立,每個文件型別是單一檢視類型相關聯。在某些情況下,最好能夠來切換文件的新檢視目前的檢視。

提示提示

如需實作的一份文件的多個檢視的其他程序,請參閱 CDocument::AddView收集 MFC 範例。

您可以實作這項功能,藉由新增新的CView-衍生的和額外程式碼,在現有的 MFC 應用程式的動態切換檢視。

步驟如下:

  • 修改現有的應用程式類別

  • 建立及修改新的檢視類別

  • 建立並附加新的檢視

  • 實作切換函式

  • 新增檢視切換的支援

本主題的其餘部分假設下列各項:

  • 值為CWinApp-衍生的物件是CMyWinApp,以及CMyWinApp宣告,然後在 MYWINAPP 中定義。H 和 MYWINAPP。CPP。

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

修改現有的應用程式類別

若要檢視之間切換的應用程式,您必須加入成員變數來儲存檢視和切換它們的方法來修改應用程式類別。

將下列程式碼加入至宣告中的CMyWinApp MYWINAPP 中。H:

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

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

上次修改的應用程式類別需要包括新的標頭檔定義之特殊 Windows 訊息 (WM_INITIALUPDATE) 用於切換函式。

MYWINAPP [包含] 部分中,插入下行程式碼。CPP:

#include <AFXPRIV.H>

儲存變更並繼續進行下一個步驟。

建立及修改新的檢視類別

建立新的檢視類別更容易使用新的類別類別檢視中可用的命令。這個類別的唯一需求就是其衍生自CView。將這個新類別加入至應用程式中。如需將新的類別加入至專案的特定資訊,請參閱將類別加入

一旦將類別加入至專案後,您必須變更某些檢視類別成員的存取範圍。

修改 NEWVIEW。藉由變更從的存取規範 h protected到公用建構函式和解構函式。這樣的類別來建立和摧毀以動態方式,然後修改檢視的外觀,不然就看得見。

儲存變更並繼續進行下一個步驟。

建立並附加新的檢視

若要建立並附加新的檢視,您必須修改InitInstance您的應用程式類別的函式。所作的修改會加入新的程式碼會建立新的 view 物件,然後初始化這兩個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方法,當應用程式需要檢視之間切換。這可以在幾個方面: 讓使用者選擇新增功能表項目,或是符合特定條件時,在內部切換檢視。

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

請參閱

概念

文件/檢視架構