![]() |
Neues On... Ereignis zuweisen
Hi, eine kurze Frage:
Ich habe hier in der Suche folgendes gefunden: Wenn ich z.B. ein OnClick ereignis zur laufzeit definieren will, mache ich das einfach indem ich mir eine procedur schreibe, die unter Public deklariere und dann die zuweisung mache Button.onclick:=meineProcedur; Nur folgendes Problem: Ich hab jetzt eine Unit, die kein Formular hat, also gibts auch keine public und private deklaration. Ich habe gefunden, dass man mit diesem Befehl trotzdem eine Procedur zuweisen kann die unter VAR Deklariert wird: @Button.OnClick:=@MeineProcedur; Kann es sein dass durch die "@" keine Parameter mehr übergeben werden? oder was macht das "@" überhaupt? Grüße |
Re: Neues On... Ereignis zuweisen
|
Re: Neues On... Ereignis zuweisen
Zitat:
Hm okay, d.h. eigentlich müsste auch die parameterinformtion erhalten bleiben oder? |
Re: Neues On... Ereignis zuweisen
Guten Abend und entschuldigt bitte den Push, aber exakt die oben genannte Frage habe ich auch. Dafür braucht es ja keinen neuen Thread.
Ich habe eine Unit erstellt, die bisher keine Klassen enthält. Ich möchte nun eine Prozedur mit einem Ereignis verknüpfen, dessen Komponente von der Unit zur Laufzeit geladen wurde. Wie mache ich das am Schönsten? Danke. |
Re: Neues On... Ereignis zuweisen
Am schönsten ist es wenn du eine Klasse schreibst und dort eine entsprechende Methode in der dann entweder der richtige Code plaziert wird oder die normale Funktion aufgerufen wird.
Das hat den Vorteil das es auch noch bei zukünftigen Delphiversionen funktioniert. Spielt man hingegen mit den Pointern rum und es ändert sich mal etwas am internen Aufbau oder Aufrufsystem darf man dann alles umbauen. |
Re: Neues On... Ereignis zuweisen
Delphi-Quellcode:
Das sollte so zwar Compilieren - funktionieren sollte es jedoch nicht einwandfrei.
@Button.OnClick:=@MeineProcedur;
Ein Methodenzeiger (also das, worauf OnClick normalerweise zeigt) ist normalerweise so aufgebaut:
Delphi-Quellcode:
"Code" spezifiziert hierbei die Codestelle der Prozedur, "Data" die Instanz der Klasse. Jede Methode einer Klasse kann man sich im Prinzip wie eine normale Prozedur mit einem zusätzlichen Parameter "self" vorstellen:
type
TMethod = record Code: Pointer; Data: Pointer; end; PMethod = ^TMethod; Dieser Code...
Delphi-Quellcode:
...ist vom Prinzip her das selbe wie...
type
TMyClass = class value: integer; procedure Test; end; [...] procedure TMyClass.Test; begin Writeln(value); end;
Delphi-Quellcode:
Wenn du nun den Methodenzeiger wie von dir gezeigt einfach so überschreibst, können da die tollsten Sachen passieren, da "Data" in ein Register geschrieben wird, welches eigentlich für einen Parameter gedacht ist (Angabe ohne Gewähr, ich kann mir das nur so vorstellen, überprüft habe ich es nicht). Außerdem wird für "Data" irgendein Wert angenommen, da ein normaler Funktionszeiger ja nur 4 Byte und nicht 8 Byte wie ein Methodenzeiger breit ist.
type
TMyClass = record value: integer; end; PMyClass = ^TMyClass; procedure TMyClass_Test(self: Pointer); begin Writeln(PMyClass(self)^.value); end; Ich hoffe das dies die Sache etwas klarer macht, Andreas |
Re: Neues On... Ereignis zuweisen
Vielen Dank für Eure Antworten & Erklärungen.
Mit
Delphi-Quellcode:
habe ich es übrigens bereits probiert, allerdings wurde dabei mein String-Parameter nicht korrekt übertragen.
@Button.OnClick:=@MeineProcedur;
Nun gut, dann bekommt meine Unit jetzt ihre erste Klasse :) |
Re: Neues On... Ereignis zuweisen
Ein kleiner Nachtrag um meine Theorie zu bestätigen:
Delphi-Quellcode:
Ausgabe:uses SysUtils; type TNotifyEvent = procedure(Sender: TObject) of object; procedure test(Self: Pointer; Sender: TObject); begin writeln(Integer(self)); writeln(Integer(Pointer(Sender))); end; var m: TMethod; ne: TNotifyEvent; begin m.Code := @test; m.Data := Pointer(100); TNotifyEvent(m)(Pointer(200)); Readln; end.
Code:
Eigentlich reicht es also, zu seiner Prozedur einen "self"-Parameter des Typs "Pointer" hinzuzufügen, und schon kann man diese auch als Ziel für Methodenzeiger verwenden. Allerdings ist das ziemlich "tricky" - um es mal so auszudrücken.
100
200 |
Re: Neues On... Ereignis zuweisen
Ich muss nochmal nachfragen.
Mein bisheriger Code:
Delphi-Quellcode:
d2xx.onRead ist definiert als:
unit core;
interface uses d2xxcomp, ... type ReadIn = class procedure parse(message: String); end; var d2xx: TD2xx; // ... procedure load; implementation procedure load; begin d2xx := TD2xx.Create(nil); // ... d2xx.onRead := ReadIn.parse; // [Fehler] core.pas(55): Inkompatible Typen: 'TReadEvent' und 'Procedure' // ... end; procedure ReadIn.parse(message: String); begin //blub end; begin // ... end.
Delphi-Quellcode:
Warum akzeptiert Delphi die Zuweisung d2xx.onRead := ReadIn.parse; nicht? Es handelt sich nun um eine Methode, und die Form der Prozedur ist dieselbe.
type
TReadEvent = procedure(message: String) of object; // Edit: Code aufs Wesentliche beschränkt. |
Re: Neues On... Ereignis zuweisen
Zitat:
|
Re: Neues On... Ereignis zuweisen
Natürlich -.-
Hatte ich vor lauter Klassen und Prozeduren und Methoden total vergessen. Vielen Dank für die schnelle Antwort. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz