Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Eigenes Event aus Eventprozedur aufrufen -> Fehler
peeage - Fr 23.01.09 16:46
Titel: Eigenes Event aus Eventprozedur aufrufen -> Fehler
Hallo zusammen !
Ich nutze in meiner Klasse eine Komponente, deren ich den Pointer zu einer Prozedur in meiner Klasse bekanntgebe. Die Komponente ruft dann regelmäßig meine Prozedur auf ( Callback / Event ). Das klappt alles perfekt. Nun bietet meine Klasse auch eigene Events / CallBacks an, so das andere Klassen - die meine Klasse nutzen - auch bei bestimmten Ereignissen informiert werden. Dies klappt auch wunderbar... NUR wenn ich MEINE CallBackprozedur ( sprich: Die Prozedur in der Klasse welche bei Ereignissen aus meiner Klasse informiert werden möchte) innerhalb der CallBackprozedur aufrufe, die in meiner Klasse durch die Komponente ausgelöst wurde, kommt es zu einer Zugriffsverletzung.
Ist jemand auch schonmal über das Problem gestoßen?
Gruß
jaenicke - Fr 23.01.09 18:54
Ohne etwas Code ist es schwer dazu etwas zu sagen...
Wie sieht der Aufruf aus, wie die Deklaration?
Kommt die Zugriffsverletzung an Adresse 0 oder einer anderen?
peeage - Fr 23.01.09 20:06
Mir ist gerade aufgefallen das ich von einer Callback- Prozedur allgemein auf keine Variablen aus der eigenen Klasse zugreifen kann ( sei es privat, public ... )
Hier ein Beispiel:
Klasse die das Ereignis bekannt gibt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| unit Unit2;
interface
type TMyEvent = procedure of object;
TMyClass = Class private FMyEvent : TMyEvent; public constructor Create; procedure doEvent; property MyEvent : TMyEvent read FMyEvent write FMyEvent; end;
implementation
constructor TMyClass.Create; Begin inherited Create; end;
procedure TMyClass.doEvent; Begin if Assigned( FMyEvent ) then FMyEvent; end;
end. |
Klasse deren Callback- Prozedur aufgerufen wird ( Hier als Beispiel eine TForm- Klasse ):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Unit2, StdCtrls;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private str : String; procedure MyEvent; public end;
var Form1 : TForm1; MyClass : TMyClass;
implementation
{$R *.dfm}
procedure TForm1.MyEvent; Begin ShowMessage(str); end;
procedure TForm1.FormCreate(Sender: TObject); begin MyClass := TMyClass.Create; @MyClass.MyEvent := @TForm1.MyEvent; MyClass.doEvent; end;
end. |
TForm1.MyEvent wird aufgerufen. Hier soll der String "str" ausgegeben werden, nur leider kommt es hier zu einer Fehlermeldung.
jaenicke - Fr 23.01.09 20:41
peeage hat folgendes geschrieben : |
TForm1.MyEvent wird aufgerufen. Hier soll der String "str" ausgegeben werden, nur leider kommt es hier zu einer Fehlermeldung. |
Weil das Event nicht im Kontext des Formulars aufgerufen wird sozusagen. Versteckt wird glaube ich die Instanz mitgeliefert, und die ist in dem Fall nil.
(Werte einfach mal Self aus mit Strg + F7.)
Warum nicht einfach so:
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.MyEvent; Begin ShowMessage(Form1.str); end; |
;-)
peeage - Fr 23.01.09 21:06
Hmmm.. stimmt. So geht es in meinem Beispiel.
Nur habe ich in meiner Klasse ( nicht das Beispiel mit der TForm- Klasse ) keine Referenz auf die aktuelle Instanz meiner Klasse ( wie im Beispiel "Form1" ). Die Referenz auf die Instanz meiner Klasse besitzt nur die Klasse, die meine Klasse Instantiert.
Ich kann innerhalb der instantiierten Klasse nur mittels "self" auf die aktuelle Instanz der Klasse zugreifen, oder? Nur wenn ich das nun so mache -> ShowMessage( self.str ) ... Dann bekomm ich auch wieder diesen Fehler.
jaenicke - Fr 23.01.09 21:20
jaenicke hat folgendes geschrieben : |
und die ist in dem Fall nil.
(Werte einfach mal Self aus mit Strg + F7.) |
Ich sagte ja, dass genau das Self das Problem ist. Du darfst den Eventhandler nicht als Teil der Klasse sehen und das entsprechend programmieren.
delfiphan - So 25.01.09 18:39
Verwende:
Delphi-Quelltext
1:
| MyClass.MyEvent := MyEvent; |
statt
Delphi-Quelltext
1:
| @MyClass.MyEvent := @TForm1.MyEvent; |
Und wenn die eigentliche Instanz unwichtig ist, dann mit class procedures arbeiten, dann heisst es:
Delphi-Quelltext
1:
| MyClass.MyEvent := TForm1.MyEvent; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!