Partager via


TN062 : Point d'arrêt de message pour les contrôles Windows

[!REMARQUE]

La note technique suivante n'a pas été modifiée depuis si c'était première inclus dans la documentation en ligne.Par conséquent, certaines procédures et rubriques peuvent être obsolètes ou incorrects.Pour obtenir les informations les plus récentes, il est recommandé que vous trouviez la rubrique d'intérêt dans l'index de la documentation en ligne.

Cette note technique explique le renvoi de message, une nouvelle fonctionnalité dans MFC 4,0.Elle contient également comment créer un contrôle réutilisable simple qui utilise le renvoi de message.

Cette note technique ne traite pas le renvoi de message à mesure qu'elle applique aux contrôles ActiveX (précédemment appelés contrôles OLE). Consultez l'article Contrôles ActiveX : Sous-classement d'un contrôle Windows.

Quel est renvoi de message ?

Les contrôles Windows envoient fréquemment des messages de notification à leurs fenêtres parentes.Par exemple, de nombreux contrôles envoyer un message de notification de contrôle de couleur (WM_CTLCOLOR ou une de ses variantes) à leur parent pour permettre au parent pour fournir un pinceau pour peindre l'arrière-plan du contrôle.

Dans windows et dans MFC avant la version 4,0, la fenêtre parente, souvent une boîte de dialogue, est chargé de gérer ces messages.Cela signifie que le code de la gestion que le message doit se trouver dans la classe parente de la fenêtre et qu'il doit être dupliqué dans chaque classe qui doit traiter ce message.Dans le cas ci-dessus, chaque boîte de dialogue que les contrôles souhaités avec des arrière-plans personnalisés doivent traiter le message de notification de contrôle de couleur.Il serait beaucoup plus simple de réutiliser du code s'il peut écrire une classe de contrôle qui ' sa propre couleur d'arrière-plan.

Dans MFC 4,0, le mécanisme ancien s'exécute toujours — les fenêtres parentes peuvent traiter les messages de notification.En outre, toutefois, MFC 4,0 simplifie la réutilisation en fournissant une fonctionnalité appelée « renvoi de message » qui permet ces messages de notification à gérer dans la fenêtre du contrôle enfant ou la fenêtre parente, ou les deux.Dans l'exemple de contrôle couleur d'arrière-plan, vous pouvez maintenant écrire une classe de contrôle qui définit sa propre couleur d'arrière-plan en gérant le message réfléchi d' WM_CTLCOLOR — tout sans compter sur le parent.(Notez que étant donné que le renvoi de message est implémenté par les MFC, pas par windows, la classe de fenêtre parente doit être dérivée d' CWnd pour que le renvoi de message s'exécute.)

Les versions antérieures MFC possèdent la fonction est semblable au retour de message en fournissant des fonctions virtuelles pour certains messages, tels que des messages pour les zones de liste owner-drawn (WM_DRAWITEM, etc.).Le nouveau mécanisme de renvoi de message est généralisé et cohérent.

Le renvoi de message est compatible en amont avec du code écrit pour les versions MFC avant 4,0.

Si vous avez fourni un gestionnaire d'un message spécifique, ou pour une plage des messages, dans la classe parente de la fenêtre, elle remplace les gestionnaires de messages réfléchis pour le même message vous a fourni n'appelez pas la fonction gestionnaire de classe de base dans votre propre gestionnaire.Par exemple, si vous gérez WM_CTLCOLOR dans votre classe de boîte de dialogue, votre gestion substitueront tous les gestionnaires de messages réfléchis.

Si, dans votre classe de fenêtre parente, vous fournissez un gestionnaire d'un message spécifique de WM_NOTIFY ou une chaîne des messages de WM_NOTIFY , votre gestionnaire est appelé uniquement si le contrôle enfant envoyant ces messages n'a pas un gestionnaire de messages répercutée dans ON_NOTIFY_REFLECT().Si vous utilisez ON_NOTIFY_REFLECT_EX() dans votre table des messages, votre gestionnaire de messages peut ou ne pas autoriser la fenêtre parente pour gérer le message.Si le gestionnaire retourne FALSE, le message est également traité par le parent, alors qu'un appel qui retourne TRUE n'autorise pas le parent de la gérer.Notez que le message réfléchi est traité avant le message de notification.

Lorsqu'un message de WM_NOTIFY est envoyé, le contrôle reçoit la première chance de la gérer.Si un autre message réfléchi est envoyé, la fenêtre parente a la première chance de la gérer et le contrôle recevra le message réfléchi.Pour ce faire, elle a besoin d'une fonction gestionnaire et d'une entrée appropriée dans la table des messages de la classe du contrôle.

Macro de la table des messages pour les messages réfléchis est légèrement différente pour les notifications normales : elle a _REFLECT ajouté à son nom habituel.Par exemple, pour gérer un message de WM_NOTIFY dans le parent, vous utilisez un ON_NOTIFY dans la table des messages du parent.Pour traiter le message réfléchi dans le contrôle enfant, utilisez la macro d' ON_NOTIFY_REFLECT dans la table des messages du contrôle enfant.Dans certains cas, les paramètres sont différents, également.Notez que l'assistant classe peut généralement ajouter des entrées de la table des messages pour vous et fournir aux implémentations squelettes de fonction de les paramètres appropriés.

Consultez TN061 : messages d'ON_NOTIFY et de WM_NOTIFY pour plus d'informations sur le nouveau message de WM_NOTIFY .

Entrées de la table des messages et prototypes de fonction gestionnaire pour les messages réfléchis

Pour gérer un message de contrôle réfléchi de notification, utilisez les macros de table des messages et les prototypes de fonctions répertoriées dans le tableau suivant.

Assistant classe peut généralement ajouter ces entrées de la table des messages pour vous et fournir des implémentations squelettes de fonction.Consultez Définir un gestionnaire de messages pour un message réfléchi pour plus d'informations sur la définition des gestionnaires pour les messages réfléchis.

Pour convertir le nom de message au nom de la macro dans, ajoutez ON_ et ajoutez _REFLECT.Par exemple, WM_CTLCOLOR devient ON_WM_CTLCOLOR_REFLECT.(Pour afficher les messages peuvent être mis en miroir, effectuez la conversion opposée sur la macro entrées dans le tableau ci-dessous.)

Les trois exceptions à cette règle ci-dessus sont les suivantes :

  • La macro pour les notifications de WM_COMMAND est ON_CONTROL_REFLECT.

  • La macro pour des réflexions de WM_NOTIFY est ON_NOTIFY_REFLECT.

  • La macro pour des réflexions d' ON_UPDATE_COMMAND_UI est ON_UPDATE_COMMAND_UI_REFLECT.

Dans ces cas spéciaux ci-dessus, vous devez spécifier le nom de la fonction membre de gestionnaire.Dans les autres cas, vous devez utiliser le nom standard pour votre fonction gestionnaire.

Les significations des paramètres et valeurs de retour des fonctions sont documentées sous ou le nom de fonction ou le nom de fonction avec On avez ajouté.Par exemple, CtlColor est documenté dans OnCtlColor.Plusieurs gestionnaires de messages réfléchis requièrent moins de paramètres que les gestionnaires similaires dans une fenêtre parente.Mettre en correspondance uniquement les noms dans le tableau ci-dessous avec les noms des paramètres formels dans la documentation.

Entrée de mappage

Prototype de fonction

ON_CONTROL_REFLECT( wNotifyCodeServeur IIS local memberFxn )

afx_msg void memberFxn ( );

ON_NOTIFY_REFLECT( wNotifyCodeServeur IIS local memberFxn )

résultat);d'afx_msg void memberFxn ( NMHDR * pNotifyStruct, LRESULT*

ON_UPDATE_COMMAND_UI_REFLECT( memberFxn )

afx_msg void memberFxn ( CCmdUI* pCmdUI);

ON_WM_CTLCOLOR_REFLECT ()

afx_msg HBRUSH CtlColor ( CDC* pDC, UINT nCtlColor);

ON_WM_DRAWITEM_REFLECT ()

afx_msg void DrawItem ( LPDRAWITEMSTRUCT lpDrawItemStruct);

ON_WM_MEASUREITEM_REFLECT ()

afx_msg void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct);

ON_WM_DELETEITEM_REFLECT ()

afx_msg void DeleteItem ( LPDELETEITEMSTRUCT lpDeleteItemStruct);

ON_WM_COMPAREITEM_REFLECT ()

afx_msg int CompareItem ( LPCOMPAREITEMSTRUCT lpCompareItemStruct);

ON_WM_CHARTOITEM_REFLECT ()

afx_msg int CharToItem ( UINT nKey, UINT nIndex);

ON_WM_VKEYTOITEM_REFLECT ()

afx_msg int VKeyToItem ( UINT nKey, UINT nIndex);

ON_WM_HSCROLL_REFLECT ()

afx_msg void HScroll ( UINT nSBCode, UINT nPos);

ON_WM_VSCROLL_REFLECT ()

afx_msg void VScroll ( UINT nSBCode, UINT nPos);

ON_WM_PARENTNOTIFY_REFLECT ()

afx_msg void ParentNotify ( UINT message, LPARAM lParam);

Les macros d' ON_NOTIFY_REFLECT et d' ON_CONTROL_REFLECT ont des variations qui permettent à plusieurs objet (tel que le contrôle et son parent) pour gérer un message donné.

Entrée de mappage

Prototype de fonction

ON_NOTIFY_REFLECT_EX( wNotifyCodeServeur IIS local memberFxn )

résultat);d'afx_msg BOOL memberFxn ( NMHDR * pNotifyStruct, LRESULT*

ON_CONTROL_REFLECT_EX( wNotifyCodeServeur IIS local memberFxn )

afx_msg BOOL memberFxn ( );

Gérer les messages réfléchis : un exemple d'un contrôle réutilisable

L'exemple simple suivant crée un contrôle réutilisable appelé CYellowEdit.Le contrôle fonctionne de la même manière qu'un contrôle d'édition normal mais affiche le texte noir sur un arrière-plan jaune.Il serait facile d'ajouter les fonctions membres qui permettraient le contrôle d' CYellowEdit à différentes couleurs d'affichage.

Pour tenter l'exemple qui crée un contrôle réutilisable

  1. Créez une nouvelle boîte de dialogue dans une application existante.Pour plus d'informations, consultez la rubrique d' éditeur de boîtes de dialogue .

    Vous devez disposer d'une application dans laquelle pour développer le contrôle réutilisable.Si vous n'avez pas une application existante à utiliser, créez une application basée sur des boîtes de dialogue à l'aide de AppWizard.

  2. Votre projet qui est chargé dans Visual C++, l'utilisation ClassWizard de créer une nouvelle classe a appelé CYellowEdit en fonction CEdit.

  3. Ajoutez les variables composées de trois membres à votre classe d' CYellowEdit .Les deux premiers sont des variables de COLORREF pour maintenir la couleur de texte et la couleur d'arrière-plan.Le troisième est un objet d' CBrush qui contiendra le pinceau pour peindre l'arrière-plan.L'objet d' CBrush vous permet de créer le pinceau une fois, simplement le référencement après que, et pour détruire le pinceau automatiquement lorsque le contrôle d' CYellowEdit est détruit.

  4. Initialisez les variables membres en écrivant le constructeur comme suit :

    CYellowEdit::CYellowEdit()
    {
       m_clrText = RGB( 0, 0, 0 );
       m_clrBkgnd = RGB( 255, 255, 0 );
       m_brBkgnd.CreateSolidBrush( m_clrBkgnd );
    }
    
  5. À l'aide de l'assistant classe, ajoutez un gestionnaire pour le message réfléchi d' WM_CTLCOLOR à votre classe d' CYellowEdit .Notez que le signe égal devant le nom de message dans la liste des messages que vous pouvez traiter indique que le message est pris en compte.Cela est décrit dans Définir un gestionnaire de messages pour un message réfléchi.

    ClassWizard ajoute la macro suivante de la table des messages et la fonction squelette pour vous :

    ON_WM_CTLCOLOR_REFLECT()
    
    // Note: other code will be in between....
    
    HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) 
    {
       // TODO: Change any attributes of the DC here
    
       // TODO: Return a non-NULL brush if the
       //   parent's handler should not be called
       return NULL;
    }
    
  6. Remplacez le corps de la fonction par le code suivant.Le code spécifie la couleur de texte, la couleur d'arrière-plan de texte, et la couleur d'arrière-plan pour le reste du contrôle.

       pDC->SetTextColor( m_clrText );   // text
       pDC->SetBkColor( m_clrBkgnd );   // text bkgnd
       return m_brBkgnd;            // ctl bkgnd
    
  7. Créez un contrôle d'édition dans votre boîte de dialogue, puis joignez -le à une variable membre en double-cliquant sur le contrôle d'édition en maintenant une touche de commande vers le bas.Dans la boîte de dialogue de variable membre d'ajouter, terminez le nom de la variable et choisissez « contrôle » pour la catégorie, puis « CYellowEdit » pour le type de variable.n'oubliez pas de définir l'ordre de tabulation dans la boîte de dialogue.En outre, veillez à inclure le fichier d'en-tête pour le contrôle d' CYellowEdit dans le fichier d'en-tête de votre boîte de dialogue.

  8. Générez et exécutez votre application.Le contrôle d'édition aura un arrière-plan jaune.

Voir aussi

Autres ressources

Notes techniques de nombres

Notes techniques de catégorie