![]() |
Event-Typen und warum deren Inhalte manchmal nicht stimmen
Hallo,
Hab nochmal eine Verständnisfrage zu Events. Lustiger Weise funktionieren sie irgendwann genau immer so, wie ich das will aber hab hier zum x.ten mal Anfangschwierigkeiten bei dem Einfügen eines neuen Events. Folgender Maßen führe ich in eine meiner Komponenten die Events ein:
Delphi-Quellcode:
Also ich habe sicherlich in der Art und Weise schon mehrfach Events eingeführt und irgendwie funktioniert das am Anfang immer überhaupt nicht (so wie jetzt) und irgendwann ohne für mich ersichtlichen Grund (derzeit) funktioniert es. Ich habe schon das OnTischChange := nil gesetzt und trotzdem bleibt assigned(OnTischChange) = false.
Type TOnTischChange = procedure of Object;
Type TTischsteuerung = class(TWinControl) private ... // Variablen für Events FOnTischChange: TOnTischChange; published // OnTischChange soll dem Programm die Möglichkeit geben alle Eigenschaften auf den // ausgewählten Tisch auszurichten. property OnTischChange: TOnTischChange read FOnTischChange write FOnTischChange; ... end; ... // irgendwo in der createwnd-Procedure FCombBoxTischauswahl := CreateComboBox(17,35, 200); FCombBoxTischauswahl.Items.Add('Test1'); FCombBoxTischauswahl.Items.Add('Test2'); FCombBoxTischauswahl.Items.Add('Test3'); FCombBoxTischauswahl.ItemIndex := 0; FCombBoxTischauswahl.OnChange := Tischaenderung; // Die Procedure Tischaenderung procedure TTischsteuerung.Tischaenderung(Sender: TObject); begin case FCombBoxTischauswahl.ItemIndex of 0: Komponentenanpassung(1); 1: Komponentenanpassung(2); 2: Komponentenanpassung(3); end; if assigned(OnTischChange) then OnTischChange; end; Der Sinn hinter dem Event ist eigentlich, dass ich in meinem Composite Control das onChange-Event der Combonox weitergeben will. Dafür habe ich auch schon die Komponente deinstalliert und neu installiert (verwende hier auf Arbeit Rad2007, nicht wie in Profil TD2006). Kann mir jemand vieleicht sagen, warum das anscheinend derart flüchtig ist, was aus assigned(On...) herauskommt? Vielen Dank BAMatze |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
probiers mal mit FOnTischChange
|
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Ganz ehrlich:
* an dem hier gezeigtem Code kann ich keinen Fehler finden, welcher dieses Problem erklären würde * und ich äußere meine Vermutung gern nochmal (hab so langsam das Gefühl), wenn ich hier und da den einen oder anderen Post/Thread lese: ein Bufferoverrun, bzw. ein verirrter Pointer oder Ähnliches, würden dieses Verhalten erklären. Zitat:
aber dennoch würde das hier nix ändern, da eh direkt auf die Variable zugegriffen wird. |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Hallo @himitsu und alle anderen natürlich auch,
Gibt es für mich als Anfänger da eine Möglichkeit eine Art Fehleranalyse zu machen, ohne den Quellcode Schritt für Schritt noch einmal durchzugehen (der Debugger an sich bringt mir ja keinen Fehler)? Ich glaube gelesen zu haben, dass es für Speicherlecks etwas in der Art gibt. Leider ist das Programm mittlerweile doch so groß, dass eine direkte Suche ohne Anhaltspunkt sehr lange dauern würde. Vielen Dank BAMatze |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Besorge Dir FastMM, lies Dir die Gebrauchsanweisung gut durch, verwende es und fertig.
|
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
@alzaimar: Danke schonmal, dass scheint genau das zu sein, was ich jetzt brauche. habe hier und in Google mal geschaut und folgende 2 Sachen gefunden (
![]() ![]()
Delphi-Quellcode:
Speicherlecks ohne Installation von FastMM finden/ erkennen. Ich verwende hier auf Arbeit D2007 für Win32 Professional. Muss ich jetzt das FastMM installieren (oder ist es eventuell nicht nötig, weil es ja schon der Standardmanager ist)?
{$WARN SYMBOL_PLATFORM OFF}
{$IF RTLVersion > 15.0} ReportMemoryLeaksOnShutDown := DebugHook<>0; {$IFEND} {$WARN SYMBOL_PLATFORM ON} |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Zitat:
|
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
eine etwas abgespeckte FastMM-Version ist bei dir schon im Delphi drinnen
Codegear hatte den alten DelphiMM durch eine einfachere/schnellere FastMM-Version ersetzt. falls du dir mit der Version nicht sicher bist, dann geht auch dieses:
Delphi-Quellcode:
willst du alle Features (Speicheranalyse, besseren Fehlerreport usw.) nutzen, dann mußt du dir aber ein "vollständiges" FastMM installieren.
{$IF Declared(ReportMemoryLeaksOnShutDown}
ReportMemoryLeaksOnShutDown := DebugHook <> 0; {$IFEND} |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Zitat:
Events sind Zeiger auf Methoden. Durch die Zuweisung "OnTischChange := <irgendwas>" weist du diesem Zeiger eine Methode zu, bei "OnTischChange := nil" wird auf keine Methode verwiesen. Da Methoden auch Funktionen mit Rückgabewerten sein können, würde ein Vergleich "if OnEvent <> nil then" nicht prüfen, ob OnEvent eine Methode zugewiesen ist, sondern ob das Funktionsergebnis von OnEvent ungleich nil ist. Daher gibt es die Funktion Assigned, die prüft, ob ein Pointer (in diesem Fall eine Methodenzeiger) auf einen (hoffentlich) gültigen Wert zeigt oder nicht. Bei Klassen-Instanzen oder Pointer auf Records oder einfache Typen ist Assigned(P) das Gleiche wie (P <> nil). Bei Methodenzeigern geht das aus oben genannten Gründen nicht. Und nun sollte auch klar sein, warum nach einem "OnTischChange := nil" natürlich "Assigned(OnTischChange) = false" sein muss. |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Liste der Anhänge anzeigen (Anzahl: 1)
Jetzt bin ich glaube ich vollends verwirrt :shock:
Hab ebend den von himitsu geposteten Quellcode verwendet Resultat -> keine Fehlermeldung nach Beenden des Programmes *grübel Vorher hatte ich den von mir geposteten Quellcode drin Resultat siehe Bild im Anhang. Hab ich da irgendwas übersehen oder falsch gemacht? @Uwe Raabe: Ah gute Erklärung, danke dir dafür. Das mit dem nil, war auch nur mal ein Versuch und ist nach dem nicht funktionieren gleich wieder aus dem Quellcode geflogen und die Implementierung des Events entspricht somit der oben geposteten Variant und funktioniert leider immer noch nicht. :evil: |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
ups :oops:
$if Declared() und nicht $if Defined() |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Liste der Anhänge anzeigen (Anzahl: 1)
jupp jetzt funktioniert es.
ist die FastMM4_Readme.txt = Anleitung? Edit1: ok hab mich jetzt zumindest mal durch alle Anleitungen durchgewurschtelt, die ich hier gefunden hab und auch die Event-Log-Datei erstellt bekommen. Ich glaube gelesen zu haben, dass man diese von unten lesen soll und werde auch versuchen, mittels Auskommentieren, die Probleme zu finden und somit zu beseitigen. Bei einigen Speicherlecks steht ja auch glücklicher Weise drin, wo sie Auftreten, also die Unit. Hänge mal die Log hier an, vieleicht kann ja mal jemand schauen, ob so ein Fehler drin ist (weiß ja nicht, ob man sowas auf einen Blick erkennt), der mir die Probleme bereitet, die zur Post-Topic gehören. Vielen Dank BAMatze |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Ich vermute du hast nicht ganz verstanden was Uwe Raabe dir sagen wollte:
Delphi-Quellcode:
FOnTischChange wird abgerufen und sofort ausgeführt.
if Assigned(OnTischChange) then OnTischChange;
Dann wird geprüft ob das nicht vorhandene Funktionsergebnis ungleich nil ist. Sollte das der Fall sein, wird FOnTischChange erneut abgerufen und ausgeführt.
Delphi-Quellcode:
Es wird geprüft ob FOnTischChange ungleich nil ist.
if Assigned(FOnTischChange) then FOnTischChange;
Sollte das der Fall sein, wird FOnTischChange ausgeführt. Deshalb führt die erste Variante zur Zugriffsverletzung. Unabhängig davon würde ich jedem Event immer den Sender mitliefern. |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Ah ok dann werde ich die Variante auch nochmal testen am Montag. Wobei der Hinweis mit den Speicherlecks und so ja wie ich sehe auch berechtigt war.
Vielen Dank BAMatze |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Also hab heute mal beide Varianten nochmal durchprobiert, sowohl:
Delphi-Quellcode:
also auch
if assigned(OnTischChange) then OnTischChange;
Delphi-Quellcode:
Bei beiden gibt der Debugger als Wert für FOnTischChange/ OnTischChange eine Zugriffsverletzung bei 00000000 aus. Sieht für mich aus, als wenn er sie gar nicht erzeugt. Hab nochmal direkt in die Komponente, in der ich dieses Event implementieren will geschaut und die dcu-Datei kontrolliert, ob sie im Verzeichnis liegt, wo Delphi drauf zugreift. Das scheint zu passen.
if assigned(FOnTischChange) then FOnTischChange;
Kann es aber trotzdem sein, dass dort ein Problem mit dem Erzeugen des Events vorliegt? BAMatze Edit 1: Der Fehler hat sich gerade erledigt. Habe die Komponente nach dem Motto "keep it simple" in eine leere Form mal gezogen und und das Event getestet. Dort funktioniert es wunderbar. Darauf hin habe ich auch im großen Projekt nochmal die Procedure aus dem Objektinspektor und aus der Deklaration gelöscht. Alles kompilieren lassen, so dass die Event-Prozeduren auch wirklich weg waren und dann nochmal neu erzeugen lassen. Jetzt gibt es keine Probleme und das Event wird so erzeugt, wie ich das möchte. Bleibt eigentlich noch nur die Frage: Ist die Auslösung des Events mit OnTischChange (ist die published Variable) oder FOnTischChange (die private Variable)richtig, auf die OnTischChange eigentlich zurück greift? Denke mal FOnTischChange, sonst könnte man die private Variable ja ganz weg lassen, allerdings bin ich da überhaupt nicht sicher. |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Zitat:
Delphi-Quellcode:
procedure TTischSteuerung.TischChange;
begin if Assigned(FOnTischChange) then FOnTischChange; end; |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Das ist schonmal gut zu wissen. Meine Erfahrung besteht ja eigentlich nur daraus, dass ich einige Varianten hier aus der DP genommen hab, die ich gefunden (oder genannt bekommen) habe und dann ausprobiert (wobei meistens noch mindestens so viele Fehler aufgetreten sind, dass ich hier nochmal nachfragen musste). Habe dich jetzt so verstanden, dass ich meine Komponente wie folgt abändern sollte:
Delphi-Quellcode:
Type TTischsteuerung = class(TWinControl)
private ... //Variablen für Events FOnTischChange: TOnTischChange; ... protected //Events // OnTischChange soll dem Programm die Möglichkeit geben alle Eigenschaften auf den // ausgewählten Tisch auszurichten. property OnTischChange: TOnTischChange read FOnTischChange write FOnTischChange; ... published ... public //alternativ könnte auch die property OnTischChange hier aufgeführt sein ... end; // Rest wie am Anfang des Threats, außer dass if assigned(OnTischChange) then OnTischChange; in if assigned(FOnTischChange) then FOnTischChange; geändert wird |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Zitat:
Delphi-Quellcode:
Das Ganze sieht erstmal etwas komplizierter aus aber es bringt viele Vorteile beim erweitern oder debuggen. Außerdem macht es Borland genauso. :-D
{$M+}
TOnTischChange = procedure(Sender: TObject) of object; Type TTischsteuerung = class(TWinControl) private ... //Variablen für Events FOnTischChange: TOnTischChange; ... protected // die event auslöser procedure doTischChange; ... published property OnTischChange: TOnTischChange read FOnTischChange write FOnTischChange; ... public //alternativ könnte auch die property OnTischChange hier aufgeführt sein ... end; procedure TTischsteuerung.doTischChange; begin if Assigned(FOnTischChanged) then FOnTischChanged(self); end; procedure TTischsteuerung.foo begin ... // Event(s) auslösen doTischChange; ... end; |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
möchte mich mal kurz hier einklinken, hoffe dass ich damit nicht gegen eine Regel verstoße.
warum verwendet ihr
Delphi-Quellcode:
für den Event und nicht TNotifyEvent
TOnTischChange = procedure(Sender: TObject) of object;
Danke und Gruß Dieter |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Zitat:
|
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Die Version von TheReaper ist genau richtig! Das mit dem Sender ist zwar nicht notwendig, aber sinnvoll - somit kann dann der Event-Handler feststellen, wer den Event ausgelöst hat, wenn er sich bei mehreren eingeklinkt hat. Die Namensgebung von DoTischChange ist reine Geschmacksache, aber nicht unüblich.
|
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
Ok dann danke ich auf jeden Fall für die Antworten, werde das auf jeden Fall so umsetzen, wie ihr das mir hier ratet. Ich denke auch, dass ich das auslösen von Events mal so gesehen hab, wie ihr das hier nochmal geschrieben habt. Leider hatte ich damals die DCU-Dateien immer in die Projektordner gepackt und nicht bei jeder Änderung immer kopiert. Deswegen hat das nicht richtig funktioniert und ich habe es geändert und irgendwann mal die DCU nachgepackt, was dann zu der verwurschtelten Version von mir führte.
Wo wir aber das Thema schonmal angesprochen haben, habe auch die ein oder andere TNotifyEvent im Projekt drin. Wo liegen denn die Unterschiede? sollte ich nur eins von beiden nehmen? oder gibt es Vorteile des ein oder anderen? |
Re: Event-Typen und warum deren Inhalte manchmal nicht stimm
So benutze diesen Post mal als kleines Danke schön, da es das wie es scheint erste zu einer 4- oder 5-reihigen FastMM-Frage-Serie gehört. Es hat zwar einiges an Arbeit gekostet, die ganzen Speicherlecks (derzeit waren es 105) zu suchen und zu beseitigen aber mit der großen Hilfestellung die mir hier geboten wurde bei der Suche und Lösung, denke ich mal ist 3,5 Tage Zeitinvestition für einen Anfänger nicht schlecht. Das hier gepostete Problem hat sich erfolgreich gelöst, nachdem ich die formal richtige Lösung, die hier gepostet wurde, umgesetzt war.
Ich Liste mal hier kurz die Threats auf, die sich damit erledigt haben (auch in der Erkenntnis, dass immer noch Lecks vorhanden sein können, die sich noch aufgrund von nicht Benutzung mir noch nicht erschließen). ![]() ![]() ![]() und noch der ein oder andere Threat, den ich ebend vergessen hab :-D Vielen Dank an euch :bounce1: :dp: :bounce1: BAMatze |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 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