Partager via


Ajout de plusieurs vues à un seul document

Dans une application d’interface à document unique (SDI) créée avec la bibliothèque MFC (Microsoft Foundation Class), chaque type de document est associé à un type d’affichage unique. Dans certains cas, il est souhaitable d’avoir la possibilité de changer l’affichage actuel d’un document avec une nouvelle vue.

Conseil

Pour obtenir des procédures supplémentaires sur l’implémentation de plusieurs vues pour un document unique, consultez CDocument ::AddView et l’exemple COLLECT MFC.

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

Les étapes sont les suivantes :

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

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

  • CNewView est le nom du nouvel CViewobjet dérivé et CNewView est déclaré et défini dans NEWVIEW. H et NEWVIEW. CPP.

Modifier la classe d’application existante

Pour que l’application bascule entre les vues, vous devez modifier la classe d’application en ajoutant des variables membres pour stocker les vues et une méthode pour les changer.

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

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

Les nouvelles variables membres, m_pOldView et m_pNewView, pointent vers l’affichage actuel et le nouveau membre créé. La nouvelle méthode (SwitchView) bascule les vues lorsque l’utilisateur le demande. Le corps de la méthode est abordé plus loin dans cette rubrique dans Implémenter la fonction de basculement.

La dernière modification de la classe d’application nécessite l’inclusion d’un nouveau 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 Include de MYWINAPP. CPP :

#include <AFXPRIV.H>

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

Créer et modifier la nouvelle classe d’affichage

La création de la classe d’affichage est facile à l’aide de la commande Nouvelle classe disponible à partir de l’affichage de classes. La seule exigence pour cette classe est qu’elle dérive de CView. Ajoutez cette nouvelle classe à l’application. Pour plus d’informations sur l’ajout d’une nouvelle classe au projet, consultez Ajout d’une classe.

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

Modifiez NEWVIEW. H en modifiant le spécificateur protected d’accès de vers 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 l’affichage avant d’être visible.

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

Créer et attacher la nouvelle vue

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

Étant donné que la nouvelle vue est créée dans la InitInstance fonction, les vues nouvelles et existantes persistent pendant toute la durée de vie de l’application. Toutefois, l’application peut aussi facilement créer la nouvelle vue de manière dynamique.

Insérez ce 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émenter la fonction de basculement

À l’étape précédente, vous avez ajouté du code qui a créé et initialisé un nouvel objet d’affichage. Le dernier élément majeur consiste à implémenter 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 du changement d’affichage

La dernière étape consiste à ajouter du code qui appelle la SwitchView méthode lorsque l’application doit basculer entre les vues. Cette opération peut être effectuée de plusieurs façons : en ajoutant un nouvel élément de menu à l’utilisateur pour choisir ou basculer les vues en interne lorsque certaines conditions sont remplies.

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

Voir aussi

Architecture de document/affichage