TN061 : messages d'ON_NOTIFY et de WM_NOTIFY
[!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 fournit des informations générales sur le nouveau message de WM_NOTIFY et décrit (et la plus courante) la manière recommandée pour gérer les messages de WM_NOTIFY dans votre application MFC.
Messages de notification dans windows 3.x
Dans windows 3.x, les contrôles informent leurs parents les événements tels que les clics de souris, des modifications de contenu et sélection, et peinture d'arrière-plan du contrôle en envoyant un message au parent.Les notifications simples sont envoyées en tant que messages de WM_COMMAND spéciale, au code de notification (tel que BN_CLICKED) et l'ID du contrôle compressé dans wParam et le handle du de commande dans lParam.Notez que depuis wParam et lParam sont complet, il n'existe aucun moyen de passer des informations supplémentaires — ces messages peuvent uniquement être notification simple.Par exemple, dans la notification de BN_CLICKED , il n'y a aucun moyen d'envoyer des informations sur l'emplacement du curseur de la souris lorsque le bouton concerné.
Lorsque les contrôles dans windows 3.x doivent envoyer un message de notification qui inclut des informations supplémentaires, ils utilisent un grand nombre de messages pour un usage spécial, y compris WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM, WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM, et ainsi de suite.Ces messages peuvent être affichés sur le contrôle qui les a envoyés.Pour plus d'informations, consultez TN062 : renvoi de message pour des contrôles Windows.
Messages de notification dans Win32
Pour les contrôles qui existaient dans Windows 3.1, l'API Win32 la plupart des messages de notification qui ont été utilisés dans windows 3.x.Toutefois, Win32 ajoute également plusieurs sophistiquée, contrôles complexes à ceux pris en charge dans windows 3.x.Souvent, le besoin de ces contrôles d'envoyer des informations supplémentaires avec leurs messages de notification.Au lieu d'ajouter un nouveau message de WM_* pour chaque nouvelle notification qui a besoin d'informations supplémentaires, les concepteurs de l'API Win32 avez choisi d'ajouter simplement un message, WM_NOTIFY, qui peut passer n'importe quelle quantité d'informations supplémentaires d'une manière standard.
Les messages deWM_NOTIFY contiennent l'ID de l'émission de contrôle le message dans wParam et un pointeur vers une structure dans lParam.Cette structure est une structure de NMHDR ou une certaine plus grande structure qui a une structure de NMHDR comme premier membre.Notez que étant donné que le membre de NMHDR est en premier, un pointeur à cette structure peut être utilisé en tant que pointeur vers NMHDR ou en tant que pointeur vers la structure plus grande selon la façon dont vous le cast.
Dans la plupart des cas, le pointeur indique une plus grande structure et vous devez effectuer un cast de celle-ci lorsque vous utilisez.Dans quelques notifications, telles que les notifications courantes de notifications (dont les noms commencent par NM_) et de TTN_SHOW et de TTN_POP du contrôle d'info-bulle, est une structure de NMHDR réellement utilisée.
La structure de NMHDR ou le membre initial contient le handle et l'ID de l'émission de contrôle le message et le code de notification (tel que TTN_SHOW).Le format de la structure de NMHDR est indiqué ci-dessous :
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
Pour un message de TTN_SHOW , le membre de code serait définie à TTN_SHOW.
La plupart des notifications passent un pointeur vers une plus grande structure qui contient une structure de NMHDR comme premier membre.Par exemple, considérez la structure utilisée par le message de notification de LVN_KEYDOWN du contrôle liste view, qui est envoyé lorsqu'une touche est enfoncée un contrôle liste view.Les points du pointeur vers une structure de LV_KEYDOWN , qui est définie comme indiqué ci-dessous :
typedef struct tagLV_KEYDOWN {
NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;
Notez que étant donné que le membre de NMHDR est en premier dans cette structure, le pointeur que vous avez passé dans le message de notification pouvez être casté en un pointeur vers NMHDR ou un pointeur vers LV_KEYDOWN.
Notifications communes à tous les nouveaux contrôles Windows
Certaines notifications sont communes à tous les nouveaux contrôles Windows.Ces notifications passent un pointeur vers une structure de NMHDR .
Le code de notification |
Envoyé car |
---|---|
NM_CLICK |
l'utilisateur a cliqué sur le bouton gauche de la souris dans le contrôle |
NM_DBLCLK |
L'utilisateur a double-cliquez sur le bouton gauche de la souris dans le contrôle |
NM_RCLICK |
L'utilisateur a cliqué sur le bouton de la souris dans le contrôle |
NM_RDBLCLK |
L'utilisateur a double-cliqué le bouton droit de la souris dans le contrôle |
NM_RETURN |
L'utilisateur a utilisateur appuie sur la touche ENTRÉE pendant que le contrôle a le focus d'entrée |
NM_SETFOCUS |
Le contrôle a été focus d'entrée donné |
NM_KILLFOCUS |
Le contrôle a perdu le focus d'entrée |
NM_OUTOFMEMORY |
Le contrôle ne peut pas effectuer une opération car il n'y a pas assez de mémoire libre |
ON_NOTIFY : Messages de la gestion WM_NOTIFY dans les applications MFC
Les messages de notification de handles d' CWnd::OnNotify de fonction.Son implémentation par défaut permet la table des messages pour les gestionnaires de notification appellent.En général vous ne substituez pas OnNotify.À la place, vous fournissez une fonction gestionnaire et ajoutez une entrée de la table des messages pour ce gestionnaire à la table des messages de la classe de votre fenêtre propriétaire.
ClassWizard, via la feuille de propriétés ClassWizard, peut créer l'entrée de la table des messages d' ON_NOTIFY et vous donner une fonction gestionnaire squelette.Pour plus d'informations sur l'utilisation de l'assistant classe pour simplifier ce processus, consultez Mapper les messages aux fonctions.
Macro de la table des messages d' ON_NOTIFY a la syntaxe suivante :
ON_NOTIFY( wNotifyCode, id, memberFxn )
par lorsque les paramètres en italique sont remplacés :
wNotifyCode
Le code du message de notification est géré, telles que LVN_KEYDOWN.id
l'identificateur enfant du contrôle pour lequel la notification est envoyée.memberFxn
La fonction membre à appeler lorsque cette notification est envoyée.
Votre fonction membre doit être déclarée avec le prototype suivant :
afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );
Notes
lorsque les paramètres en italique sont :
pNotifyStruct
Un pointeur vers la structure de notification, comme décrit dans la section ci-dessus.result
Un pointeur vers le code de résultat que vous définirez avant le retourniez.
Exemple
Pour spécifier que la fonction membre OnKeydownList1 de traiter les messages de LVN_KEYDOWN d' CListCtrl dont l'ID est IDC_LIST1, vous utiliseriez ClassWizard pour ajouter le texte suivant à votre table des messages :
ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 )
Dans l'exemple ci-dessus, la fonction fournie par l'assistant classe est :
void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler
// code here
*pResult = 0;
}
Notez que l'assistant classe fournit un pointeur du type approprié automatiquement.Vous pouvez accéder à la structure de notification via pNMHDR ou pLVKeyDow.
ON_NOTIFY_RANGE
Si vous devez traiter le même message de WM_NOTIFY pour un ensemble de contrôles, vous pouvez utiliser ON_NOTIFY_RANGE plutôt qu' ON_NOTIFY.Par exemple, vous pouvez avoir un jeu de boutons dont vous souhaitez effectuer la même action pour tout message de notification.
Lorsque vous utilisez ON_NOTIFY_RANGE, vous spécifiez une plage contiguë des identificateurs enfants pour lesquels traitent le message de notification en spécifiant les ID enfants de début et de fin de la plage.
ClassWizard ne gère pas ON_NOTIFY_RANGE; pour utiliser, vous devez modifier votre table des messages vous-même.
L'entrée de la table des messages et le prototype de fonction pour ON_NOTIFY_RANGE sont les suivantes :
ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn )
par lorsque les paramètres en italique sont remplacés :
wNotifyCode
Le code du message de notification est géré, telles que LVN_KEYDOWN.id
Le premier identificateur dans la plage contiguë des identificateurs.idLast
Le dernier identificateur dans la plage contiguë des identificateurs.memberFxn
La fonction membre à appeler lorsque cette notification est envoyée.
Votre fonction membre doit être déclarée avec le prototype suivant :
afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Notes
lorsque les paramètres en italique sont :
id
l'identificateur enfant du contrôle qui a envoyé la notification.pNotifyStruct
Un pointeur vers la structure de notification, décrite ci-dessus.result
Un pointeur vers le code de résultat que vous définirez avant le retourniez.
ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
Si vous souhaitez plusieurs objets dans le routage de notification pour traiter un message, vous pouvez utiliser ON_NOTIFY_EX (ou ON_NOTIFY_EX_RANGE) plutôt qu' ON_NOTIFY (ou ON_NOTIFY_RANGE).La seule différence entre la version d' EX et la version normale est que la fonction membre appelée pour la version d' EX retourne BOOL qui indique si le traitement des messages doit se poursuivre.Retourner FALSE de cette fonctionnalité vous permet de traiter le même message dans plusieurs objets.
ClassWizard ne gère pas ON_NOTIFY_EX ou ON_NOTIFY_EX_RANGE; si vous souhaitez utiliser l'un des deux, vous devez modifier votre table des messages vous-même.
L'entrée de la table des messages et le prototype de fonction pour ON_NOTIFY_EX et l' ON_NOTIFY_EX_RANGE sont les suivantes.Les significations les paramètres sont les mêmes que pour les versions non d'EX .
ON_NOTIFY_EX( nCode, id, memberFxn )
ON_NOTIFY_EX_RANGE( wNotifyCode, id, idLast, memberFxn )
Le prototype pour les deux ce qui précède est le même :
afx_msg BOOL memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );
Notes
Dans les deux cas, id contient l'identificateur enfant du contrôle qui a envoyé la notification.
La fonction doit retourner TRUE si le message de notification a été totalement traité ou FALSE si d'autres objets dans le routage des commandes ont la possibilité de gérer le message.