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 Event Handling (https://www.delphipraxis.net/136038-event-handling.html)

Highttower 22. Jun 2009 15:58


Event Handling
 
Hallo zusammen,
auf meiner Reise von C++ zu Delphi bin ich auf ein weiteres kleines Problem gestoßen: Events

Ich hab mal nen kleines Testprogramm dazu geschrieben:

Delphi-Quellcode:
  TAEvent = procedure(A:String) of object; // soweit klar ein Funktionszeiger

TBrowser = class
  private
    FEvent: TAEvent;
  public
    property Event: TAEvent read FEvent write FEvent;
    procedure show;
end;


TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure AnotherEvent(A: String);

    private
        FBrowser: TBrowser;

    public

end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AnotherEvent(A: String);
begin
    ShowMessage(a);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    FBrowser := TBrowser.Create; // soweit noch klar und wenn ich alle möglichen Bücher über Delphi lese und Googel befrage müsste das auch gehn:
    self.AnotherEvent := (FBrowser.Event); // geht so scheinbar nicht; laut Kompiler: zu wenige Parameter aber ich weise doch nur nen Pointer zu oder nicht?
end;

procedure TBrowser.show;
begin
    ShowMessage('dfdfdf');
    Event('ddddd');
end;
Kann mir jemand erklären warum das so nicht geht? Ich hab schon alles mögliche Probiert das
Delphi-Quellcode:
 self.AnotherEvent := (FBrowser.Event);
Ist meine Momentane Fassung, so Späße wie nen Temporäres Object mit "with" kreieren oder Tempoäre Variablen, als auch das Event als Pointer zu handeln und das andere als Adresse bringt alles nix. Auch Klammersetzung in jeglicher Form haben nix gebracht.

Vielen lieben dank,

Tobi

PS: So bald ich mal nen mindest Wissen in Delphi hab schreib ich mal nen kleines Tut für Umsteiger von C++ auf Delphi ;)

Phoenix 22. Jun 2009 16:00

Re: Event Handling
 
Du benutzt das falsch rum.

Delphi-Quellcode:
FBrowser.Event := self.anotherEvent;
Wobei das bei self eigentlich besser EventHandler heissen sollte.

Highttower 22. Jun 2009 16:07

Re: Event Handling
 
ok gut dann hab ich ne Verständnis Frage:

Ich hol erst mal aus, ein Event ist irgendeine Methode die von einem (internen?) Thread gehandelt wird. Dieser ist quasi als Observer geschrieben und benachrichtigt alle die an diesem Thread hängen wenn sich eine Methode ändert.

Soweit richtig?

Es gibt verschiedene Methoden aber um einer Methode eine andere zu zuweisen muss man:
Zitat:

Zitat von Phoenix
Du benutzt das falsch rum.

Delphi-Quellcode:
FBrowser.Event := self.anotherEvent;
Wobei das bei self eigentlich besser EventHandler heissen sollte.

Die Methode dem Event zu weisen und nicht das Event der Methode, aber die Methode soll doch das Event sein oder nicht?

Euer aufm schlauchstehender
Tobi

uligerhardt 22. Jun 2009 16:09

Re: Event Handling
 
Zitat:

Zitat von Highttower
aber ich weise doch nur nen Pointer zu oder nicht?

Jein. Du weist einen Methodenzeiger zu. Der besteht aus zwei "normalen" Zeigern - einem auf das aufrufende Objekt und einen auf die Methode. Intern zeigt ein Methodenzeiger auf ein TMethod.

Highttower 22. Jun 2009 16:14

Re: Event Handling
 
Zitat:

Zitat von uligerhardt
Zitat:

Zitat von Highttower
aber ich weise doch nur nen Pointer zu oder nicht?

Jein. Du weist einen Methodenzeiger zu. Der besteht aus zwei "normalen" Zeigern - einem auf das aufrufende Objekt und einen auf die Methode. Intern zeigt ein Methodenzeiger auf ein TMethod.

Ja, aber tief im innern Weise ich doch nur Code, Code zu und Data, Data. Oder kreuzt sich hier irgendwas? Und darum muss man das anders rum benutzen?

mkinzler 22. Jun 2009 16:18

Re: Event Handling
 
Zitat:

Die Methode dem Event zu weisen und nicht das Event der Methode, aber die Methode soll doch das Event sein oder nicht?
Nein, die Methode ist ein CallBack.

Apollonius 22. Jun 2009 16:20

Re: Event Handling
 
Ich glaube, dass du eine falsche Vorstellung von einem Event hast.
Zitat:

Ich hol erst mal aus, ein Event ist irgendeine Methode die von einem (internen?) Thread gehandelt wird. Dieser ist quasi als Observer geschrieben und benachrichtigt alle die an diesem Thread hängen wenn sich eine Methode ändert.
Ein Event ist erstmal eine ganz normale Variable. Im Gegensatz zu .NET-Sprachen handelt es sich dabei also nicht direkt um ein Sprachkonstrukt. Diese Variable kann eine einzige Methode speichern. Außerdem kann diese Methode dann wieder abgerufen und aufgerufen werden. Genau das passiert irgendwo in den Innereien von TBrowser. Es handelt sich dabei nicht um irgendwelche Magie, sondern in irgendeiner Methode steht explizit FEvent('foo') o.Ä.
Jetzt sollte aber auch klar sein, warum die Zuweisung so aussehen muss, wie sie aussieht: Die Methode selbst wird nicht verändert, lediglich das Feld in der Objektinstanz erhält einen neuen Wert.

Highttower 22. Jun 2009 16:37

Re: Event Handling
 
Zitat:

Zitat von Apollonius
Ich glaube, dass du eine falsche Vorstellung von einem Event hast.
Zitat:

Ich hol erst mal aus, ein Event ist irgendeine Methode die von einem (internen?) Thread gehandelt wird. Dieser ist quasi als Observer geschrieben und benachrichtigt alle die an diesem Thread hängen wenn sich eine Methode ändert.
Ein Event ist erstmal eine ganz normale Variable. Im Gegensatz zu .NET-Sprachen handelt es sich dabei also nicht direkt um ein Sprachkonstrukt. Diese Variable kann eine einzige Methode speichern. Außerdem kann diese Methode dann wieder abgerufen und aufgerufen werden. Genau das passiert irgendwo in den Innereien von TBrowser. Es handelt sich dabei nicht um irgendwelche Magie, sondern in irgendeiner Methode steht explizit FEvent('foo') o.Ä.
Jetzt sollte aber auch klar sein, warum die Zuweisung so aussehen muss, wie sie aussieht: Die Methode selbst wird nicht verändert, lediglich das Feld in der Objektinstanz erhält einen neuen Wert.

Das klingt einleuchtend, allerdings verstehe ich nicht wie. Du sagst
Zitat:

Zitat von Apollonius
Außerdem kann diese Methode dann wieder abgerufen

, aber so wie ich das Verstanden wird sie aber ständig abgerufen. So kann ich z.B. wenn ich ein Event ändere von einem Server aus dem Client sagen, hier sind neue Daten angekommen(Das ist z.b. das Beispiel aus dem Buch "Delphi in a nutshell" von Ray Lischner(übrigends ne tolle sache wo alles andere super drin erklärt, wird wenn man nen bissl ahnung hat was man tun will(tut))). Also muss ja irgendetwas "magisches" über alle Events iterienen und den Objekten bescheid geben. Ich kann mir nicht vorstellen das das jedes Objekt oder jede Instanz eines Objektes autonom für sich macht. Meines Verständnisses nach ist genau dieser Zauberstab der EventHandler.

Stimmt das soweit?

Wenn ja dann find ich es nämlich verwirrend das man von den Objekten selbst auch noch die Events rufen kann. :?: :?:

Gruß,
Tobi

PS: Sagt mir wenn ich mich zu tief darein denke, oder wie nen Kumpel immer sagt, das ist Delphi nicht C++, was unter der Haube passiert ist hier nicht so wichtig, hauptsache es tut. -> Aber ich wüsste es halt gern :D

Apollonius 22. Jun 2009 16:41

Re: Event Handling
 
Nein, es gibt keine Magie. In deinem Socket-Beispiel registriert sich der Socket bei Windows, sodass Windows eine bestimmte Prozedur aufruft, wenn neue Daten sind. Diese Prozedur ruft dann das Delphi-Event auf.

sirius 22. Jun 2009 16:45

Re: Event Handling
 
Hier gibt es keinen Zauberstab:

Delphi-Quellcode:
type TEineMethode=procedure of object;

type TFoo=class
       procedure EineMethode;
       procedure andereMethode;
     end;

var Foo:TFoo;

//jetzt kann man eben irgendwo (für Ereignisse meist in einer Klasse)
//eine Variable deklarieren
var gEineMethode:TeineMethode;

begin
  Foo:=TFoo.Create;
 
  gEineMethode:=Foo.EineMethode;
  //jetzt steht in der Variablen gEineMethode der Zeiger auf die Methode EineMethode der Instanz Foo. Das sind simple 8 Bytes (2 Zeiger)
  //jetzt kannst du geMeineMethode ainfach aufrufen und es wird die darin gespeicherte Methode aufgerufen
  gEineMethode;

  //und wir können eine andere Methode drin speichern:
  gEineMethode:=Foo.andereMethode;
  //und aufrufen
  gEineMethode
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:09 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