L'objectif est de pouvoir appeler une méthode sur un objet, descendant de TObject, dont la classe est inconnu. Cette méthode sera simple et sans paramètre. La difficulté ici est que l'on ne peut pas passer par le transtypage.
Donc il va falloir ruser pour pouvoir faire l'appel à une méthode de cette classe.
Conditions préalables :
1 - La classe doit être compilé avec la directive $M+ (par exemple TPersistent).
2 - La méthode que l'on souhaite appeler doit être publiée.
Pour récupérer la méthode save d'un objet inconnu il faut passer par la fonction de classe MethodAddress introduite dans TObject. Tant qu'une classe descendante de TObject n'est pas compilée avec la directive $M+, les instances n'auront pas de RTTI, on donc pas de possibilité de retrouver l'adresse d'une méthode.
Pour plus de détails à ce sujet vous pouvez voir le code de MethodAddress dans System.pas.
Le code de cet appel est le suivant :
var
zmSave: procedure of object; // la méthode save
zpSave: pointer; // pointeur vers le code de la méthode save
begin
// si il existe un éditeur courant et que le panneau de cet éditeur existe et que le panneau a une méthode
// save publié alors....
if assigned(CurrentEditor) and assigned(CurrentEditor.ctrl) and (CurrentEditor.ctrl.MethodAddress('Save') <> nil) then
begin
// on récupère le pointeur sur le code de la méthode save
zpSave := CurrentEditor.ctrl.MethodAddress('Save');
// puis on initialise la variable zmSave avec le code et les données associés
TMethod(zmSave).data := CurrentEditor.ctrl;
TMethod(zmSave).code := zpSave;
// et on fait l'appel
zmSave;
