IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Le Fox Toolkit


précédentsommairesuivant

II. La gestion des évènements

Pour rendre notre application dynamique, il est possible (et heureusement) d'associer des méthodes à des évènements.

II-A. Principe de communication entre les objets

Chaque objet interactif possède un pointeur vers l'objet auquel il doit envoyer ses messages. L'objet qui reçoit les messages connait les associations messages / méthodes, il peut donc appeler les fonctions correspondantes lorsqu'il reçoit des messages. Chaque type de message possède un identifiant ainsi qu'une correspondance avec un évènement. Donc, quand un objet reçoit un message, il en connait l'identifiant ainsi que l'évènement qui a généré le message.

La liste des associations entre messages et méthodes est définie par la macro FXDEFMAP. Mais c'est au programmeur de renseigner cette macro de la manière suivante :

 
Sélectionnez
FXDEFMAP(NotreWindow) NotreWindowMap[]={
                     //___Type du message________Identifiant________Méthode__________
                     FXMAPFUNC(SEL_COMMAND , NotreWindow::ID_NEW , NotreWindow::fct1),
                     FXMAPFUNC(SEL_MINIMIZE, NotreWindow::ID_END , NotreWindow::fct2),
                     FXMAPFUNC(SEL_COMMAND , NotreWindow::ID_FOX , NotreWindow::fct3),
                     FXMAPFUNC(SEL_MAXIMIZE, NotreWindow::ID_TOTO, NotreWindow::fct2),
                     [...]
                     FXMAPFUNC(SEL_MOTION  , NotreWindow::ID_TATA, NotreWindow::fct4)
                     };

Vous pouvez trouver la liste des types des messages ici.

Une fois la liste établie, il faut appeler la seconde macro qui permet d'implémenter notre liste d'associations :

 
Sélectionnez
FXIMPLEMENT(NotreWindow,FXMainWindow,NotreWindowMap,ARRAYNUMBER(NotreWindowMap))

Reste maintenant à informer la classe NotreWindow de l'existence de ces types de messages, en rajoutant un type énuméré en attribut de classe ainsi que les prototypes des fonctions associées.

 
Sélectionnez
class NotreWindow: public FXMainWindow{
 FXDECLARE(NotreWindow);
 private:
    ...
 public:
    ...
    enum{
      ID_ZERO,
      ID_NEW,
      ID_END,
      ID_FOX,
      ID_TOTO,
      ID_TATA
      };
       
    long fct1(FXObject*,FXSelector,void*);
    long fct2(FXObject*,FXSelector,void*);
    long fct3(FXObject*,FXSelector,void*);
    long fct4(FXObject*,FXSelector,void*);
 };

Les fonctions à appeler lors d'un évènement ont toujours le prototype suivant :

 
Sélectionnez
long nom_fct(FXObject*,FXSelector,void*);

où FXObject* est un pointeur sur l'objet qui a émis le message, FXSelector est le type du message et void* est un pointeur sur une structure représentant l'évènement qui a amené l'émission du message.

Vous en mourez d'envie, voici un petit exemple pour illustrer l'utilisation des évènements. Implémentons un label dont le texte change au clic sur un bouton.

NotreWindow.h
Sélectionnez
#ifndef __NotreWindow_h__ 
 #define __NotreWindow_h__ 
 
 class NotreWindow : public FXMainWindow { 
    FXDECLARE(NotreWindow); 
    private: 
        NotreWindow(){} 
        FXLabel *lab; 
        FXButton *b1,*b2; 
    public: 
        NotreWindow(FXApp *); 
        void create(); 
        enum{ 
            ID_ZERO, 
            ID_CHANG, 
            ID_DEVEL 
            };
         
        long onChangez(FXObject*,FXSelector,void*); 
        long onDeveloppez(FXObject*,FXSelector,void*); 
 }; 
 
 #endif
NotreWindow.cpp
Sélectionnez
#include <fox/fx.h>
 #include "NotreWindow.h"
 
 FXDEFMAP(NotreWindow) NotreWindowMap[]={
                   FXMAPFUNC(SEL_COMMAND, NotreWindow::ID_CHANG   , NotreWindow::onChangez),
                   FXMAPFUNC(SEL_COMMAND, NotreWindow::ID_DEVEL   , NotreWindow::onDeveloppez)
                   };
 FXIMPLEMENT(NotreWindow,FXMainWindow,NotreWindowMap,ARRAYNUMBER(NotreWindowMap))
 
 NotreWindow::NotreWindow(FXApp *a):FXMainWindow(a,"Ma fenêtre FOX",NULL,NULL,DECOR_ALL,50,100,250,80){
     int buttonStyle = FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT;
      
     lab=new FXLabel(  this, "hello world",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X );
     b1 =new FXButton( this, "Changez"    ,NULL,this,ID_CHANG,buttonStyle,0,0,0,0,10,10,5,5);
     b2 =new FXButton( this, "Developpez" ,NULL,this,ID_DEVEL,buttonStyle,0,0,0,0,10,10,5,5);
 }
  
 void NotreWindow::create(){
   FXMainWindow::create();
 
   show(PLACEMENT_VISIBLE);
 }
   
 long NotreWindow::onDeveloppez(FXObject*,FXSelector,void*){
     lab->setText("developpez");
     return 0;
 }
 
 long NotreWindow::onChangez(FXObject*,FXSelector,void*){
     lab->setText("changez");
     return 0;
 }

II-B. Explications du code

J'ai déclaré deux pointeurs sur des boutons (FXButton), créés dans le constructeur public de notre classe. On remarquera la présence du premier argument this qui définit l'objet graphique contenant notre bouton. Le second argument positionné à this correspond à un pointeur sur l'objet à qui envoyer les messages, et dans notre cas, nous envoyons les messages à la fenêtre. On remarquera aussi les arguments ID_CHANG et ID_DEVEL décrivant le type des messages que les boutons émettront.

Comme la fenêtre sera amenée à recevoir des messages, elle doit connaitre les associations entre les messages et les fonctions à appeler, ceci est fait via la macro FXDEFMAP :

 
Sélectionnez
FXMAPFUNC(SEL_COMMAND, NotreWindow::ID_CHANG   , NotreWindow::onChangez),
 FXMAPFUNC(SEL_COMMAND, NotreWindow::ID_DEVEL   , NotreWindow::onDeveloppez)

Pour éviter les erreurs de résolution de symbole et les références indéfinies, il ne faut pas oublier de créer les méthodes onChangez et onDeveloppez :

 
Sélectionnez
long NotreWindow::onDeveloppez(FXObject*,FXSelector,void*){
     lab->setText("developpez");
     return 0;
 }
 
 long NotreWindow::onChangez(FXObject*,FXSelector,void*){
     lab->setText("changez");
     return 0;
 }

ainsi que les types de messages ID_CHANG et ID_DEVEL :

 
Sélectionnez
class NotreWindow : public FXMainWindow {
     ...
  public:
     ...
  enum{
     ID_ZERO,
     ID_CHANG,
     ID_DEVEL
    };
     ...
 };

Attention à ne pas oublier de déclarer un premier item non utilisé pour le type énuméré. En effet, le premier item est géré comme étant 0, valeur ne convenant pas pour les message Fox. En ne déclarant pas le premier item, vous prenez le risque d'obtenir des comportements indéfinis.


précédentsommairesuivant

Copyright © 2005 khayyam Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.