Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Methodenaufruf umbiegen? (https://www.delphipraxis.net/143952-methodenaufruf-umbiegen.html)

himitsu 26. Nov 2009 19:32

Re: Methodenaufruf umbiegen?
 
Zitat:

Zitat von NamenLozer
Edit: Ach verdammt, hab dein Edit übersehen :wall:

Tschuldschung :oops:

Nja, aber er hat ja anscheinend statische Methoden und die brauchen auch keine Tabellen, da sie sich ja normaler Weise nicht ändern und es somit "sinnlose" Sprünge ergeben würde.

Neutral General 26. Nov 2009 19:36

Re: Methodenaufruf umbiegen?
 
Zitat:

Zitat von Medium
Zitat:

Zitat von Neutral General
Leute.. Wenn man mein Problem mit OOP lösen könnte, dann hätte ich das schon getan :freak:

...weswegen eine Anfrage auch eigentlich immer beinhalten sollte, was man schon so versucht hat. Ist ja nicht so, dass das nicht des öfteren schon in der DP Thema war :cheer:

Warum sollte ich erwähnen, dass ich es noch nicht mit ner Taschenlampe versucht habe, wenn ich ein Loch graben will?
Mein Vorhaben hat absolut nichts mit OOP zu tun :roll:

Zitat:

Zitat von Medium
Und selbst DANN gibt es fast immer noch Wege an die man selbst evtl. dann doch noch nicht gedacht hat - nobody is perfect. Und da uns partout nicht erzählen magst, was du im großen und ganzen vor hast (um evtl. einen anderen Weg zu finden - was ja schon irgendwo in deinem Interesse sein dürfte), klinke ich mich mal aus. Weil dass das so wie von dir erhofft eher nix wird dürfte nun ja klar genug geworden sein - so "tänzelnde" Beiträge der Art "hmmm, was hast'n vor, das geht evtl. anders" deuten da ja eigentlich ganz gut drauf hin.

Ich habe bereits gesagt was ich vorhabe und außer dir haben mich die meisten auch verstanden glaube ich. Aber ich kann es gerne nochmal erklären.

Angenommen ich baue einen Nachfolger von TEdit, der die Caption eines Buttons anzeigt. Der Programmierer kann dann dem Edit einen Button zuweisen.

Delphi-Quellcode:
TNeutralEdit = class
public
  Button: TButton;
end;
Nun folgender Code:


Delphi-Quellcode:
var Edit: TNeutralEdit;
    Button: TButton;
begin
  Edit.Button := Button;
  Button1.Caption := 'Test123';
  ShowMessage(Edit.Text); // ==> 'Test123'
end;
Dafür muss das Edit aber (automatisch!) mitbekommen, wenn die Caption des Buttons geändert wird.
Und genau DAS ist das Problem.

Dazu allerdings noch eine Anmerkungen:

Das war ein sehr spezielles Beispiel. Ich kann zu diesem Zweck weder Windows Messages abfangen noch einen Class Helper für TButton o.ä. benutzen. Denn der TButton aus dem Beispiel ist durch eine beliebige andere Klasse austauschbar. Die Property, die angezeigt werden soll ebenso.

himitsu 26. Nov 2009 19:39

Re: Methodenaufruf umbiegen?
 
Du kannst ja mal versuchen rauszubekommen, wie z.B. TUpDown das Ändern des {Edit}.Text mitbekommt.

Neutral General 26. Nov 2009 19:43

Re: Methodenaufruf umbiegen?
 
Zitat:

Zitat von himitsu
Du kannst ja mal versuchen rauszubekommen, wie z.B. TUpDown das Ändern des {Edit}.Text mitbekommt.

Gar nicht.. TUpDown ist unabhängig.. Einfach nur 2 Pfeile und einen Value-Wert. TUpDown hat erstmal nichts mit einem TEdit zu tun. Kann man allerdings verbinden wenn man das OnChange des UpDowns (und des Edits) benutzt

brechi 26. Nov 2009 20:06

Re: Methodenaufruf umbiegen?
 
Hast du eigentlich schon meine Lösungen gesehen? Da nicht virtual Methoden keine Adress in irgendeiner LUT haben musst du direkt den Code überschreiben. Anders wist du es nicht hinbekommen.

Medium 26. Nov 2009 20:20

Re: Methodenaufruf umbiegen?
 
Ich kann mich nicht entsinnen, in deinem ersten Beitrag etwas von Properties und deren Binding gelesen zu haben. Da muss ich wohl mal in die Runde fragen, womit ihr so eure Glaskugeln putzt ;) Das einzige wonach du gefragt hast, ist wie man eine Methode an eine vormals anders implemetierte knoten kann, was mit Properties kam dann danach, was ich als Lösungsversuch verstanden habe, bzw. war nicht eindeutig, dass es im Grunde um Properties geht - von Methoden war die Rede, was ja u.U. etwas allgemeiner, im Falle direkter Variablenbindung aber auch ganz anders ausfällt: Stell dir mal vor, es gäbe Properties die keinen Setter haben, sondern direkt in eine private Variable schreiben (oder aus ihr lesen) :shock:.

Eine generelle Lösung scheint es in Delphi nicht zu geben. Sämtliche Ansätze in diese Richtung die mir bisher so begegnet sind, sind Komponentensammlungen die diese Möglichkeit explizit vorsehen, oder es gab ein globales Update-Objekt, dass Komponenten mit Werten versorgt hat die aus einer DB oder sonstwoher stammen (ein OPC-Server ist da mein aktuellster Kandidat). Dir bliebe lediglich zu hoffen, dass es ein (published) OnChange der zu überwachenden Komponente gibt, dem du mit Hilfe der RTTI dynamisch einen Handler zuweisen könntest. Das muss dann zudem natürlich einheitlich ein TNotifyEvent sein. Problematisch ist dabei, dass man u.U. Handler vom anwendenden Programmierer damit abhängt, bzw. umgekehrt. Da ist dann die Frage wer zuerst kommt beim Laden des Formulars - bist du es, hast du schlechte Karten. Ist es die andere Kompo, lässt sich evtl. der zuvor zugewiesene Handler mit einschleifen.
Das OnChange ist dann natürlich allgemein, und du müsstest dir dann noch "von Hand" den betreffenden Wert abholen. Nur muss man dann drauf vertrauen, dass die Kompo auch bei Änderung der gewünschten Property auch wirklich OnChange feuert.

himitsu 26. Nov 2009 20:47

Re: Methodenaufruf umbiegen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Neutral General
Gar nicht.. TUpDown ist unabhängig.. Einfach nur 2 Pfeile und einen Value-Wert. TUpDown hat erstmal nichts mit einem TEdit zu tun.

Eben nicht.

Die beiden Edit und UpDown sind nur via UpDown.Associate verbunden,
aber egal was man macht (UpDown-Klicken oder in Edit was reinschreiben),
es ändern sich immer Beide.

OK, UpDown weiß beim Klicken über .Associate vom Edit, aber das Edit weiß nichts vom UpDown,
also wie bekommt beim Ändern von Edit.Text das UpDown was davon mit? (.Position ändert sich ja)

Neutral General 26. Nov 2009 21:59

Re: Methodenaufruf umbiegen?
 
Habs den Code von TUpDown kurz überflogen. Sieht danach aus als würde da mit Messages gearbeitet. Auf die muss ich allerdings verzichten. Und OnChange kommt auch nicht in Frage weil die meisten Klassen (!) kein OnChange haben. Die meisten Klassen haben überhaupt keine Events.

@Medium: Ok ich gebe zu mein Ursprungs-Post lässt viel Spielraum für Glaskugeln. Aber schon im 2. Post (der 3. des Threads) habe ich nochmal deutlicher erklärt was ich vorhabe. Und meiner Meinung nach konnte man da schon recht gut rauslesen was ich vorhatte und dass da mit OOP nichts zu machen ist....

Medium 26. Nov 2009 22:40

Re: Methodenaufruf umbiegen?
 
Ich wollte nur noch mal abschließend (aus meiner Sicht, nicht wegen Groll sondern Unmachbarkeit in dieser Form), auf den recht vernichtenden Umstand: "Properties die keinen Setter haben, sondern direkt in eine private Variable schreiben (oder aus ihr lesen)" hinweisen. Dann gibt es nämlich noch nichtmal eine hartgecodete Methodenadresse die man mit Gefrickel bis der Arzt kommt evtl. noch umbiegen könnte, sondern da wird dann einfach direkt irgendwo im Heap gefummelt wie bei "i := 42" (mal angenommen i sei aufm Heap :)).

negaH 27. Nov 2009 00:36

Re: Methodenaufruf umbiegen?
 
Es geht teilweise was du vorhast. Dazu muß die Property

1.) eine Setter Methode haben
2.) das Schreiben in diese Property muß über die RTTI dynamisch erfolgen, zb. beim Laden von Komponenten aus DFMs ist dies immer der Fall.

Schon kompilierter Code wird durch den Kompiler einen statischen Aufruf der Setter Methode benutzen.

Beachte aber das du die Klassen-RTTI im Codesegment manipulieren musst und damit mit einem Hook alle Objekte und deren Nachfahren dieser Klasse beeinflussts.

Eine zweite Alternative gibt es noch. Werden Properties eines Objektes dynamisch gesetzt, zb. beim Laden aus DFMs dann könntest du eine "Spiegelklasse" benutzen. Dazu musst du aber die kompletten privaten Felder und Methoden der zu "hookenden" Klasse kennen. Man deklariert also eine komplett neue Klasse abgeleitet von einem gemeinsammen Vorfahr der Zielklasse, maximal also TObject, die Speichertechnisch identisch ist. Nun reimplemetierst du alle Felder, Properties und virtuellen/dynamischen Methoden deiner Zielklasse in der Spiegelklasse, natürlich mit dem gewünschten veränderten Verhalten.

Zur Laufzeit hat jedes Objekt in seinem "Speicherrecord" als erstes einen Zeiger auf seine VMT, genauer gesagt einen Zeiger mitten in die RTTI seiner Klasse an der die VMT beginnt. Diesen biegst du bei deinen Zielobjekten auf deine Spiegelklasse temporär um. Also solange wie du das geänderte Verhalten wünscht. Alle nicht statischen Zugriffe auf dieses Objekt die über die RTTI gehen werden ab sofort über deine Spiegelklasse "geroutet". Dynamische Zugriffe können auf Properties, Events, virtuelle, dynamische Methoden (und damit auch Message Methoden), Interfaces, TypInfos, Konstruktoren usw. erfolgen. Mit diesem Trick veränderst du zu einem allozierten Objekt zur Laufzeit deren Klassenbeziehung. Damit das funktioniert muß die VMT und DMT beider Klassen pseudoidentisch sein, also gleiche Anzahl an Methoden und auch gleiche Aufrufparameter jeder Methode in gleicher Slot Position.

Nachteil dieser Methode: alle is und as Operatoren funktionieren nicht mehr korrekt. Genauer gesagt: as/is benutzt exakt diesen Zeiger auf die VMT eines Objektes für einen Vergleich beim Typcast bzw. Klassenabfrage. Diese Operatoren vergleichen im Grunde also nur die Codesegement Speicheradresse der RTTI/Klassenstruktur der Objekte.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:22 Uhr.
Seite 3 von 3     123   

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