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 CView
classe 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
CWinApp
derivato da èCMyWinApp
eCMyWinApp
viene dichiarato e definito in MYWINAPP. H e MYWINAPP. CPP.CNewView
è il nome del nuovoCView
oggetto derivato da eCNewView
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.