Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Neues On... Ereignis zuweisen (https://www.delphipraxis.net/70089-neues-ereignis-zuweisen.html)

alleinherrscher 24. Mai 2006 21:19


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

pacman1986 24. Mai 2006 21:37

Re: Neues On... Ereignis zuweisen
 
Es ist ein Pointer auf Deutsch Zeiger

http://www.dsdt.info/

alleinherrscher 24. Mai 2006 21:44

Re: Neues On... Ereignis zuweisen
 
Zitat:

Zitat von pacman1986
Es ist ein Pointer auf Deutsch Zeiger

http://www.dsdt.info/


Hm okay, d.h. eigentlich müsste auch die parameterinformtion erhalten bleiben oder?

no_way_back 22. Dez 2009 21:45

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.

SirThornberry 22. Dez 2009 21:51

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.

igel457 22. Dez 2009 22:14

Re: Neues On... Ereignis zuweisen
 
Delphi-Quellcode:
@Button.OnClick:=@MeineProcedur;
Das sollte so zwar Compilieren - funktionieren sollte es jedoch nicht einwandfrei.

Ein Methodenzeiger (also das, worauf OnClick normalerweise zeigt) ist normalerweise so aufgebaut:
Delphi-Quellcode:
type
  TMethod = record
    Code: Pointer;
    Data: Pointer;  
  end;
  PMethod = ^TMethod;
"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:

Dieser Code...
Delphi-Quellcode:
type
  TMyClass = class
    value: integer;
    procedure Test;
  end;

[...]
procedure TMyClass.Test;
begin
  Writeln(value);
end;
...ist vom Prinzip her das selbe wie...
Delphi-Quellcode:
type
  TMyClass = record
    value: integer;
  end;
  PMyClass = ^TMyClass;

procedure TMyClass_Test(self: Pointer);
begin
  Writeln(PMyClass(self)^.value);
end;
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.

Ich hoffe das dies die Sache etwas klarer macht,
Andreas

no_way_back 22. Dez 2009 22:32

Re: Neues On... Ereignis zuweisen
 
Vielen Dank für Eure Antworten & Erklärungen.
Mit
Delphi-Quellcode:
@Button.OnClick:=@MeineProcedur;
habe ich es übrigens bereits probiert, allerdings wurde dabei mein String-Parameter nicht korrekt übertragen.
Nun gut, dann bekommt meine Unit jetzt ihre erste Klasse :)

igel457 22. Dez 2009 23:09

Re: Neues On... Ereignis zuweisen
 
Ein kleiner Nachtrag um meine Theorie zu bestätigen:

Delphi-Quellcode:

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.
Ausgabe:
Code:
100
200
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.

no_way_back 22. Dez 2009 23:31

Re: Neues On... Ereignis zuweisen
 
Ich muss nochmal nachfragen.
Mein bisheriger Code:

Delphi-Quellcode:
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.
d2xx.onRead ist definiert als:
Delphi-Quellcode:
type
 TReadEvent = procedure(message: String) of object;
Warum akzeptiert Delphi die Zuweisung d2xx.onRead := ReadIn.parse; nicht? Es handelt sich nun um eine Methode, und die Form der Prozedur ist dieselbe.
// Edit: Code aufs Wesentliche beschränkt.

Namenloser 22. Dez 2009 23:41

Re: Neues On... Ereignis zuweisen
 
Zitat:

Zitat von no_way_back
Warum akzeptiert Delphi die Zuweisung d2xx.onRead := ReadIn.parse; nicht?

Weil die Methode eines Objekts erwartet wird, nicht einer Klasse. Deswegen heißt es ja auch "of object" und nicht "of class". Du musst erst eine Instanz deiner Klasse erzeugen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:25 Uhr.
Seite 1 von 2  1 2   

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