Sdílet prostřednictvím


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é CViewodvozené 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 CWinAppje CMyWinAppa CMyWinApp je deklarován a definován v MYWINAPP. H a MYWINAPP. CPP.

  • CNewView je název nového CView-odvozeného objektu a CNewView 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_pNewViewpř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í.

Viz také

Architektura dokumentů a zobrazení