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 Problem mit TNotifyEvent (https://www.delphipraxis.net/43251-problem-mit-tnotifyevent.html)

Gambit 31. Mär 2005 13:32


Problem mit TNotifyEvent
 
Hallo,

ich möchte, wenn ich auf eine CheckBox klicke, dann wenn sie angehakt wird, eine Form2 öfnnen.
Ob die Checkbox angeklickt ist oder nicht, speichere ich in einer Ini-Datei. Damit wird der Zustand der Checkbox beim Aktivieren der Form1, auf der die CheckBox liegt, wiederhergestellt. Da ich aber nicht möchte, dass die Form2, die durch Klicken auf die Checkbox geöffnet werden soll, jedesmal geöffnet wird wenn ich die Form1 auf der die Checkbox liegt öffne, (das passiert, wenn der Defaultwert der Checkbox von dem aus der Ini-Datei abweicht, weil dann ein OnClick-Ereignis ausgelöst wird), lege ich das OnClick-Ereignis der Checkbox temporär auf eine Variable vom Typ TNotifyEvent (foo), und weise der CheckBox den Wert aus der Ini-Datei zu:

Auszug aus der OnActivate-Procedur von Form1

Delphi-Quellcode:
foo := ChkBox1.OnClick;
ChkBox1.OnClick := nil;
ChkBox1.Checked:= ini.IniCheckBox1Value;
ChkBox1.OnClick := foo;
das funzt auch.

wenn ich aber weiter im OnActivate-Ereignis der Form1 eine Procedur aufrufe, die ebenfalls ein Ereignis temporär auf ein TNotifyEvent legt, hier aber die Variable foo lokal benutzt, bekomme ich eine Speicherschutzverletzung.

Delphi-Quellcode:
procedure TFormSettings.setIP_Values(AddressField: TJvIPAddress; IP_String: String; var val: array of String);
var foo : TNotifyEvent;
begin
  foo := AddressField.OnChange;
  AddressField.OnChange := nil;
  for i:= 1 to length(val) do
  begin
    ...
  end;
  AddressField.OnChange := foo;
end;

Warum das? Lege ich die Variable foo als globale Variable der Klasse an, funzt auch alles.

Gruß

Gambit

teebee 31. Mär 2005 14:09

Re: Problem mit TNotifyEvent
 
Bist Du sicher, dass die Schutzverletzung im Zusammenhang mit der lokalen Variablen auftritt? Auf den ersten Blick ist das so nämlich in Ordnung. Allerdings gehst Du von 1 bis Length durch das dynamische Array. Arrays fangen bei aber bei 0 an dementsprechend müsstest Du eigentlich von 0 bis Length-1 gehen (oder von Low bis High). Das sieht jedenfalls eher nach einer Schuztverletzung aus.

Gruß, teebee

Gambit 31. Mär 2005 14:12

Re: Problem mit TNotifyEvent
 
es funzt ja alles, wenn ich foo als Private-Variable der Klasse deklariere. An der Prozedur liegt es nicht, die funzte vorher auch schon...

teebee 31. Mär 2005 14:19

Re: Problem mit TNotifyEvent
 
Trotzdem ist der Zugriff auf das Array so höchstwahrscheinlich nicht ok. Es sei denn Du indizierst immer über i-1. Man kann zwar auch ohne Schutzverletzung über die Grenzen von Arrays schreiben, je nachdem, was noch im Speicher kommt, sollte so aber nicht stehenbleiben.
An welcher Stelle kommt denn die AV genau?

Gambit 31. Mär 2005 14:32

Re: Problem mit TNotifyEvent
 
Tja, das ist schon merkwürdig. Jetzt habe ich mal von
Delphi-Quellcode:
i:= 0 to length(val)-1
geschrieben und es klappt tatsächlich jetzt.
Raff ich allerdings nicht so richtig, was das eine mit dem anderen zu tun hat...

teebee 31. Mär 2005 14:42

Re: Problem mit TNotifyEvent
 
Du hast irgendwo in Speicher geschrieben, der Dir nicht gehört hat. Je nachdem, wo Du foo deklariert hast, war hinter dem Speicherbereich des Arrays entweder Dein foo oder eben nicht reservierter Speicher. (Naja, meine Theorie...) Wahrscheinlich hast Du mit dem Überschreiten der Grenze Dein foo überschrieben, was aber scheinbar ok war, weil es ja Speicher war, der von Dir reserviert wurde, aber foo wird dann nicht mehr den richtigen Wert gehabt haben.
Genau kann man halt nie wissen, wo man hinkommt, wenn man irgendwo reinschreibt, wo man nicht sollte.
Du kannst während der Testphase die Bereichsüberprüfung einschalten {$R+}.

Gruß, teebee

Gambit 31. Mär 2005 15:43

Re: Problem mit TNotifyEvent
 
ich hatte gedacht wenn ich eine Array so definiere:

Delphi-Quellcode:
IP_values: array[1..4] of String;
könnte ichs auch mit
Delphi-Quellcode:
for i:= 1 to 4 do
durchlaufen...hab ich wohl falsch gedacht...

Muetze1 31. Mär 2005 15:54

Re: Problem mit TNotifyEvent
 
Moin!

Nein, das ist richtig. Wenn du es so definiert hast, dann kannst du es auch so durchlaufen.

Aber: Length() liefert dir die Anzahl der Einträge und nicht den höchsten Index. Daher nutze lieber Low() und High() und du bist bei egal welchem Array auf der sicheren Seite - egal ob dynamisch oder statisch. Auch egal ob das statische Array bei 100 als kleinster Index anfängt.

MfG
Muetze1

sakura 31. Mär 2005 15:58

Re: Problem mit TNotifyEvent
 
Liste der Anhänge anzeigen (Anzahl: 1)
Anbei mal eine Unit, welche das Problem löst. Binde diese Unit in Dein Programm ein und rufe die Prozedur SetCheckBoxSilent auf. Der erste Parameter ist die CheckBox, der zweite ist der neue Wert.

Die Details schreibe ich in einen neuen CL-Beitrag :zwinker:

...:cat:...

sakura 31. Mär 2005 16:10

Re: Problem mit TNotifyEvent
 
Hier ist der CL-Eintrag mit Erklärungen: Wert einer Checkbox ändern, ohne OnClick Handler auszulösen

...:cat:...


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