Cette note décrit l'installation de la carte message MFC.
Le problème
Microsoft Windows met en œuvre ce sont essentiellement des fonctions virtuelles dans les classes de fenêtre à l'aide de ses installations de messagerie. En raison du grand nombre de messages impliqués, offrant une fonction virtuelle distincte pour chaque message Windows entraîne une trop grande vtable.
Aussi, puisque le nombre de messages de Windows défini par le système change au fil du temps, et car une application spécifique peut définir certains messages Windows qui lui sont propres, le mécanisme de la carte-message fournit un niveau d'indirection qui empêche les modifications de l'interface de briser le code existant.
Vue d'ensemble
MFC fournit une alternative à l'instruction switch utilisée dans les programmes traditionnels de Windows pour gérer les messages envoyés à une fenêtre. Le mappage de messages à des fonctions de membre peut être défini afin que lorsqu'un message doit être gérée par une fenêtre, la fonction de membre appropriée est appelée automatiquement. Ce centre message-carte est conçu pour ressembler à des fonctions virtuelles, mais n'a pas possibles avec des fonctions virtuelles C++ des avantages supplémentaires.
Définition d'une carte Message
La macro DECLARE_MESSAGE_MAP déclare trois membres d'une classe.
Cette macro doit être placée dans la déclaration d'une classe à l'aide de cartes de message. Par convention, il est à la fin de la déclaration de classe. Par exemple:
class CMyW&nd : public CMyParentWndClass
{
nbsp ; / / mon truc...
protégé :
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint() ;
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
C'est le format généré par AppWizard et ClassWizard lorsqu'ils créent de nouvelles classes. Le / / {{et / /}} entre crochets sont nécessaires pour le ClassWizard.
Table la carte message est défini par un ensemble de macros qui d'étendre aux entrées de la carte de message. Un tableau commence par un appel de macro BEGIN_MESSAGE_MAP , qui définit la classe qui est gérée par la carte de ce message et la classe parente à laquelle les messages non gérées sont passés. Le tableau se termine par l'appel de la macro END_MESSAGE_MAP.
Entre les appels de ces deux macro est une entrée pour chaque message à être gérées par cette carte de message. Chaque message Windows standard a une macro de la forme ON_WM_xxx (où xxx est le nom du message) qui génère une entrée pour ce message.
Une signature de fonction standard a été définie pour les paramètres de chaque message de Windows et d'assurant la sécurité de type. Ces signatures peuvent être trouvés dans le fichier AFXWIN.H dans la déclaration de CWnd. Chacun d'eux est marqué avec mot afx_msg pour une identification facile.
&Notenbsp ; ClassWizard nécessite que vous utilisez le mot clé afx_msg dans vos déclarations de gestionnaire de carte message.
Ces signatures de fonction ont été calculées à l'aide d'une simple convention. Le nom de la fonction commence toujours avec « On ». Cela est suivi par le nom du message Windows avec le WM_ enlevé et le seul mis en majuscule la première lettre de chaque mot. L'ordre des paramètres est wParam suivie LOWORD (lParam) puis HIWORD(lParam). Paramètres non utilisés ne sont pas transmises. Pointeurs vers les objets MFC appropriés sont convertis tous les handles qui sont enveloppés par les classes MFC. L'exemple suivant montre comment gérer le message WM_PAINT et causer le CMyWnd:: OnPaint la fonction
BEGI&N_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
nbsp ; //{{AFX_MSG_MAP(CMyWnd)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
La table de mappage de message doit être définie à l'extérieur de la portée de toute définition de fonction ou de classe. Il ne doit pas être placé dans un bloc d'extern « C ».
&Notenbsp ; ClassWizard va modifier les entrées de la carte de message qui sont trouvent entre les / / {{et / /}} crochet de commentaire.
Défini par l'utilisateur des Messages Windows
Les messages définis par l'utilisateur peuvent être inclus dans une message de la carte à l'aide de la macro ON_MESSAGE . Cette macro accepte un numéro de message et une fonction de membre de la forme:
nbsp ; / / à l'intérieur de la déclaration de classe
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam) ;
Par exemple :
# define WM_MYMESSAGE (WM_USER + 100)
BEGI&N_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
ON_MESSAGE (WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()
Dans cet exemple, nous établissons un gestionnaire d'événements pour un message personnalisé avec un ID de message Windows dérivé de la norme WM_USER de base pour les messages définis par l'utilisateur. Vous pouvez invoquer ce gestionnaire d'événements avec le code tel que:
CWnd * pWnd =... ;
pWnd-gt ;SendMessage(WM_MYMESSA&GE)
La plage de messages définis par l'utilisateur à l'aide de cette approche doit être dans la gamme WM_USER à 0x7fff.
&Notenbsp ; ClassWizard ne supporte pas les routines de gestionnaire d'événements ON_MESSAGE entrant de l'interface utilisateur de l'Assistant classe : vous devez les entrer manuellement dans l'éditeur de Visual C++. Une fois entrés, ClassWizard sera d'analyser ces entrées et vous permettre de les parcourir comme toutes les autres entrées message-carte.
Inscrit les Messages Windows
La :: RegisterWindowMessage fonction est utilisée pour définir un nouveau message de fenêtre est garanti d'être unique dans tout le système. La macro ON_REGISTERED_MESSAGE est utilisée pour traiter ces messages. Cette macro accepte une ID. du message le nom d'une variable UINT près qui contient les windows enregistrés Par exemple
class CMyWnd : public CMyParentWndClass
{
public :
nbsp ; CMyWnd() ;
//{{AFX_MSG(CMyWnd)
afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam) ;
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
UI&NT statique près de WM_FIND = RegisterWindowMessage("COMMDLG_FIND") ;
BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_REGISTERED_MESSAGE (WM_FIND, OnFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
La variable ID de message enregistrée Windows (WM_FIND dans l'exemple ci-dessus) doit être une variable près de la façon dont ON_REGISTERED_MESSAGE est mis en œuvre.
La gamme des messages définis par l'utilisateur à l'aide de cette approche sera dans la gamme 0xC000 à 0xFFFF.
&Notenbsp ; ClassWizard ne supporte pas les routines de gestionnaire d'événements ON_REGISTERED_MESSAGE entrant de l'interface utilisateur de l'Assistant classe, vous devez les entrer manuellement dans l'éditeur de texte. Une fois entrés, ClassWizard sera d'analyser ces entrées et vous permettre de les parcourir comme toutes les autres entrées message-carte.
Messages de commande
Les messages de commande de menus et d'accélérateurs sont traités de cartes message avec la macro ON_COMMAND . Cette macro accepte un ID de commande ainsi qu'une fonction membre. Seulement le message WM_COMMAND spécifique avec un wParam égale à la commande spécifiée, QU'ID est géré par la fonction membre spécifié dans l'entrée de la carte-message. Fonctions de membre du gestionnaire commande prennent sans paramètres et retournent void. La macro a la forme:
ON_COMMAND (id, memberFxn)
Commande mise à jour des messages sont routés par le même mécanisme que les gestionnaires ON_COMMAND . La macro ON_UPDATE_COMMAND_UI est utilisée à la place. Fonctions de commande de mise à jour gestionnaire membres prennent un paramètre unique, un pointeur vers un objet CCmdUI et retournent void. La macro a la forme
ON_UPDATE_COMMAND_UI (id, memberFxn)
Une forme étendue des gestionnaires de messages de commande est disponible pour les usages avancés. La macro ON_COMMAND_EX est utilisée à la place et offre un sur-ensemble des fonctionnalités ON_COMMAND . Fonctions étendues membres du gestionnaire de commandes prennent un paramètre unique, un UINT contenant l'ID de commande et renvoient une valeur BOOL. Le retour BOOL devrait être TRUE pour indiquer que la commande a été gérée, sinon routage continuera à d'autres objets de cible de commande.
Exemples des formes ci-dessus:
#defi&nenbsp ; ID_MYCMD 100
# define ID_COMPLEX 101
afx_msg void OnMyCommand() ;
afx_msg void OnUpdateMyCommand (CCmdUI * pCmdUI) ;
afx_msg BOOL OnComplexCommand(UINT nID)
ON_COMMAND (ID_MYCMD, OnMyCommand)
ON_UPDATE_COMMAND_UI (ID_MYCMD, OnUpdateMyCommand)
ON_COMMAND_EX (ID_MYCMD, OnComplexCommand)
vOID CMyClass::OnMyCommand()
{
nbsp ; / / traiter la commande
}
VOID CMyClass::OnUpdateMyCommand (CCmdUI * pCmdUI)
{
/ / définir l'état de l'interface utilisateur avec pCmdUI
}
BOOL CMyClass::OnComplexCommand(UI&NT nID)
{
/ / traiter la commande
Return TRUE ;
}
Également disponible pour une utilisation avancée est ON_COMMAND_RANGE et ON_COMMAND_RANGE_EX qui vous permet de gérer un éventail de commandes avec un gestionnaire de commande unique. Consultez la documentation du produit pour plus d'informations sur ces macros.
&Notenbsp ; ClassWizard prend en charge la création de gestionnaires ON_COMMAND et ON_UPDATE_COMMAND_UI , mais il ne supporte pas la création de gestionnaires d'événements ON_COMMAND_EX ou ON_COMMAND_RANGE . Cependant, Assistant classe va analyser et vous permettent de parcourir toutes les variantes de gestionnaire de commande trois.
Messages de Notification de contrôle
Les messages qui sont envoyés à des contrôles enfants à une fenêtre ont bit un supplément d'information dans leur message carte entrée : l'ID. du contrôle Le gestionnaire de messages spécifié dans une message carte entrée est appelé uniquement si le code de notification spécifié dans l'entrée de message-carte correspond à (1) le code de notification de contrôle (mot haut de lParam) comme BN_CLICKED, et ID de contrôle (2) (wParam) correspond à l'ID du contrôle spécifié dans l'entrée de message-carte.
Messages de notification de contrôle personnalisé peuvent utiliser la macro ON_CONTROL pour définir une entrée de message avec un code de notification personnalisé. Cette macro est de la forme
ON_CONTROL (wNotificationCode, id, memberFxn)
Pour une utilisation avancée des ON_CONTROL_RANGE peut être utilisé pour gérer une notification de contrôle spécifique d'une gamme de contrôles avec le même gestionnaire d'événements.
ClassWizard ne supporte pas la création d'un gestionnaire d'événements ON_CONTROL ou ON_CONTROL_RANGE dans l'interface utilisateur ; vous devez les entrer manuellement avec l'éditeur de texte. Une fois entrés, ClassWizard sera d'analyser ces entrées et vous permettent de parcourir les tout comme les autres entrées de carte message.
Contrôles communs Windows faire usage de la plus puissante WM_NOTIFY pour les notifications de contrôle complexe. Cette version de MFC possède un soutien direct pour ce nouveau message avec les macros ON_NOTIFY et ON_NOTIFY_RANGE . Consultez la documentation du produit pour plus d'informations sur ces macros.
&Notes techniques par le numéro |nbsp ; Notes techniques par catégorie