Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Klassenlose Procedure per String-Parameter aufrufen (https://www.delphipraxis.net/193847-klassenlose-procedure-per-string-parameter-aufrufen.html)

Harry Stahl 14. Sep 2017 19:08

Klassenlose Procedure per String-Parameter aufrufen
 
Im Internet findet man verschiedene Tipps, wie man Prozeduren oder Funktionen anhand deren Namen per Parameter aufrufen kann, vgl. z.B. hier:

http://www.swissdelphicenter.ch/en/showcode.php?id=799

Diese Tipps setzen aber voraus, dass die Funktionen Teil einer Klasse sind.

Nun habe ich aber verschiedene Prozeduren in einer unit (ohne Form) und ohne, dass diese Teil einer Klasse wären.
Bislang ist mir nur eingefallen, die Prozeduren manuell während der Initialisierung der Unit in einer Stringliste dieser Unit zu registrieren, so dass ich diese registrierten Prozeduren dann später über den String-Namen aufrufen kann (vgl. z.B. hier: http://delphi.cjcsoft.net/viewthread.php?tid=43267).

Ich bin aber (wie immer) zu faul und möchte mir ein wenig Tipparbeit ersparen. Gibt es hier keine Möglichkeit, die klassenlose Procedure zur Laufzeit anhand ihres Names in dieser Unit zu finden und aufzurufen?

Noch kurz ein paar Worte zum Sinn und Zweck des ganzen: Ich habe für ein Multi-Device-Projekt teilweise für Desktop- und Mobilanwendung unterschiedliche Forms, welche nur die Form selber halten, aber keinen Source-Code (mal abgesehen von der einen Prozedur, welche zur Laufzeit OnklickEvents an die Bedienelemente bindet und die Verbindung zum MessageManager herstellt).
Wenn man in diesen Forms auf einen Schalter oder ein Menü klickt, wird per MessageManager eine Botschaft versendet (generiert aus dem Namen des Buttons, Menu, usw), welche unterschiedliche Units abhören (die sich i.d.R. untereinander nicht kennen). Damit die Unit weiß, welche Prozedur sie ausführen soll, erhält Sie in der Message den Namen als String-Parameter übergeben.

Vorteil des ganzen ist, dass ich mein Basis-Programmcode quasi mit unterschiedlichen Oberflächen (und natürlich Plattformen) ausführen kann. Außerdem kann ich einige von den (Source-Code freien) Forms als "Blaupause" verwenden, für andere Programme, welche ähnliche Bedienoberflächen haben.

Nathan 14. Sep 2017 20:55

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Ist vielleicht nicht wirklich was Du suchst, aber ich benutze die Detours Library https://github.com/MahdiSafsafi/delphi-detours-library zum Mocken von z.B. ToDay() oder Api's oder ShowMessage() welche nicht so einfach weg zu Mocken sind.

Redeemer 14. Sep 2017 21:00

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Ich glaube, es liegt nicht an der Tatsache, ob es eine Klasse ist, sondern dass es published ist. In dem verlinkten Beispiel stehen die Methoden ebenfalls unter published. Nur das, was unter published steht, hat zur Laufzeit einen Namen. Der Rest wird vom Compiler gelöscht.

Harry Stahl 14. Sep 2017 21:22

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Zitat:

Zitat von Redeemer (Beitrag 1381235)
Ich glaube, es liegt nicht an der Tatsache, ob es eine Klasse ist, sondern dass es published ist. In dem verlinkten Beispiel stehen die Methoden ebenfalls unter published. Nur das, was unter published steht, hat zur Laufzeit einen Namen. Der Rest wird vom Compiler gelöscht.

OK, wenn das so ist, müsste ich halt ein Dummy-Object erzeugen und die prozeduren da rein packen.

sakura 14. Sep 2017 21:25

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Schau Dir mal Spring4D an. Damit kannst Du Deinen Code vollständig entkuppeln. Das wäre der wohl eleganteste Weg, aber auch dabei wirst Du Deine Klassen noch registrieren müssen.

...:cat:...

himitsu 14. Sep 2017 21:31

AW: Klassenlose Procedure per String-Parameter aufrufen
 
In der TypeInfo (alte RTTI) ist nur Published drin, was man über Funktionen aus der Delphi-Referenz durchsuchenTypInfo und auch direkt über Methoden von [OH]System.TObject[/H] auslesen kann.
> MethodAddress, MethodName und FieldAddress

Aber auch in der erweiterten RTTI haben einfache Prozeduren keine Infos zum Namen, auch wenn diese neue RTTI auch Public und Private enthalten kann (bei Objekt-Methoden).

Harry Stahl 14. Sep 2017 22:03

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Das mit dem Dummy-Object funktioniert jedenfalls, man muss aber noch explizit "published" hinzuschreiben:

Delphi-Quellcode:
type
   TDBProcs = Class
     published

     procedure ShowAbout;
   end;
Das ist schon eine große Hilfe, also Danke für die Hinweise.:thumb:

himitsu 15. Sep 2017 11:33

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Zitat:

Zitat von Harry Stahl (Beitrag 1381247)
man muss aber noch explizit "published" hinzuschreiben

Nicht, wenn man von TPersistent ableitet, bzw. selber die TypeInfo in für deine Klasse oder für einen derer Vorfahren aktivieren.
http://docwiki.embarcadero.com/RADSt...tionen_(Delphi)

In dem Fall ist Published dann die Standardsichtbarkeit, wie z.b. bei den TForms alles Published ist, was dort immer ganz oben deklariert wurde. (siehe die automatischen Felder und Methoden)

uligerhardt 15. Sep 2017 12:25

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Zitat:

Zitat von Harry Stahl (Beitrag 1381247)
Das mit dem Dummy-Object funktioniert jedenfalls, man muss aber noch explizit "published" hinzuschreiben:

Delphi-Quellcode:
type
   TDBProcs = Class
     published

     procedure ShowAbout;
   end;
Das ist schon eine große Hilfe, also Danke für die Hinweise.:thumb:

Du könntest auch
Delphi-Quellcode:
type
   TDBProcs = Class
     published

     class procedure ShowAbout; static;
   end;
probieren (ggfs. ohne das static) - dann bräuchtest du keine Instanz von TDBProcs anzulegen. Ich hab aber nicht nachgeschaut, ob "class procedure" mit published zusammen geht.

Harry Stahl 15. Sep 2017 22:33

AW: Klassenlose Procedure per String-Parameter aufrufen
 
Ja, das mit der class procedure hatte ich auch überlegt. Geht auch (und auch mit published), macht aber letztlich an verschiedenen Stellen mehr Schreibarbeit....


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz