Trouver la procédure associée à un événement

fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 - 12 mai 2013 à 10:48
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 - 17 mai 2013 à 14:00
 
   Je voudrais pouvoir réécrire le DFM d'une unité une fois l'application lancée. C'est très facile au début, je sais comment avoir la liste des composants et pour chaque composant la liste de ses propriétés et des événements auxquels il réagit.
 
   Si je veux avoir une propriété d'un composant, c'est très facile. Il me suffit d'écrire:

GetPropValue(Le_composant,Nom_de_la_propriete);

   Par exemple, si j'écris:

   Caption_recherchée := GetPropValue(Button1,Caption);

   j'obtiens la bonne réponse: 'Démarrer'.

   Mais pour les événements, problème. Si j'écris:

       Procedure_appelée_par_OnClick_avec_Button1 := GetPropValue(Button1,OnClick);

   je n'obtiens pas la bonne réponse ('Button1OnClick') mais 'TNotifyEvent' qui est le type de l'événement (dont je n'ai que faire)

Quelqu'un connaitrait-il un autre mot ?

        Fred

PS: J'ai bien trouvé sur Internet un projet du même style que le mien (Runtime Inspector) fait par sourceforge ( http://www.ohloh.net/p/rtinspector ) mais comme ça arrive bien souvent, avec ma version de Delphi7, j'ai des messages d'erreur: Unit DBGrid non trouvée, Unit DB non trouvée, etc...)

9 réponses

sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
13 mai 2013 à 11:10
Salut,
C'est quoi le contenu de ta fonction GetPropValue ?

Simon
0
korgis Messages postés 420 Date d'inscription samedi 17 mai 2003 Statut Membre Dernière intervention 6 mai 2019 17
13 mai 2013 à 18:46
@simonpelloquin : pour GetPropValue, sous D7, uses TypInfo
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
13 mai 2013 à 19:46
Salut aux deux.

Ce n'est pas moi qui ai écrit la fonction GetPropList. C'est un mot de Delphi. Voici ce que dit l'aide:

                                (voir tentative de traduction à la fin)


 Description

GetPropList utilises Delphi's RTTI (Run Time Type Information) to retrieve a list of property information records for
 a component or component type.  

In one form of this function, TypeInfo defines the component type, PropList defines a variable to receive the list of 
properties : a pointer to a TPropList variable, and TypeKinds defines the type of properties that will be returned. 
Use tkAny to return all types. The list may optionally be sorted by setting SortList true.  

The Delphi inbuilt TypeInfo function may be used to provide the TypeInfo value.  

In the other form of this function, you specify a component instance rather than component type. The TypeKinds and 
SortList parameters can no longer be specified.  

Note: If you do not need the count of properties returned, use GetPropInfos.


Voici une tentative de traduction et de clarification:

   GetPropLIst utilise RTTI pour aller chercher des informations concernant une liste de propriétés d'un composant sous
 forme de "records".

   Cette fonction a plusieurs formes possibles. Sous l'une de ces formes, Typeinfo définit le type de composant,
 Proplist est une variable destinée à recevoir la liste des propriétés, un PPropList est un pointeur de PropList, et 
Typekind définit le type de propriété (entier, caractere, string, etc...)

   La fonction TypeInfo peut remplacer GetPropList (Korgis n'a pas menti). 

   Sous une autre forme de cette fonction, (celle que j'utilise) le 1er paramètre peut être le nom d'un composant ('Label1')
 plutôt qu'un type (TLabel)

   On peut aussi utiliser la fonction GetPropInfos.


    Eh bien je vais essayer GetPropInfos !
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
14 mai 2013 à 10:46
   
   GetPropInfos n'existe pas. Par contre l'aide de Delphi me propose GetPropInfo.  

   GetPropInfo ne m'apporte rien de plus que PPropinfo. C'est une fonction qui donne un pointeur de propriété (comme PPropInfo) . Elle admet 4 syntaxes:

   MonPointeur= GetPropInfo( Instance:Object;   Const Propname: String;   [AKinds: TTypeKinds= []]);
   MonPointeur= GetPropInfo( AClass:Class;   Const Propname: String;   [AKinds: TTypeKinds= []]);
   MonPointeur= GetPropInfo( TypeInfo:TTypeInfo;   Const Propname: String);
   MonPointeur= GetPropInfo( TypeInfo:TTypeInfo;   Const Propname: String;   AKinds: TTypeKinds);

   J'ai essayé:
getpropinfo(label1,caption)^.Name;

   et j'ai obtenu un message d'erreur.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
16 mai 2013 à 20:25
   J'ai fait quelques recherches sur les possibilités de faire un lien entre une procédure et son nom. J'ai fini par comprendre que ce que je veux faire est compliqué. On trouve bien des programmes sur Internet qui permettent de le faire mais le code-source est toujours absent.

   Si on a une procedure qui s'appelle "Afficher_Salut", je pensais que pour l'exécuter, il suffisait d'écrire:
   begin
      Ma_procedure:= 'Afficher_salut";
      Ma_procedure; 
   end;
 


   En fait, voilà ce qu'il faut écrire:

PROCEDURE TForm1.Afficher_salut;
Begin
   ShowMessage('Salut!') ;
End;

PROCEDURE TForm1.Button1Click(Sender: TObject) ;
Begin
   Executer(Form1, 'Afficher_salut') ;
End;

PROCEDURE TForm1.Executer(La_Classe: TObject; Nom_de_la_procedure: String) ;
type
     TModule_executable = PROCEDURE Of OBJECT;
var
    Ma_methode: TMethod;
    Module_executable: TModule_executable;
begin
   // On définit Ma_méthode
   Ma_methode.Data := Pointer(La_Classe) ;
   Ma_methode.Code := La_Classe.MethodAddress(Nom_de_la_procedure) ;
   // Si le nom de la procédure est bidon, on laisse tomber
   IF NOT Assigned(Ma_methode.Code) THEN EXIT;
   // On définit la partie exécutable et on l'exécute
   Module_executable := TModule_executable(Ma_methode) ;
   Module_executable;
end;


   Je ne l'aurais pas trouvé seul ! Et pour ce que je cherche à faire, je finirai peut-être un jour par trouver...
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
16 mai 2013 à 22:48
Bonsoir,
Les évènements des controles sont de type TNotifyEvent et sont en fait des pointeurs:

procedure TForm1. MonClick (Sender:tObject);
begin
... // tu écris tes evenements
end;

var NewEvClick, OldEvClick : tNotifyEvent;

procedure TForm1.FormCreate(Sender:tObject); // dans create ou ailleurs
begin
OldEvClick := Button1Click; // on mémorise l'ancien evenmt Button1Click dans OldEvClick
Button1Click := NewEvClick; // on change la proc attachee a l'even OnClick du bouton
Button1Click := nil; // on desactive le click, plus de proc
Button1Click := OldEvClick; // on rebranche le OnClick original
// ou encore:
if OldEvClick = nil then // y a pas d'even OnClick
...
end;

C'est tout simple.
Salut
solilog
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
17 mai 2013 à 09:22
   Merci pour cette réponse.

   Je pense avoir compris la procédure mais:
     - tous les événements ne sont pas du type TNotifyEvent (je veux tous les événements de chaque composant, pas seulement les OnClick); mais ça, ce n'est pas un problème, je peux trouver la nature des événements grâce à l'inspecteur d'objets.

     - je ne cherche pas à changer la procédure associée au click de Button1, mais à avoir son nom. Bien sûr, il y a de grandes chances qu'elle s'appelle Button1OnClick mais elle peut aussi s'appeler Afficher_Salut.
   
   J'ai essayé:
      Showmessage(button1.Onclick.name);

mais ça ne marche pas !
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
17 mai 2013 à 10:24
Salut,

Si TOUS les evenements sont des tNotifyEvent (c est d ailleurs a ca que servent les tNotifyEvent), les param qu'íls attendent peuvent etre <> bien-sur. Tu peux checker si <> nil (il y a un evenement attache), attacher une autre proc (exemple precedent), mais il est conseille de remettre le pointeur de la proc originale avant de quitter la fenetre car certains peuvent faire planter (OnActiveControlChange, OnActiveFormChange, ...)
Bonne journee.

solilog
0
fredelem Messages postés 136 Date d'inscription dimanche 29 octobre 2006 Statut Membre Dernière intervention 1 décembre 2022 2
17 mai 2013 à 14:00
 
Merci pour ces précisions mais je vais encore te contredire.

   J'ai obtenu une liste des propriétés de Button1 en écrivant le code suivant:
              Valeur_de_la_propriete:= GetPropValue(Le_composant,Nom_de_la_propriete);
              Memo1.lines.add(vartostr(valeur_de_la_propriete));


   Pour les propriétés, ça marche bien, le nom, par exemple, apparait bien comme étant "Button1" mais pour les évènements, au lieu d'avoir le nom, j'ai le type. Voici un extrait de ce que j'obtiens:

         Name = 'Button1'
         OnClick = TNotifyEvent
         OnContextPopup = TContextPopupEvent
         OnDragDrop = TDragDropEvent
         OnDragOver = TDragOverEvent
         OnEndDock = TEndDragEvent
         OnEndDrag = TEndDragEvent
         OnEnter = TNotifyEvent
         OnExit = TNotifyEvent
         OnKeyDown = TKeyEvent
         OnKeyPress = TKeyPressEvent
         OnKeyUp = TKeyEvent
         OnMouseDown = TMouseEvent
         OnMouseMove = TMouseMoveEvent
         OnMouseUp = TMouseEvent
         OnStartDock = TStartDockEvent
         OnStartDrag = TStartDragEvent

   Ils ne sont pas tous du même type. Mais finalement, ça n'a pas d'importance. Ce que je veux faire, ce n'est pas remplacer une procédure par une autre. Je voudrais seulement, dans ma liste ci-dessus, au lieu de
         OnClick = TNotifyEvent
obtenir
         OnClick = Button1OnClick

. Fred

PS: J'ai obtenu une liste trop longue, elle contient tous les événements même ceux qui n'ont pas de procédure associée. Au prochain essai, je tiendrai compte de ton tuyau et je ferai précéder la consigne de
     IF propriete<> Nil THEN
0
Rejoignez-nous