Aggiunta di più visualizzazioni a un singolo documento

In un'applicazione SDI (Single Document Interface) creata con la libreria MFC (Microsoft Foundation Class), ogni tipo di documento è associato a un singolo tipo di visualizzazione. In alcuni casi, è consigliabile avere la possibilità di cambiare la visualizzazione corrente di un documento con una nuova visualizzazione.

Suggerimento

Per altre procedure sull'implementazione di più visualizzazioni per un singolo documento, vedere L'esempio CDocument::AddView e COLLECT MFC.

È possibile implementare questa funzionalità aggiungendo una nuova CViewclasse derivata da e codice aggiuntivo per passare dinamicamente le visualizzazioni a un'applicazione MFC esistente.

Attieniti alla procedura seguente:

Nella parte restante di questo argomento si presuppone quanto segue:

  • Il nome dell'oggetto CWinAppderivato da è CMyWinAppe CMyWinApp viene dichiarato e definito in MYWINAPP. H e MYWINAPP. CPP.

  • CNewView è il nome del nuovo CViewoggetto derivato da e CNewView viene dichiarato e definito in NEWVIEW. H e NEWVIEW. CPP.

Modificare la classe applicazione esistente

Affinché l'applicazione passi da una visualizzazione all'altra, è necessario modificare la classe dell'applicazione aggiungendo variabili membro per archiviare le visualizzazioni e un metodo per cambiarle.

Aggiungere il codice seguente alla dichiarazione di CMyWinApp in MYWINAPP. H:

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

Le nuove variabili membro e m_pOldView m_pNewView, puntano alla visualizzazione corrente e a quella appena creata. Il nuovo metodo (SwitchView) cambia le visualizzazioni quando richiesto dall'utente. Il corpo del metodo viene illustrato più avanti in questo argomento in Implementare la funzione di cambio.

L'ultima modifica alla classe dell'applicazione richiede l'inclusione di un nuovo file di intestazione che definisce un messaggio di Windows (WM_INITIALUPDATE) usato nella funzione di cambio.

Inserire la riga seguente nella sezione include di MYWINAPP. CPP:

#include <AFXPRIV.H>

Salvare le modifiche e continuare con il passaggio successivo.

Creare e modificare la nuova classe View

La creazione della nuova classe di visualizzazione è semplificata usando il comando Nuova classe disponibile in Visualizzazione classi. L'unico requisito per questa classe è che deriva da CView. Aggiungere questa nuova classe all'applicazione. Per informazioni specifiche sull'aggiunta di una nuova classe al progetto, vedere Aggiunta di una classe.

Dopo aver aggiunto la classe al progetto, è necessario modificare l'accessibilità di alcuni membri della classe di visualizzazione.

Modificare NEWVIEW. H modificando l'identificatore di accesso da protected a public per il costruttore e il distruttore. In questo modo la classe può essere creata e eliminata dinamicamente e modificare l'aspetto della visualizzazione prima che sia visibile.

Salvare le modifiche e continuare con il passaggio successivo.

Creare e collegare la nuova visualizzazione

Per creare e collegare la nuova visualizzazione, è necessario modificare la InitInstance funzione della classe dell'applicazione. La modifica aggiunge nuovo codice che crea un nuovo oggetto visualizzazione e quindi inizializza e m_pOldView m_pNewView con i due oggetti visualizzazione esistenti.

Poiché la nuova visualizzazione viene creata all'interno della InitInstance funzione, sia le visualizzazioni nuove che esistenti vengono mantenute per la durata dell'applicazione. Tuttavia, l'applicazione potrebbe creare facilmente la nuova visualizzazione in modo dinamico.

Inserire questo codice dopo la chiamata a 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);

Salvare le modifiche e continuare con il passaggio successivo.

Implementare la funzione switching

Nel passaggio precedente è stato aggiunto codice che ha creato e inizializzato un nuovo oggetto visualizzazione. L'ultima parte principale consiste nell'implementare il metodo di cambio, SwitchView.

Alla fine del file di implementazione per la classe dell'applicazione (MYWINAPP. CPP), aggiungere la definizione del metodo seguente:

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;
}

Salvare le modifiche e continuare con il passaggio successivo.

Aggiungere il supporto per cambiare la visualizzazione

Il passaggio finale prevede l'aggiunta di codice che chiama il SwitchView metodo quando l'applicazione deve passare da una visualizzazione all'altra. Questa operazione può essere eseguita in diversi modi: aggiungendo una nuova voce di menu che l'utente può scegliere o cambiare internamente le visualizzazioni quando vengono soddisfatte determinate condizioni.

Per altre informazioni sull'aggiunta di nuove voci di menu e funzioni del gestore comandi, vedere Gestori per comandi e notifiche di controllo.

Vedi anche

Architettura documento/visualizzazione