將多個檢視加入至單一文件
在以 Microsoft Foundation Class (MFC) Library 建立的單一檔介面 (SDI) 應用程式中,每個檔案類型都與單一檢視類型相關聯。 在某些情況下,最好能夠使用新檢視來切換檔的目前檢視。
提示
如需針對單一檔實作多個檢視的其他程式,請參閱 CDocument::AddView 和 COLLECT MFC 範例。
您可以新增 CView
衍生類別和其他程式碼,以動態方式將檢視切換至現有的 MFC 應用程式,以實作這項功能。
步驟如下:
本主題的其餘部分假設如下:
衍生物件的名稱
CWinApp
是CMyWinApp
,並在CMyWinApp
MYWINAPP 中 宣告和定義。H 和 MYWINAPP。CPP 。CNewView
是新CView
衍生物件的名稱,並在CNewView
NEWVIEW 中 宣告和定義。H 和 NEWVIEW。CPP 。
修改現有的應用程式類別
若要讓應用程式在檢視之間切換,您必須藉由新增成員變數來儲存檢視,以及用來切換這些檢視的方法來修改應用程式類別。
將下列程式碼新增至 MYWINAPP 中的 宣告 CMyWinApp
。H :
CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();
新的成員變數 m_pOldView
和 m_pNewView
,指向目前的檢視和新建立的成員變數。 新的方法 ( SwitchView
) 會在使用者要求時切換檢視。 本主題稍後會在實作切換函 式中 討論方法的本文。
對應用程式類別的最後一個修改需要包含定義切換函式中使用的 Windows 訊息 ( WM_INITIALUPDATE ) 的新標頭檔。
在 MYWINAPP 的 include 區段中插入下一行。CPP :
#include <AFXPRIV.H>
儲存您的變更,並繼續下一個步驟。
建立和修改新的檢視類別
使用 [類別檢視] 提供的 [新增類別] 命令,即可輕鬆建立新的檢視類別 。 這個類別的唯一需求是其衍生自 CView
。 將這個新類別新增至應用程式。 如需將新類別新增至專案的特定資訊,請參閱 新增類別 。
將 類別新增至專案之後,您必須變更某些檢視類別成員的存取範圍。
修改 NEWVIEW。針對建構函式和解構函式,將存取規範從 protected
變更為 , public
以使用 H 。 這可讓類別以動態方式建立和終結,並在顯示檢視之前修改檢視外觀。
儲存您的變更,並繼續下一個步驟。
建立並附加新檢視
若要建立並附加新檢視,您必須修改 InitInstance
應用程式類別的函式。 修改會加入新的程式碼,以建立新的檢視物件,然後使用兩個現有的檢視物件初始化 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
方法。 這可以透過數種方式來完成:藉由為使用者新增功能表項目,以在符合特定條件時,在內部切換檢視。
如需新增功能表項目和命令處理常式函式的詳細資訊,請參閱 命令和控制通知的 處理常式。