Contents Up Previous Next

Vue d'ensemble de la gestion d'événements

Classes: wxEvtHandler, wxWindow, wxEvent

Introduction
Comment sont traités les événements
Evénements générés par l'utilisateur par rapport aux événements générés par programmation
Gestionnaires d'événements connectables
Identifiants des fenêtres
Sommaire des macros d'événements
Sommaire des événements personnalisés


Introduction

Avant la version 2.0 de wxWidgets, les événements étaient gérés par l'application soit en fournissant des fonctions d'appel, ou en surclassant des fonctions membres virtuelles telles que OnSize.

Depuis wxWidgets 2.0, les tables d'événements sont utilisées à la place, avec quelques exceptions.

Une table d'événements est placée dans un fichier d'implémentation pour dire à wxWidgets comment rediriger les événements vers les fonctions membres. Ces fonctions membres ne sont pas des fonctions virtuelles, mais elles ont toutes une forme similaire : elles prennent toutes un argument unique dérivé de wxEvent, et on un type de retour vide (void).

Voici un exemple d'une table d'événements.

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  EVT_MENU    (DO_TEST,   MyFrame::DoTest)
  EVT_SIZE    (           MyFrame::OnSize)
  EVT_BUTTON  (BUTTON1,   MyFrame::OnButton1)
END_EVENT_TABLE()
Les deux premières entrées définissent la redirection de deux commandes de menus vers deux fonctions membres différentes. La macro EVT_SIZE n'a pas besoin d'un identifiant de fenêtre, car normalement, vous n'êtes interresés que par les événement de redimensionnement de la fenêtre courante.

La macro EVT_BUTTON démontre que l'événement originaire ne doit pas forcément venir de la fenêtre implémentant la table d'événement -- si la source de l'événement est un bouton placé sur un panel, lui-même dans une frame, cela marchera quand même, parce-que les tables d'événements sont parcourues à travers toute la hiérarchie des fenêtres pour les événements de commande. Dans ce cas, la table d'événement du bouton sera parcourur, puis celle du panel parent, ensuite, celle de la frame.

Comme indiqué précédemment, les fonctions membres qui gèrent les événements n'ont pas à être virutelles. En effet, les fonctions membres ne doivent pas être virtuelles car le gestionnaire d'événements ignore que ces fonctions sont virtuelles, par exemple, surclasser une fonction membre virtuelle dans une classe dérivée n'aura aucun effet. Ces fonctions membres prennent un argument "événement", et la classe d'événement diffère suivant le type d'événement et la lasse de la fenêtre originaire. Pour les événements de redimensionnement, wxSizeEvent est utilisé. Pour les commandes de menus, et la plupart des commandes de contrôles (tels que les appuis sur les boutons), wxCommandEvent est utilisé. Quand les contrôles deviennent plus compliqués, alors, des classes d'événements spécifiques sont utilisées, telles que wxTreeEvent pour les événements depuis un wxTreeCtrl (contrôle d'arborescence).

Tout comme la table d'événements dans le fichier d'implémentation, il doit y avoir une macro DECLARE_EVENT_TABLE quelquepart dans la déclaration de la classe. Par exemple:

class MyFrame : public wxFrame
{
public:
  ...
  void OnExit(wxCommandEvent& event);
  void OnSize(wxSizeEvent& event);

protected:
  int       m_count;
  ...

  DECLARE_EVENT_TABLE()
};
Notez que cette macro peut être placée dans n'importe quelle section (publique, protégée ou privée) mais qu'il est probablement mieux de l'insérer à la fin, comme montré dans l'exemple, parce que cette macro change implicitement l'accès à "protégé" (protected) ce qui peut ne pas être voulu pour les éventuels événements qui la suivent.

Finalement, si vous n'aimez pas utiliser les macros pour l'initialisation statique des tables d'événements, vous pouvez utiliser wxEvtHandler::Connect pour connecter dynamiquement les événements aux gestionnaires, au moment de l'éxécution. Voyez l'exemple sur les événements pour voir la façon de le faire.


Comment sont traités les événements

Quand un événement est reçu depuis un système de fenêtrage, wxWidgets appelle wxEvtHandler::ProcessEvent sur le premier objet gestionnaire d'événements relatif à la fenêtre générant l'événement.

Vous pouvez noter que le système de traitement des événements wxWidgets implémente quelquechose de très similaire aux méthodes virtuelles en C++ classique, par exemple, il est possible de modifier le comportement d'une classe en surclassant ses fonctions de gestion des événements. Dans beaucoup de cas, cela marche également pour le comportement des contrôles natifs. Par exemple, il est possible de filtrer un certain nombre d'événements clavier envoyés par le système à un contrôle texte natif, en surclassant wxTextCtrl et en définissant un gestionnaire pour les événements claviers en utilisant EVT_KEY_DOWN. En effet, cela va éviter que les événements clavier soient envoyés au contrôle natif - ce qui peut ne pas être voulu. Dans ce cas, la fonction de gestion de l'événement doit appeler Skip() pour indiquer que la recherche du gestionnaire d'événements doit continuer.

Pour résumer, au lieu d'appeler explicitement la version de la classe de base comme vous l'auriez fait avec les fonctions virtuelles C++ (par exemple, wxTextCtrl::OnChar()), vous devriez appeler Skip.

Dans la pratique, voici à quoi cela ressemblerait si le contrôle texte dérivé n'accepte que les caractères 'a' à 'z' et 'A' à 'Z':

void MyTextCtrl::OnChar(wxKeyEvent& event)
{
    if ( isalpha( event.KeyCode() ) )
    {
       // le code de touche est dans la plage légale. nous pouvons appeler event.Skip() ainsi
       // l'événement sera traité par la classe de base wxWidgets
       // ou par le contrôle natif

       event.Skip();
    }
    else
    {
       // code de touche illégal. nous n'appelons pas event.Skip() ainsi
       // l'événement n'est pas traité autre part.

       wxBell();
    }
}
L'ordre normal de recherche de table d'événement par ProcessEvent est le suivant:

  1. Si l'objet est désactivé (par un appel à wxEvtHandler::SetEvtHandlerEnabled) la fonction passe directement à l'étape (6).
  2. Si l'objet est une wxWindow, ProcessEvent est appelé récursivement sur le wxValidator de la fenêtre. Si celui-ci retourne true, la fonction se termine.
  3. SearchEventTable est appelée pour ce gestionnaire d'événements. Si cette fonction échoue, la classe de base est essayée, et ainsi de suite jusqu'à ce que plus aucune table n'existe ou qu'une fonction appropriée soit trouvée, auquel cas, la fonction se termine.
  4. La recherche est appliquée en descendant sur toute la chaine des gestionnaires d'événements (habituellement la chaine a une longueur de 1). En cas de succès, la fonction se termine.
  5. Si l'objet est une wxWindow et que l'événement est prévu pour être propagé (dans la bibliothèque, seuls les événements basés sur wxCommandEvent sont faits pour être propagés), ProcessEvent est appliquée récursivement au gestionnaire d'événements de la fenêtre parente. Si celui-ci retourne true, la fonction se termine.
  6. Finalement, ProcessEvent est appelée sur l'objet wxApp.

Accordez une attention particulière à l'étape 5. Les gens ont tendance à ignorer ou à être induits en erreur par cette fonctionnalité puissante du système de traitement des événements wxWidgets. Pour le dire de manière différente, les événements destinés à être propagés voir: (wxEvent::ShouldPropagate) (le plus souvent dérivés directement ou indirectement de wxCommandEvent) vont remonter le confinement hiérarchique des enfants aux parents jusqu'à ce que le niveau de propagation maximal soit atteind, ou qu'un gestionnaire d'événement n'appelant pas event.Skip() soit trouvé.

Finalement, il y a une autre complication additionnelle (qui, en fait, simplifie de façon significative la vie des programmeurs wxWidgets): lors de la propagation des événements jusqu'à la fenêtre parente, cette propagation s'arrête quand elle atteind le dialogue parent, s'il y en a un. Cela signifie que vous ne risquez pas d'obtenir des événements imprévus depuis les contrôles dialogues (qui pourront être laissés non-traités par le dialogue lui-même s'il n'en n'a pas besoin) quand un dialogue modal est affiché. Toutefois, les événements se propagent à travers les frames. La raison de ce choix est qu'il n'y a que quelques frames dans une application typique et leurs relations parent-enfant sont bien comprises par le programmeur alors qu'il est très difficile, pour ne pas dire impossible, de retrouver tous les dialogues qui peuvent être affichés dans un programme complexe (rappelez-vous que certains sont créés automatiquement par wxWidgets). Si vous avez besoin de spécifier un comportement différent pour quelque raison que ce soit, vous pouvez utiliser SetExtraStyle(wxWS_EX_BLOCK_EVENTS) explicitement pour éviter que les événements soient propagés au delà l'une fenêtre donnée, ou désactiver cette option pour les dialogues qui l'ont par défaut.

En règle générale, les événements qui traitent avec une fenêtre comme une fenêtre (taille, déplacement, dessin, souris, clavier, etc.) sont envoyés seulement à la fenêtre. Les événements qui ont un niveau plus élevé et/ou qui sont générés par la fenêtre elle-même (clic sur un bouton, sélection de menu, extension d'arborescence, etc.) sont des événements de commande et sont remontés jusqu'au parent afin qu'il puisse éventuellement les traiter.

Notez que votre application peut nécessiter que vous surclassiez ProcessEvent pour rediriger le traitement des événements. Cela est fait dans le framework document/affichage, par exemple, pour permettre aux gestionnaires d'événements d'être définis dans le document ou dans la vue. Pour tester les événements de commande (qui seront probablement les seuls événements que vous voudrez rediriger), vous pouvez utiliser wxEvent::IsCommandEvent pour plus d'efficacité que de tester le système de type d'événement au moment de l'exécution.

Comme cela est mentionné ci-dessus, seuls les événements de commande sont appliqués récursivement aux gestionnaires d'événements des parents, dans la biblothèque elle-même. Comme cela est bien souvent source de confusion pour les utilisateurs, voici une liste des événements systèmes qui NE SERONT PAS envoyés au gestionnaire d'événements du parent:

wxEvent La classe événement de base
wxActivateEvent Un événement d'activation de l'application ou d'une fenêtre
wxCloseEvent Un événement de fermeture de fenêtre ou de fin de session
wxEraseEvent Un événement d'effacement de l'arrière-plan
wxFocusEvent Un événement focus
wxKeyEvent Un événement de touche pressée
wxIdleEvent Un événement idle
wxInitDialogEvent Un événement d'initialisation de boite de dialogue
wxJoystickEvent Un événement joystick
wxMenuEvent Un événement menu
wxMouseEvent Un événement souris
wxMoveEvent Un événement de déplacement
wxPaintEvent Un événement de dessin
wxQueryLayoutInfoEvent Utilisé pour obtenir une information de mise en page
wxSetCursorEvent Utilisé pour le traitement spécifique au curseur basé sur la position de la souris
wxSizeEvent Un événement de redimensionnement
wxScrollWinEvent Un événement de défilement envoyé par une fenêtre défilement (non par une barre de défilement)
wxSysColourChangedEvent Un événement de changement de couleur système

Dans certains cas, il peut être voulu par le programmeur d'obtenir un certain nombre d'événement systèmes dans une fenêtre parente, par exemple, tous les événements claviers envoyés à, mais non utilisés par, les contrôles natifs dans une boite de dialogue. Dans ce cas, un gestionnaire d'événements spécial devra être codé pour surclasser ProcessEvent() de façon à passer tous les événements (ou une certaine sélections d'entre eux) à la fenêtre parente.


Evénements générés par l'utilisateur par rapport aux événements générés par programmation

Bien que généralement les wxEvents peuvent être générés à la fois par des actions de l'utilisateur (par exemple, le redimensionnement d'une wxWindow) et par des appels à des fonctions (par exemple wxWindow::SetSize), les contrôles wxWidgets n'envoient normalement que des événements dérivés de wxCommandEvent pour les événements générés par l'utilisateur. Les seules exceptions à cette règle sont:

wxNotebook::AddPage Pas d'alternative sans événements
wxNotebook::AdvanceSelection Pas d'alternative sans événements
wxNotebook::DeletePage Pas d'alternative sans événements
wxNotebook::SetSelection Utilisez wxNotebook::ChangeSelection à la place car wxNotebook::SetSelection est dépréciée
wxTreeCtrl::Delete Pas d'alternative sans événements
wxTreeCtrl::DeleteAllItems Pas d'alternative sans événements
wxTreeCtrl::EditLabel Pas d'alternative sans événements
Toutes les méthodes wxTextCtrl wxTextCtrl::ChangeValue peut être utilisé à la place de wxTextCtrl::SetValue mais les autres fonctions, telles que Replace ou WriteText n'ont pas d'équivalent sans événement


Gestionnaires d'événements connectables

En fait, vous n'avez pas besoin de dériver une nouvelle classe depuis une classe de fenêtre si vous ne le voulez pas. Vous pouvez dériver une nouvelle classe depuis wxEvtHandler à la place, en définissant la table d'événements appropriés, et ensuite appeler wxWindow::SetEventHandler (ou, de préférence, wxWindow::PushEventHandler) pour faire de ce gestionnaire d'événements l'objet qui répondra aux événements. De cette façon, vous pourrez éviter un bon nombre de dérivation de classe, et utiliser des instances de la même classe de gestionnaire d'événements (mais différents objets comme même gestionnaire d'événements ne devraient pas être utilisés plus d'une fois) pour traiter les événements d'instances de différentes classes wxWidgets. Si vous devez appeler le gestionnaire d'événements d'une fenêtre manuellement, utilisez la fonction GetEventHandler pour retrouver le gestionnaire d'événements de la fenêtre, et utilisez le pour appeler la fonction membre. Par défaut, GetEventHandler retourne un pointeur vers la fenêtre elle-même tant qu'une application n'a pas redirigé le traitement des événements avec SetEventHandler ou PushEventHandler.

Une utilisation de PushEventHandler est de changer temporairement ou de façon permanente le comportement de l'interface utilisateur. Par exemple, vous pouvez vouloir invoquer un éditeur de dialogue dans votre application qui change l'aspect des boites de dialogue. Vous pouvez capturer toutes les entrées d'une boite de dialogue existante, et la modifier 'en live', avant de restaurer son comportement normal. Ainsi, même si l'application a de nouvelles classes dérivées pour personnaliser le comportement, votre utilitaire peut Section non traduite:indulge in a spot of body-snatching. Cela peut-être également une technique utile pour des tutoriaux en ligne, où vous emmenez l'utilisateur à travers une série d'étapes et que vous ne voulez pas qu'il s'écarte du cours. Dans ce cas, vous pouvez examiner les événements venant des boutons et des fenêtres, et s'ils sont acceptables, les transférer au gestionnaire d'événements d'origine. Utilisez PushEventHandler/PopEventHandler pour former une chaine de gestionnaire d'événements, où chaque gestionnaire traite une gamme différente d'événements, indépendament des autres gestionnaires.


Identifiants des fenêtres

Les identifiants des fenêtres sont des entiers, et sont utilisés uniquement pour déterminer l'identité d'une fenêtre dans le système d'événements (mais vous pouvez les utiliser à d'autres fins). En fait, les identifiants n'ont pas besoin d'être uniques à travers une application entière, tant qu'ils sont uniques au sein d'un contexte particulier qui vous intéresse, tel qu'une frame et ses enfants. Vous pouvez utiliser l'identifiant wxID_OK, par exemple, sur plusieurs dialogues, tant que vous ne l'utilisez pas plusieurs fois sur le même dialogue.

Si vous passez wxID_ANY au constructeur d'une fenêtre, un identifiant sera automatiquement généré pour vous par wxWidgets. Cela est utile quand vous ne vous souciez pas de l'identifiant exact parce que vous n'allez pas traiter les événements depuis le contrôle lui-même, ou parce que vous traitez les événements de tous les contrôles au même endroit (dans ce cas, vous devriez spécifier wxID_ANY dans la table des événements ou appelerwxEvtHandler::Connect. Les identifiants générés automatiquement sont toujours négatifs et de ce fait n'entreront jamais en conflit avec les identifiants spécifiés par l'utilisateur qui doivent toujours être positifs.

LEs identifiants standards suivants sont fournis. Vous pouvez utiliser wxID_HIGHEST pour déterminer le numéro à partir duquel il est sûr de définir vos propres identifiants. Vous pouvez également utliser des identifiants inférieurs à wxID_LOWEST.

#define wxID_ANY                -1

#define wxID_LOWEST             4999

#define wxID_OPEN               5000
#define wxID_CLOSE              5001
#define wxID_NEW                5002
#define wxID_SAVE               5003
#define wxID_SAVEAS             5004
#define wxID_REVERT             5005
#define wxID_EXIT               5006
#define wxID_UNDO               5007
#define wxID_REDO               5008
#define wxID_HELP               5009
#define wxID_PRINT              5010
#define wxID_PRINT_SETUP        5011
#define wxID_PREVIEW            5012
#define wxID_ABOUT              5013
#define wxID_HELP_CONTENTS      5014
#define wxID_HELP_COMMANDS      5015
#define wxID_HELP_PROCEDURES    5016
#define wxID_HELP_CONTEXT       5017

#define wxID_CUT                5030
#define wxID_COPY               5031
#define wxID_PASTE              5032
#define wxID_CLEAR              5033
#define wxID_FIND               5034
#define wxID_DUPLICATE          5035
#define wxID_SELECTALL          5036
#define wxID_DELETE             5037
#define wxID_REPLACE            5038
#define wxID_REPLACE_ALL        5039
#define wxID_PROPERTIES         5040

#define wxID_VIEW_DETAILS       5041
#define wxID_VIEW_LARGEICONS    5042
#define wxID_VIEW_SMALLICONS    5043
#define wxID_VIEW_LIST          5044
#define wxID_VIEW_SORTDATE      5045
#define wxID_VIEW_SORTNAME      5046
#define wxID_VIEW_SORTSIZE      5047
#define wxID_VIEW_SORTTYPE      5048

#define wxID_FILE1              5050
#define wxID_FILE2              5051
#define wxID_FILE3              5052
#define wxID_FILE4              5053
#define wxID_FILE5              5054
#define wxID_FILE6              5055
#define wxID_FILE7              5056
#define wxID_FILE8              5057
#define wxID_FILE9              5058

#define wxID_OK                 5100
#define wxID_CANCEL             5101
#define wxID_APPLY              5102
#define wxID_YES                5103
#define wxID_NO                 5104
#define wxID_STATIC             5105

#define wxID_HIGHEST            5999

Sommaire des macros d'événements

Macros listées par classe d'événement

La documentation pour les macros spécifiques aux événements est organisée par classe d'événements. Merci de vous référer à ces sections pour plus de détails.

wxActivateEvent Les macros EVT_ACTIVATE et EVT_ACTIVATE_APP interceptent les événements d'activation et de désactivation.
wxCommandEvent Une gamme d'événements pour les contrôles utilisés couramment.
wxCloseEvent La macro EVT_CLOSE traite la fermeture d'une fenêtre demandée par wxWindow::Close.
wxDropFilesEvent La macro EVT_DROP_FILES traite les événements de dépose de fichiers par glisser/déplacer.
wxEraseEvent La macro EVT_ERASE_BACKGROUND est utilisée pour traiter les requêtes d'affacement de fenêtre.
wxFocusEvent Les macros EVT_SET_FOCUS et EVT_KILL_FOCUS sont utilisées pour traiter les événements de focus depuis le clavier.
wxKeyEvent Les macros EVT_CHAR, EVT_KEY_DOWN et EVT_KEY_UP traitent les entrées clavier pour toutes les fenêtres.
wxIdleEvent La macro EVT_IDLE traitent les événements idle d'une application, c'est à dire, quand celle-ci est au repos (pour traiter les tâches d'arrière-plan, par exemple).
wxInitDialogEvent La macro EVt_INIT_DIALOG est utilisée pour gérer l'initialisation d'une boite de dialogue.
wxListEvent Ces macros gèrent les événements relatifs au contrôle wxListCtrl.
wxMenuEvent Ces macros gèrent les événements spéciaux pour les menus (et non les commandes de menus).
wxMouseEvent Les macros d'événements de souris peuvent gérer les événements souris individuels, aussi bien que tous les événements souris.
wxMoveEvent La macro EVT_MOVE est utilisée pour gérer le déplacement d'une fenêtre.
wxPaintEvent La macro EVT_PAINT est utlilisée pour gérér les requêtes de dessin d'une fenêtre.
wxScrollEvent Ces macros sont utilisées pour gérer les événements de défilement depuis les contrôles wxScrollBar, wxSlider,et wxSpinButton.
wxSetCursorEvent La macro EVT_SET_CURSOR est utilisée pour le traitement spécifique relatif au curseur.
wxSizeEvent La macro EVT_SIZE est utilisée pour gérer le redimensionnement d'une fenêtre.
wxSplitterEvent Les macros EVT_SPLITTER_SASH_POS_CHANGED, EVT_SPLITTER_UNSPLIT et EVT_SPLITTER_DCLICK sont utilisées pour gérer les différents événements des séparateurs de fenêtres.
wxSysColourChangedEvent La macro EVT_SYS_COLOUR_CHANGED est utilisée pour gérer les événements informant l'application que l'utilisateur a changé les couleurs du système (Windows uniquement).
wxTreeEvent Ces macros gèrent les événements relatifs au contrôle wxTreeCtrl.
wxUpdateUIEvent La macro EVT_UPDATE_UI est utilisée pour gérer les pseudos-événements demise à jour de l'interface utilisateur, qui sont générés pour donner à l'application une chance de mettre à jour l'état visule des menus, des barres d'outils et des contrôles.


Sommaire des événements personnalisés

Approche générale

Depuis la version 2.2.x de wxWidgets, chaque type d'événement est identifié par un ID qui est donné au type d'événement au moment de l'éxécution, ce qui rend possible l'ajout de nouveaux types d'événements à la bibliothèque ou à l'application sans risque de conflit d'ID (deux types d'événements différents ayant le même ID). Cet ID de type d'événement est stocké dans une structure de type const wxEventType.

Pour définir un nouveau type d'événement, il existe deux possibilités. La première est de définir entièrement une nouvelle classe d'événement (dérivée de wxEvent ou wxCommandEvent). L'autre est d'utiliser les classes d'événement existantes et de leur donner un nouveau type d'événement. Quelque soit le choix que vous ferez, vous aurez à définir et à déclarer un nouveau type d'événement, et ceci se fait en utilisant les macros suivantes:

// Dans le fichier en-tête
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(name, value)
END_DECLARE_EVENT_TYPES()

// Dans le fichier d'implémentation
DEFINE_EVENT_TYPE(name)
Vous pouvez ignorer le paramètre value de la macro DECLARE_EVENT_TYPE car il n'est utilisé que pour la compatibilité descendante avec les applications basées sur wxWIdgets 2.0.x où vous devez donner à l'ID de type d'événement une valeur explicite.

Voyez aussi l'exemple sur les événements pour un exemple de code définissant et travaillant avec les types d'événements personnalisés.

Utiliser les classes d'événements existantes

Si vous avez juste besoin d'un wxCommandEvent avec un nouveau type d'événement, vous pouvez alors utiliser l'une des macros génériques de table d'événements listées ci-dessous, sans avoir à définir une nouvelle macro vous-même. Cela a également l'avantage que vous n'avez pas a définir une nouvelle méthode wxEvent::Clone() pour poster des événements entre les threads, etc. Cela pourrait ressembler à cela dans votre code:

DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)

DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)

// user code intercepting the event

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  // ....
  EVT_COMMAND  (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
END_EVENT_TABLE()

void MyFrame::OnMyEvent( wxCommandEvent &event )
{
    // do something
    wxString text = event.GetText();
}


// user code sending the event

void MyWindow::SendEvent()
{
    wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
    event.SetEventObject( this );
    // Give it some contents
    event.SetText( wxT("Hallo") );
    // Send it
    GetEventHandler()->ProcessEvent( event );
}
Macros génériques de table d'événements

EVT_CUSTOM(event, id, func) Vous permet d'ajouter une entrée personnalisée dans la table des événements en spécifiant l'identifiant de l'événement (tel que wxEVT_SIZE), l'identifiant de la fenêtre, et la fonction membre à appeler.
EVT_CUSTOM_RANGE(event, id1, id2, func) Comme EVT_CUSTOM, mais répond à une plage d'identifiants de fenêtre.
EVT_COMMAND(id, event, func) Comme EVT_CUSTOM, mais demande une fonction membre ayant pour argument un wxCommandEvent.
EVT_COMMAND_RANGE(id1, id2, event, func) Comme EVT_CUSTOM_RANGE, mais demande une fonction membre ayant pour argument un wxCommandEvent.
EVT_NOTIFY(event, id, func) Comme EVT_CUSTOM, mais demande une fonction membre ayant pour argument un wxNotifyEvent.
EVT_NOTIFY_RANGE(event, id1, id2, func) Comme EVT_CUSTOM_RANGE, mais demande une fonction membre ayant pour argument un wxNotifyEvent..

Définir votre propre classe d'événements

Sous certaines circonstances, il vous faudra définir votre propre classe d'événement, par exemple, pour envoyer des données plus complexes d'un endroit à un autre. En plus de définir votre classe d'événement, vous devrez définir votre propre macro de table d'événement (qui est relativement longue). Assurez-vous de mettre suffisament de cast pour la fonction événement héritée. Voici un exemple, pris dans la bibliothèque wxPlot, qui est dans la section contrib des sources wxWidgets.

// code defining event

class wxPlotEvent: public wxNotifyEvent
{
public:
    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );

    // accessors
    wxPlotCurve *GetCurve()
        { return m_curve; }

    // required for sending with wxPostEvent()
    wxEvent* Clone();

private:
    wxPlotCurve   *m_curve;
};

DECLARE_EVENT_TYPE( wxEVT_PLOT_ACTION, -1 )

typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);

#define EVT_PLOT(id, fn) \
    DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
    wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ),


// code implementing the event type and the event class

DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )

wxPlotEvent::wxPlotEvent( ...


// user code intercepting the event

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_PLOT  (ID_MY_WINDOW,  MyFrame::OnPlot)
END_EVENT_TABLE()

void MyFrame::OnPlot( wxPlotEvent &event )
{
    wxPlotCurve *curve = event.GetCurve();
}


// user code sending the event

void MyWindow::SendEvent()
{
    wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
    event.SetEventObject( this );
    event.SetCurve( m_curve );
    GetEventHandler()->ProcessEvent( event );
}