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

Langage Delphi Discussion :

Événement et anonyme


Sujet :

Langage Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut Événement et anonyme
    Bonjour

    La documentation Embarcadero dit ceci:

    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
     
    type
      TProc = reference to procedure;
      TMyComponent = class(TComponent)
      private
        FMyEvent: TProc;
      public
        // MyEvent property serves as an event:
        property MyEvent: TProc read FMyEvent write FMyEvent;
        // some other code invokes FMyEvent as usual pattern for events
      end;
     
    ...
     
    var
      c: TMyComponent;
    begin
      c := TMyComponent.Create(Self);
      c.MyEvent := procedure
      begin
        ShowMessage('Hello World!'); // shown when TMyComponent invokes MyEvent
      end;
    end;
    Sur le principe, pas de problème ! Sauf que ça impose de définir TProc !

    Mais si on veut faire de même avec un événement de type TNotifyEvent, impossible !

    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
     
      TFirstClass = class
      private
        FOnTest: TNotifyEvent;
      published
        property OnTest: TNotifyEvent read FOnTest write FOnTest;
      end;
     
    ..
    var
      FirstClass: TFirstClass;
    begin
      FirstClass := TFirstClass.Create;
      FirstClass.OnTest := procedure (Sender: TObject)
        begin
          ShowMessage('Hello');
        end;
      FirstClass.Free;
    [dcc32 Erreur] Unit1.pas(48): E2009 Types incompatibles : 'pointeur de méthode et procédure normale'
    Il n'y a vraiment aucun moyen moyen pour contourner ça facilement ?

    Papy !

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 299
    Points
    11 299
    Billets dans le blog
    6
    Par défaut
    et avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FirstClass.OnTest := procedure (Sender: TObject) of Object
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    TProc est déclaré dans SysUtils.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    et avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FirstClass.OnTest := procedure (Sender: TObject) of Object

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       FirstClass.OnTest := procedure(Sender: TObject) of object
       begin
         ShowMessage('Hello');
       end;
    [dcc32 Erreur] Unit1.pas(47): E2029 Déclaration attendu(e) mais 'OF' trouvé(e)

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    TProc est déclaré dans SysUtils.
    Je me suis mal exprimé. Ce que je veux dire c'est que mon événement doit être du type TProc (property MyEvent: TProc read FMyEvent write FMyEvent
    ça, c'est valable si je crée moi-même le composant, mais s'il s'agit d'un composant standard, c'est un TNotifyEvent, et là, ça marche plus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      Button1.OnClick  := procedure(Sender: TObject)
       begin
         ShowMessage('Hello');
       end;
    [dcc32 Erreur] Unit1.pas(50): E2009 Types incompatibles : 'pointeur de méthode et procédure normale'

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 858
    Points : 11 299
    Points
    11 299
    Billets dans le blog
    6
    Par défaut
    Il est donc plausible que les méthodes anonymes ne soient pas permises...

    On peut pê en fabriquer comme suggéré ici : http://laurent-dardenne.developpez.c...resEtMethodes/ en attribuant une procédure anonyme à un TMethod ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Et comme c'est écrit dans la documentation que Papy214 mentionne : Méthodes anonymes dans Delphi - Méthodes anonymes en tant qu'événements
    Toutefois, la réciproque n'est pas vraie : vous ne pouvez pas affecter une méthode anonyme à un pointeur de méthode normal. Les références de méthode sont des types managés, mais les pointeurs de méthode sont des types non managés. Ainsi, pour des raisons de fiabilité des types, l'affectation de références de méthode à des pointeurs de méthode n'est pas supportée. Par exemple, les événements sont des propriétés de méthode évaluées en pointeur , vous ne pouvez donc pas utiliser une méthode anonyme pour un événement. Pour de plus amples informations sur cette restriction, voir la section relative à la liaison des variables.
    On en avait discuté : Implémentation de procedure sur evenement pour composant dynamique

    Dans ce genre de situation,
    si le gestionnaire d'évènement est spécifique à un traitement, je fais une méthode privée
    si le gestionnaire d'évènement est généralisable, je fais une classe et une méthode de classe que j'utilise un peu comme un Helper

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type
      TFirstClassToolHelp = class(TObject)
      public
        class procedure TestDefaultEventHandler(Sender: TObject);
      end;
     
    class procedure TFirstClassToolHelp.TestDefaultEventHandler(Sender: TObject);
    begin
      ShowMessage('Hello');
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ..
    var
      FirstClass: TFirstClass;
    begin
      FirstClass := TFirstClass.Create;
      FirstClass.OnTest := TFirstClassToolHelp.TestDefaultEventHandler;
      FirstClass.Free;
    Sinon le code d'instanciation de TFirstClass n'est il pas dans un Objet ?
    Si c'est le code d'une TForm, tu peux créer ton gestionnaire en privé
    ou alors déporté l'intelligent dans un objet controleur
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    Mettre le code d'événement dans le TForm qui utilise l'objet, je peux le faire bien sur. Je fais ça régulièrement.
    Mais dans ce cas, on ne parle plus de méthode anonyme.

    Je pensais qu'il y avait une astuce pour faire ça mais je m'aperçois que non. En .net, ce genre de chose est possible mais c'est sans doute du aux types managés.

    Merci !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 22/06/2011, 15h21
  2. Pas d'événement OnClose quand on arrête W2K
    Par Altau dans le forum C++Builder
    Réponses: 9
    Dernier message: 26/01/2009, 18h36
  3. exploiter un évènement d'un sous composant dans un
    Par bjl dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/12/2002, 16h44
  4. Modification de l'évènement OnClick
    Par MrJéjé dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/08/2002, 12h52
  5. Redéfinir l'événement OnExit de mon composant TEditFloat
    Par Seb des Monts dans le forum C++Builder
    Réponses: 5
    Dernier message: 18/06/2002, 16h10

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