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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Modifier l'évènement d'un composant [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Modifier l'évènement d'un composant
    Bonjour,

    Dans un TmySpeedButton hérité d'un TSpeedButton, je voudrais modifier le comportement de l'évènement OnMouseEnter.

    Je crée un TmySpeedButton dont j'aimerais que l'évènement MouseOver soit éludé : Par exemple, qu'il affiche "d'abord" showmessage('interne');.

    Donc un survol de mySpeedButton1 avec dans la Form
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TForm1.mySpeedButton1MouseEnter(Sender: TObject);
    begin
      showmessage('externe');
    end;
    afficherait d'abord 'interne' (modification de OnMouseEnter) puis ensuite 'externe' (code dans l'inpecteur d'objet).

    Actuellement je crée une procedure DoMouseEnter(const Value: TNotifyEvent); virtual; (protected)
    Mais comment je la relie à l'évènement d'origine ? J'ai essayé quelque chose dans ce genre là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    type
      TmySpeedButton = class(TSpeedButton)
      private                       
      { Private declarations }
       FOnMouseEnter: TNotifyEvent;
       protected
        { Protected declarations }
        procedure SetOnMouseEnter(const Value: TNotifyEvent);
        procedure DoMouseEnter(const Value: TNotifyEvent); virtual;
      published
        { Published declarations }
        property OnMouseEnter: TNotifyEvent read FOnMouseEnter write SetOnMouseEnter;
       //Au départ "naïvement" property OnMouseEnter: TNotifyEvent read FOnMouseEnter write DoMouseEnter;
      end;
    Si cette base déclarative est bonne (faut-il redéclarer le FOnMouseEnter: TNotifyEvent; et dans le cas contraire ?), comment relie-t-on alors les évènements ?

    Cordialement. Gilles
    Dernière modification par Invité ; 29/09/2010 à 12h48.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Alors, par recoupement de sources Web et par tâtonnements, j'ai obtenu un code qui fonctionne... mais est-il correct ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    type
      TMySpeedButton = class(TSpeedButton)
      private
      { Private declarations }
        FOnMouseEnter: TNotifyEvent;                         
        procedure SelfOnMouseEnter (Sender : TObject);   // [procédure de substitution ou complémentaire]
        protected
        { Protected declarations }
       public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
       published
        { Published declarations }
        property OnMouseEnter : TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    end;
     
    procedure Register;
     
    implementation
     
    procedure Register;
    begin
      RegisterComponents('Additional',[TmySpeedButton]);
    end;
     
    constructor Tmyspeedbutton.Create(AOwner: TComponent);
    begin
        Inherited Create(AOwner);
        FOnMouseEnter := nil;
        Inherited OnMouseEnter := @SelfOnMouseEnter;
    end;
     
    destructor Tmyspeedbutton.Destroy;
    begin
        Inherited Destroy;
    end;
     
    //----------------------------------------------------------
    procedure Tmyspeedbutton.SelfOnMouseEnter(Sender : TObject);
    begin
     Showmessage('Interne');
     //Si code de l'utilisateur dans événement OnMouseOver, alors le déclencher...
     if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender);
     //Cette dernière ligne est à éliminer s'il s'agit d'un code de remplacement et 
     //non d'un code complémentaire précédant ou suivant le code de l'utilisateur
    end;
    Cordialement. Gilles
    Dernière modification par Invité ; 29/09/2010 à 14h32.

  3. #3
    Membre émérite
    Avatar de chris37
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juillet 2007
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 378
    Par défaut
    Hello,

    Dans la déclaration des procédures de ta classe
    procedure DoMouseEnter(const value: TNotifyEvent);Override;
    Ensuite tu déclares ta procédure dans ta classe
    procedure maclasse.DoMouseEnter(const value: TNotifyEvent);
    begin
    //Ici tu appels le code que tu veux (ton perso)
    Ma procedure();

    //Là tu appels l'événement de la classe ancêtre apres l'exécution de TON code )
    inherited DoMouseEnter(value);
    end;
    Voila le principe

    Cordialement,
    Chris

  4. #4
    Invité
    Invité(e)
    Par défaut
    Question complémentaire : Je veux stocker le glyph d'origine dans une variable du composant pour la rappeler ultérieurement.

    Donc cela se présenterait ainsi au niveau déclaratif comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    type
      TMySpeedButton = class(TSpeedButton)
      private
      { Private declarations }
        FBitmapOld : TBitMap;
        [...]
    Je pensais la "fixer" dans le create :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    constructor TMYSpeedbutton.Create(AOwner: TComponent);
    begin
        Inherited Create(AOwner);
        FBitmapOld := TBitmap.Create; 
       //et...
       fBitmapOld.Assign(glyph); //*
      [...]
    * Le glyph est celui par défaut du composant (ie le champ Glyph dans son inspecteur d'objet) . Même s'il est défini dans ce dernier par l'utilisateur, est-il disponible à ce moment du code lors de la compilation ?

    Pour l'appeler, je procède ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TMySpeedbutton.SelfOnMouseLeave(Sender : TObject);
    begin
      Self.Glyph := fBitmapOld;  
      [...]
    Et cela ne fonctionne pas... J'alterne 2 glyphs : un dans l'évènement OnMouseEnter et l'autre dans OnMouseLeave. J'ai défini un glyp additionnel dans le code pour le OnMouseEnter... Le résultat est que lors du survol le Glyph d'origine est bien remplacé par le glyph de survol... mais après au mieux, j'obtiens lors du "Leave" un glyph vide alors que je voudrais que cela soit celui d'origine... Donc la question est : Est-ce le chargement du glyph d'origine qui est mauvais... ou son appel (ou les 2 ) ?

    Et toujours ce même problème très désagréable. Comment désactiver une propriété (pas un évènement).
    Par exemple, l'aspect des TspeedButtons ne me plait pas lorsque SpeedButton.Enabled := false;
    On peut assez facilement bloquer le Enabled à true, créer une propriété Enabled2 et gérer l'aspect du TSpeedButton à partir de Enabled :=True et de la valeur de Enabled2... Mais c'est très désagréable...

    Merci. Gilles
    Dernière modification par Invité ; 29/09/2010 à 18h49.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 64
    Par défaut
    Pourrais-tu nous montrer le code complet du constructeur
    "constructor TMYSpeedbutton.Create(AOwner: TComponent);" ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonsoir Yann.m,

    voici l'unit complète... Elle fonctionne correctement, du moins de manière analogue à ce que je produis normalement en code "Form". Il y manque simplement la gestion de l'équivalent d'Enabled := False... qui modifiera sensiblement les procédures SelfOnMousexxxx... mais simplement. Au lieu d'implanter un code complémentaire dans la procédure modifiée, je placerai un code de remplacement (ie se substituant totalement à la procédure d'origine) :
    cf dans le code //Cette dernière ligne est à éliminer s'il s'agit d'un code de remplacement et non d'un code complémentaire précédant ou suivant le code de l'utilisateur.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    unit mySpeedButton;
    //Vers. 10.09.29.18.54
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons;
     
    type
      TmySpeedButton = class(TSpeedButton)
      private
      { Private declarations }
        FBitmapOver: TBitmap;
        FBitmapOut: TBitmap;
        FBitmapSelected: TBitmap;
     
        FNumGlyphs : Integer;
     
        // Modification des événements........................................... [partie 1]
        FOnMouseEnter: TNotifyEvent;
        FOnMouseLeave: TNotifyEvent;
        FOnMouseDown : TNotifyEvent;
        FOnMouseUp   : TNotifyEvent;
        FOnResize    : TNotifyEvent;
     
        // Modification des évènements............................... [partie 1-bis]
        procedure SelfOnMouseEnter (Sender : TObject); //procedure complémentaire
        procedure SelfOnMouseLeave (Sender : TObject); //       idem
        procedure SelfOnResize (Sender : TObject);     //       idem
        procedure SelfOnMouseDown (Sender: TObject;Button: TMouseButton;
                  Shift: TShiftState; X, Y: Integer);
        procedure SelfOnMouseUp (Sender: TObject; Button: TMouseButton;
                  Shift: TShiftState; X, Y: Integer);
     
        // Autres procedures : affectation des valeurs (dont blocage de NumGlyphs)
        procedure SetNumGlyphs(Value : Integer);
        procedure SetBitmapOver(Value: TBitmap);
        procedure SetBitmapOut(Value: TBitmap);
        procedure SetBitmapSelected(Value: TBitmap);
     
      protected
        { Protected declarations }
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        { Published declarations }
        property GlyphOver: TBitmap Read FBitmapOver Write SetBitmapOver;
        property GlyphOut: TBitmap Read FBitmapOut Write SetBitmapOut;
        property GlyphSelected:TBitmap Read FBitmapSelected Write SetBitmapSelected;
        property NumGlyphs : integer read FNumGlyphs write SetNumGlyphs;
     
        // Modification des évènements .................................. [partie 2]
        property OnMouseEnter : TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
        property OnMouseLeave : TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
        property OnResize : TNotifyEvent read FOnResize write FOnResize;
        property OnMouseDown : TNotifyEvent read FOnMouseDown write FOnMouseDown;
        property OnMouseUp : TNotifyEvent read FOnMouseUp write FOnMouseUp;
     
    end;
     
    procedure Register;
     
    implementation
     
    procedure Register;
    begin
      RegisterComponents('Additional',[TmySpeedButton]);
    end;
     
    constructor Tmyspeedbutton.Create(AOwner: TComponent);
    begin
        Inherited Create(AOwner);
        FBitmapOut  := TBitmap.Create;
        FBitmapOver := TBitmap.Create;
        FBitmapSelected := TBitmap.Create;
        FNumGlyphs  := 1;
        // Modification des évènements .................................. [partie 3]
        FOnMouseEnter := nil;
        Inherited OnMouseEnter := @SelfOnMouseEnter;
        FOnMouseLeave := nil;
        Inherited OnMouseLeave := @SelfOnMouseLeave;
        FOnResize := nil;
        Inherited OnResize := @SelfOnResize;
        FOnMouseDown := nil;
        Inherited OnMouseDown := @SelfOnMouseDown;
        FOnMouseUp := nil;
        Inherited OnMouseUp := @SelfOnMouseUp;
    end;
     
    destructor Tmyspeedbutton.Destroy;
    begin
      FBitmapSelected.Free;
      FBitmapOver.Free;
      FBitmapOut.Free;
      inherited Destroy;
    end;
     
    // Modification des évènements .................................. [partie 4]
    procedure Tmyspeedbutton.SelfOnMouseEnter(Sender : TObject);
    begin
      Self.Glyph := FBitmapOver;
      //Si code OnMouseEnter alors l'exécuter
      if Assigned(FOnMouseEnter) then FOnMouseEnter(Sender);
      //Cette dernière ligne est à éliminer s'il s'agit d'un code de remplacement et
      //non d'un code complémentaire précédant ou suivant le code de l'utilisateur.
    end;
     
    procedure Tmyspeedbutton.SelfOnMouseLeave(Sender : TObject);
    begin
      Self.Glyph := FBitmapOut;
      if Assigned(FOnMouseLeave) then FOnMouseLeave(Sender);
    end;
     
    procedure Tmyspeedbutton.SelfOnResize(Sender : TObject);
    begin
      Self.Glyph := FBitmapOut;
      if Assigned(FOnResize) then FOnResize(Sender);
    end;
     
    procedure Tmyspeedbutton.SelfOnMouseDown(Sender: TObject;Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    begin
      if Button <> mbLeft then
       inherited
      else begin
       Self.Glyph := FBitmapSelected;
       if Assigned(FOnMouseDown) then FOnMouseDown(Sender);
      end;
    end;
     
    procedure Tmyspeedbutton.SelfOnMouseUp(Sender: TObject;Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    begin
      if Button <> mbLeft then
       inherited
      else begin
       if (X > 0) and (X < Self.Width) and (Y > 0) and (Y < Self.Height) then
        Self.Glyph := FBitmapOver
       else
        Self.Glyph := FBitmapOut;
        if Assigned(FOnMouseUp) then FOnMouseUp(Sender);
      end;
    end; 
     
    // Autres procedures : affectation des valeurs (dont blocage de NumGlyphs)
    procedure Tmyspeedbutton.SetNumGlyphs(Value : Integer);
    begin
     value := 1;
    end; 
     
    procedure Tmyspeedbutton.SetBitmapOver(Value: TBitmap);
    begin
     FBitmapOver.Assign(value);
     invalidate;
    end;
     
    procedure Tmyspeedbutton.SetBitmapOut(Value: TBitmap);
    begin
     FBitmapOut.Assign(value);
     invalidate;
    end;
     
    procedure Tmyspeedbutton.SetBitmapSelected(Value: TBitmap);
    begin
     FBitmapSelected.Assign(value);
     invalidate;
    end;
     
    end.
    C'est un TspeedButton 4 états [4 glyphs] : 1 out, 1 over, 1 selected, 1 disabled. J'aurais bien aimé utiliser le glyph d'origine qui aurait remplacé avantageusement (peut-être ?) le FBitmapOut... qui fait double emploi. Je n'arrive pas à "charger" le "glyph d'origine" sachant que pour initialiser mon SpeedButton dans mon code usuel hors composant, j'utilise également l'évènement onResize.

    D'un autre côté, je n'utilise pas la propriété Enabled... et ses effets secondaires. Si je comprends bien qu'il n'est pas envisageable de supprimer la propriété de l'objet compte-tenu de sa présence dans le code des ancêtres, je déplore qu'il n'existe pas la possibilité de la rétrograder en protected... ou voire même en published mais sans write...

    Evidemment, il y a des codes inutiles (genre uses Dialogs...) et des manques notamment vérifier la largeur des images sélectionnées.

    Je dois avouer que si ce code fonctionne, je n'ai aucune certitude quant à son orthodoxie ou même à son niveau de qualité...

    Cordialement. Gilles
    Dernière modification par Invité ; 29/09/2010 à 19h49.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 64
    Par défaut
    C'est fonctionnel (au niveau visuel) pour moi sous mac

    Par contre il y a un problème de logique avec les glyph:

    GlyphOut devrait être suprimé !
    Glyph = bouton enabled avec bmp par défaut
    GlypOver = survol souris -> bmp survol souris
    GlyphOut = hum, en fait là on devrait avoir Glyph (bmp par défaut puisque retour à l'état par défaut)

    J'ai codé l'appel de ton composant et les propriétés comme suis (à la va-vite et avec des bitmaps carrés de couleurs différentes - ce qui explique le transparent=false) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
     
    unit Unit1; 
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      ...
     mySpeedButton;
     
    type
     
      { TForm1 }
     
      TForm1 = class(TForm)
          msb: TMySpeedButton;
          procedure FormCreate(Sender: TObject);
      private
        { private declarations }
      public
        { public declarations }
      end; 
     
    var
      Form1: TForm1; 
     
    implementation
     
    { TForm1 }
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
        msb := TMySpeedButton.Create(Self);
        msb.Transparent := False;
        msb.Glyph.LoadFromFile('/Users/yann/Desktop/test/1.bmp');
        msb.GlyphOver.LoadFromFile('/Users/yann/Desktop/test/2.bmp');
        msb.GlyphOut.LoadFromFile('/Users/yann/Desktop/test/3.bmp');
        msb.GlyphSelected.LoadFromFile('/Users/yann/Desktop/test/4.bmp');
        msb.Parent := Self;
    end;
    Je pense que tu es au courant que le premier pixel (haut, gauche) d'un Glyphe est déclaré "couleur transparente" lorsque la propriété Transparent := True;

    Essaie ce code avec tes chemins de bitmap pour vérifier.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SWING] Modifier l'apparence de certains composants
    Par rprom1 dans le forum AWT/Swing
    Réponses: 14
    Dernier message: 21/06/2006, 19h41
  2. Comment est géré l'événement OnTime du Composant TTimer?
    Par Arnaud-h dans le forum C++Builder
    Réponses: 3
    Dernier message: 02/06/2004, 17h10
  3. Réponses: 4
    Dernier message: 27/05/2004, 15h00
  4. Modifier un événement dans le code
    Par HT dans le forum Langage
    Réponses: 6
    Dernier message: 20/06/2003, 09h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo