Přidání více zobrazení do jednoho dokumentu
V aplikaci s rozhraním s jedním dokumentem (SDI) vytvořená s knihovnou Mfc (Microsoft Foundation Class) je každý typ dokumentu přidružený k jednomu typu zobrazení. V některých případech je žádoucí mít možnost přepnout aktuální zobrazení dokumentu s novým zobrazením.
Tip
Další postupy implementace více zobrazení pro jeden dokument naleznete v tématu CDocument::AddView a COLLECT MFC ukázka.
Tuto funkci můžete implementovat přidáním nové CView
odvozené třídy a dalšího kódu pro dynamické přepínání zobrazení do existující aplikace MFC.
Kroky jsou následující:
Zbývající část tohoto tématu předpokládá následující:
Název -odvozeného objektu
CWinApp
jeCMyWinApp
aCMyWinApp
je deklarován a definován v MYWINAPP. H a MYWINAPP. CPP.CNewView
je název novéhoCView
-odvozeného objektu aCNewView
je deklarován a definován v NEWVIEW. H a NEWVIEW. CPP.
Úprava existující třídy aplikace
Aby aplikace přepnula mezi zobrazeními, musíte upravit třídu aplikace přidáním členských proměnných pro uložení zobrazení a metody, která je přepne.
Do deklarace CMyWinApp
v MYWINAPP přidejte následující kód. H:
CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();
Nové členské proměnné m_pOldView
a m_pNewView
přejděte na aktuální zobrazení a nově vytvořený. Nová metoda (SwitchView
) přepne zobrazení při vyžádání uživatelem. Tělo metody je popsáno dále v tomto tématu v Implementing Function.
Poslední úprava třídy aplikace vyžaduje zahrnutí nového hlavičkového souboru, který definuje zprávu systému Windows (WM_INITIALUPDATE), která se používá ve funkci přepínání.
Do oddílu include myWINAPP vložte následující řádek. CPP:
#include <AFXPRIV.H>
Uložte změny a pokračujte dalším krokem.
Vytvoření a úprava nové třídy zobrazení
Vytvoření nové třídy zobrazení je snadné pomocí příkazu Nová třída , který je k dispozici v zobrazení třídy. Jediným požadavkem této třídy je, že je odvozen od CView
. Přidejte tuto novou třídu do aplikace. Konkrétní informace o přidání nové třídy do projektu naleznete v tématu Přidání třídy.
Po přidání třídy do projektu je potřeba změnit přístupnost některých členů třídy zobrazení.
Upravte NEWVIEW. H změnou specifikátoru přístupu z protected
na public
konstruktor a destruktor. To umožňuje, aby byla třída vytvořena a zničena dynamicky a aby před zobrazením změnila vzhled zobrazení.
Uložte změny a pokračujte dalším krokem.
Vytvoření a připojení nového zobrazení
Pokud chcete vytvořit a připojit nové zobrazení, musíte upravit InitInstance
funkci třídy aplikace. Tato úprava přidá nový kód, který vytvoří nový objekt zobrazení a pak inicializuje oba m_pOldView
objekty zobrazení a m_pNewView
se dvěma existujícími objekty zobrazení.
Vzhledem k tomu, že se nové zobrazení vytvoří v rámci InitInstance
funkce, nová i existující zobrazení po celou dobu životnosti aplikace se zachovají. Aplikace by ale mohla stejně snadno vytvořit nové zobrazení dynamicky.
Vložte tento kód za volání: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);
Uložte změny a pokračujte dalším krokem.
Implementace funkce přepínání
V předchozím kroku jste přidali kód, který vytvořil a inicializoval nový objekt zobrazení. Posledním hlavním dílem je implementace metody přepínání, SwitchView
.
Na konci souboru implementace pro vaši třídu aplikace (MYWINAPP. CPP), přidejte následující definici metody:
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;
}
Uložte změny a pokračujte dalším krokem.
Přidání podpory pro přepínání zobrazení
Poslední krok zahrnuje přidání kódu, který volá metodu SwitchView
, když aplikace potřebuje přepínat mezi zobrazeními. Můžete to provést několika způsoby: buď přidáním nové položky nabídky pro uživatele zvolit nebo interně přepnout zobrazení, když jsou splněny určité podmínky.
Další informace o přidávání nových položek nabídky a funkcí obslužné rutiny příkazů naleznete v tématu Obslužné rutiny pro příkazy a oznámení řízení.