Partager via


Vues multiples à un document unique

Dans une application (SDI) de l'interface monodocument créée avec la bibliothèque Microsoft Foundation Class (MFC), chaque type de document est associé avec un seul type de vue. Dans certains cas, il est souhaitable d'avoir la possibilité de basculer de la vue actuelle d'un document à une nouvelle vue.

Conseil

Pour des procédures supplémentaires sur l'implémentation de plusieurs vues d'un seul document, consultez CDocument::AddView et l'exemple de RECUEILLEZ MFC.

Vous pouvez implémenter cette fonctionnalité en ajoutant à une application existante de MFC une nouvelle classe dérivée de CView et du code supplémentaire pour basculer entre les vues dynamiquement.

Les étapes sont les suivantes :

  • Modifiez la classe d'application existante

  • Créez et modifiez la nouvelle classe d'affichage

  • Créez et attachez la nouvelle vue

  • Implémentez la fonction de basculement

  • Ajouter la prise en charge de basculement de vue

Le reste de cette rubrique suppose les éléments suivants :

  • Le nom de l'objet dérivé de CWinApp est CMyWinApp, et CMyWinApp est déclaré et défini dans MYWINAPP.H et MYWINAPP.CPP.

  • CNewView est le nom du nouvel objet dérivé de CView, et CNewView est déclaré et défini dans NEWVIEW.H et NEWVIEW.CPP.

Modifiez la classe d'application existante

Pour l'application de basculer entre les modes, vous devez modifier la classe d'application en ajoutant des attributs pour stocker les vues et une méthode à utiliser.

Ajoutez le code suivant à la déclaration de CMyWinApp dans MYWINAPP.H :

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

Les attributs, m_pOldView et m_pNewView, pointent sur la vue actuelle et celle nouvellement créée. La nouvelle méthode (SwitchView) bascule les vues lorsque l'utilisateur le demande. Le corps de la méthode est présenté plus loin dans cette rubrique dans Implémentez la fonction de basculement.

La dernière modification de la classe d'application requiert d'inclure un fichier d'en-tête qui définit un message windows (WM_INITIALUPDATE) utilisé dans la fonction de basculement.

Insérez la ligne suivante dans la section d'inclusion de MYWINAPP.CPP :

#include <AFXPRIV.H>

Enregistrez vos modifications et passez à l'étape suivante.

Créez et modifiez la nouvelle classe d'affichage

Créer la nouvelle classe d'affichage est rendu simple à l'aide de la Nouvelle classe disponible dans l'Affichage de classes. Le seul impératif pour cette classe est qu'elle provienne de CView. Ajouter cette nouvelle classe à l'application. Pour des informations spécifiques sur l'ajout d'une nouvelle classe au projet, consultez Ajouter une classe.

Une fois que vous avez ajouté la classe au projet, vous devez modifier l'accessibilité des membres de la classe d'affichage.

Modifiez NEWVIEW.H en modifiant le spécificateur d'accès de protected à public pour le constructeur et le destructeur. Cela permet à la classe d'être créée et détruite dynamiquement et de modifier l'apparence de la vue avant qu'elle soit visible.

Enregistrez vos modifications et passez à l'étape suivante.

Créez et attachez la nouvelle vue

Pour créer et attacher la nouvelle vue, vous devez modifier la fonction InitInstance de la classe d'application. La modification ajoute un nouveau code qui crée un nouvel objet de vue puis initialise m_pOldView et m_pNewView avec les deux objets de vue existants.

Étant donné que la nouvelle vue est créée dans la fonction InitInstance, les vues nouvelles aussi bien qu'existantes persistent pour la durée de vie de l'application. Toutefois, elle peut tout aussi facilement créer la nouvelle vue de façon dynamique.

Insérez le code après l'appel à 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);

Enregistrez vos modifications et passez à l'étape suivante.

Implémentez la fonction de basculement

Dans l'étape précédente, vous avez ajouté le code qui a créé et initialisé un nouvel objet de vue. La dernière partie principale est d'appliquer la méthode de basculement, SwitchView.

À la fin du fichier d'implémentation de votre classe d'application (MYWINAPP.CPP), ajoutez la définition de méthode suivante :

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

Enregistrez vos modifications et passez à l'étape suivante.

Ajouter la prise en charge de basculement de vue

L'étape finale implique d'ajouter le code qui appelle la méthode SwitchView lorsque l'application doit basculer entre les vues. Cela peut être accompli de plusieurs manières : soit en ajoutant un nouvel élément de menu pour que l'utilisateur le choisisse soit en activant les vues en interne lorsque certaines conditions sont remplies.

Pour plus d'informations sur l'ajout de nouveaux éléments de menu et de fonctions du gestionnaire de commandes, consultez Gestionnaires des commandes et des notifications de contrôle.

Voir aussi

Concepts

architecture Document/Vue