![]() |
Exception in IsFormSizeStored
Ich habe dieses Exception Log (Aufrufreihenfolge von unten nach oben) von einem Anwender:
exception class : EAccessViolation exception message : Zugriffsverletzung bei Adresse 006DA5BF in Modul 'MeinProgramm.exe'. Lesen von Adresse 00000010.
Code:
006da5bf +00f MeinProgramm.exe Vcl.Forms TCustomForm.IsFormSizeStored
006da5a5 +005 MeinProgramm.exe Vcl.Forms TCustomForm.IsClientSizeStored 006dce58 +5a4 MeinProgramm.exe Vcl.Forms TCustomForm.CreateParams 005d4700 +034 MeinProgramm.exe Vcl.Controls TWinControl.CreateWnd 006d88f1 +005 MeinProgramm.exe Vcl.Forms TScrollingWinControl.CreateWnd 006dced2 +00a MeinProgramm.exe Vcl.Forms TCustomForm.CreateWnd 006e33e0 +024 MeinProgramm.exe Vcl.Forms TApplication.ModalFinished 006e0062 +326 MeinProgramm.exe Vcl.Forms TCustomForm.ShowModal 005d4d12 +016 MeinProgramm.exe Vcl.Controls TWinControl.CreateHandle 005d8d90 +01c MeinProgramm.exe Vcl.Controls TWinControl.HandleNeeded 005d8d9d +005 MeinProgramm.exe Vcl.Controls TWinControl.GetHandle 006dfd2e +00e MeinProgramm.exe Vcl.Forms TCustomForm.Release <--- hier !!!! 01992e72 +0b6 MeinProgramm.exe Main 4814 TMainDlg.ShowAbrechnungDlg 01989cbb +003 MeinProgramm.exe Main 2385 TMainDlg.acAbrechnungExecute disassembling: [...] 01992e62 pop ecx 01992e63 mov fs:[eax], edx 01992e66 push $1992e7f 01992e6b 4814 mov eax, [$1a3f2e4] 01992e70 mov eax, [eax] 01992e72 > call -$12b3157 ($6dfd20) ; Vcl.Forms.TCustomForm.Release 01992e77 ret 01992e78 jmp -$15880ad ($40add0) ; System.@HandleFinally 01992e7d jmp loc_1992e6b 01992e7f 4820 xor eax, eax 01992e81 pop edx [...]
Code:
procedure TMainDlg.ShowAbrechnungDlg;
begin Application.CreateForm(TAbrechnungDlg, AbrechnungDlg); try AbrechnungDlg.ShowModal; finally AbrechnungDlg.Release; <--- hier !!!! end; end; Wer kann helfen. Es sagt mir überhaupt nichts. Es scheint so, als ob eine Action (acAbrechnungExecute) ausgeführt wurde, die ein Fenster anzeigt (AbrechnungDlg). Nach dem Schleißen wird das Release (mit "hier" markiert) ausgeführt und ruft wieder ein ShowModal auf??? Das passiert direkt im VCL-Code. Nicht in meinem Code. Meine Unit ist nur die "Main". Das Problem ist in mehr als 10 Jahren noch nie bei einem anderen Anwender aufgetreten und trat bei diesem Anwender bisher auch nicht wieder auf. Weitere Infos gibt es leider nicht. |
AW: Exception in IsFormSizeStored
Du solltest besser Free anstatt Release verwenden. Release sollte lediglich in den Events des Forms verwendet werden, da es die Freigabe verzögert. Das ist in deinem Fall aber nicht nötig und auch nicht erwünscht.
|
AW: Exception in IsFormSizeStored
Zitat:
|
AW: Exception in IsFormSizeStored
Die VCL hat nach dem ShowModal das Windows-Control (HWND) der nicht mehr sichtbaren TForm bereits freigegeben.
Im Release wird aber auf das Handle zugegriffen *1 und weil es nicht mehr da ist, wird das Windows-Control neu erstellt, um danach erneut freigegeben zu werden. Da gibt es wohl ein kleines Problemchen. 1) das Handle wird gebraucht, um dem Fenster eine Message zu schicken "gib dich frei", was aber erst "irgendwann" nach dem letzten END; ausgeführt wird, sobald die VCL jene Message verarbeitet. Und Free gibt direkt frei, ohne unnötige Umwege. Es passiert nicht immer, aber in der VCL ist es möglich die gekapselten Windows-Controls freizugeben, wenn sie nicht benötigt werden, um Systemressourcen zu sparen. Und hier passiert es zufällig mal. Das ist z.B. der Grund, warum manchmal Dinge "verschwinden", welche man selbst direkt über die WinAPI gemacht hat, weil beim Wiederherstellen die VCL davon natürlich nichts weiß. Und warum für eine lokale Sache diese besch*** globalen Variablen benutzen? Am Besten löscht man diese Variablen und kommt dann garnicht erst auf die Idee sie verwenden zu wollen.
Delphi-Quellcode:
procedure TMainDlg.ShowAbrechnungDlg;
var Dlg: TAbrechnungDlg; begin Dlg := TAbrechnungDlg.Create(nil); // oder mit Self statt nil try Dlg.ShowModal; finally Dlg.Free; end; end; // ab 10.4 procedure TMainDlg.ShowAbrechnungDlg; begin var Dlg := TAbrechnungDlg.Create(nil); // oder mit Self statt nil try Dlg.ShowModal; finally Dlg.Free; end; end; |
AW: Exception in IsFormSizeStored
Das sagt die Delphi-Hilfe:
Code:
Quelle:
To free a form, call its Release method, which destroys the form and releases the memory allocated for it after all its event handlers and those of the components it contains are through executing.
![]() |
AW: Exception in IsFormSizeStored
Wenn der Dialog nach dem Anzeigen Ausblenden keine "wichtigen" Messages mehr zu verarbeiten hat, dann ist ein Free OK und man als Entwickler weiß "JETZT ist es weg und nach mir kommt nichts mehr von diesem Objekt".
Der Dialog hat nicht zufällig sowas wie ein FreeOnClose? Oder irgendwelche "komischen" Codes in OnCloseQuery, OnClose, OnHide, OnDeactivate, OnDestroy oder Dergleichen? Hier sieht es ja fast so aus, als wenn das "ShowModal" nach/in dem Release nochmals neu aufgerufen würde. |
AW: Exception in IsFormSizeStored
Hallo,
gibt es dazu irgendwelche neuen Erkenntnisse? Wir verwenden immer schon free (nicht release), haben aber gelegentlich genau den gleichen Fehler. Ich verwende eine Komponente, die von TCustomElComboBox abgeleitet ist: TMyComboBox; die ist eins der Controls der Form, die ich freigeben will. Ich habe den Destructor dieser Komponente "übernommen" (overload) und darin nichts anderes als try inheritted; except //meldung in Log-Datei schreiben end; eingebaut, aber, wie man sieht, wird der Destructor zwar ausgeführt, aber die Exception entsteht gar nicht in dieser Routine, obwohl der Stackdump (von Madexcept) das suggeriert. Vielmehr schein Windows zu meinen, hier irgendwie eingreifen zu müssen: 7751507b +04b ntdll.dll KiUserCallbackDispatcher was ist das und wo kommt das her? Und vor allem: wie kann man das verhindern? Man sollte noch wissen, dass diese Exception nicht reproduzierbar entsteht, sondern scheinbar zufällig ungefähr in 20 von 100 Fällen. Gruß MM 006cc0ef +00f My_Prog.exe Vcl.Forms TCustomForm.IsFormSizeStored 006cc0d5 +005 My_Prog.exe Vcl.Forms TCustomForm.IsClientSizeStored 006ce988 +5a4 My_Prog.exe Vcl.Forms TCustomForm.CreateParams 005c7550 +034 My_Prog.exe Vcl.Controls TWinControl.CreateWnd 006ca421 +005 My_Prog.exe Vcl.Forms TScrollingWinControl.CreateWnd 006cea02 +00a My_Prog.exe Vcl.Forms TCustomForm.CreateWnd 005c7b62 +016 My_Prog.exe Vcl.Controls TWinControl.CreateHandle 005cbbe0 +01c My_Prog.exe Vcl.Controls TWinControl.HandleNeeded 005cbbed +005 My_Prog.exe Vcl.Controls TWinControl.GetHandle 006cf205 +0f1 My_Prog.exe Vcl.Forms TCustomForm.SetFocusedControl 005c872f +21f My_Prog.exe Vcl.Controls TWinControl.WndProc 006ccc61 +64d My_Prog.exe Vcl.Forms TCustomForm.WndProc 00bae796 +05e My_Prog.exe Main 945 +14 TWomiTota.WndProc 005c8118 +02c My_Prog.exe Vcl.Controls TWinControl.MainWndProc 00543edc +014 My_Prog.exe System.Classes StdWndProc 0040f6b0 +20c My_Prog.exe System 168 +0 DynArraySetLength 7751507b +04b ntdll.dll KiUserCallbackDispatcher 005c3f66 +2be My_Prog.exe Vcl.Controls TControl.WndProc 005c8b4b +63b My_Prog.exe Vcl.Controls TWinControl.WndProc 006ccc61 +64d My_Prog.exe Vcl.Forms TCustomForm.WndProc 00bae796 +05e My_Prog.exe Main 945 +14 TWomiTota.WndProc 005c8118 +02c My_Prog.exe Vcl.Controls TWinControl.MainWndProc 00543edc +014 My_Prog.exe System.Classes StdWndProc 7751507b +04b ntdll.dll KiUserCallbackDispatcher 0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free 00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil 00820ea3 +01b My_Prog.exe ElSBCtrl 3377 +2 TElSBHandlerCustom.DestroyScrollTimer 00820e63 +07f My_Prog.exe ElSBCtrl 3370 +9 TElSBHandlerCustom.Destroy 0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free 00460ee0 +008 My_Prog.exe System.SysUtils FreeAndNil 0082249b +017 My_Prog.exe ElSBCtrl 4165 +1 TElSBController.Destroy 0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free 00541bec +074 My_Prog.exe System.Classes TComponent.DestroyComponents 0054168b +01b My_Prog.exe System.Classes TComponent.Destroy 005c12d9 +121 My_Prog.exe Vcl.Controls TControl.Destroy 005c5dbf +16b My_Prog.exe Vcl.Controls TWinControl.Destroy 005cee90 +01c My_Prog.exe Vcl.Controls TCustomControl.Destroy 007d3544 +034 My_Prog.exe ElXPThemedControl 439 +3 TElXPThemedControl.Destroy 00842a1f +037 My_Prog.exe ElListBox 789 +4 TCustomElListBox.Destroy 0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free 00857ede +01a My_Prog.exe ElCombos 1626 +1 TCustomElComboBox.Destroy 00b3c80a +06a My_Prog.exe eboxen 2488 +10 TMyComboBox.Destroy |
AW: Exception in IsFormSizeStored
Hi
Zitat:
Zitat:
Now to the discuss the call stack you provided: I can see the problem pinpoint it Zitat:
If you had a decent logging you could have found it earlier, when forms/frames/modules report creation and destruction. Hope that helps. |
AW: Exception in IsFormSizeStored
Hi,
Thank you for your hints, but its difficoult to determin, where the strange SetFocus-Message come from. The Problem is, that - as already mentioned by BlueStarHH - it does not occur for years but suddenly now. There is a process, that is repeated - say 100 times a day - on the same machine, same user, same setting, but in about 20 cases the error occur, in about 80 cases not. On mine own machine I could not reproduce it at all. There are also other machines, where it occur only once a month or so, nevertheless, they use it also many times a dayx. It looks like, thats a strange Windows probnlem, because machines, where it occur more often, are updated recently, What do you mean by "decent logging"? Shall I catch all setfocus messages and write them to a logfile? But that would also not show, where they come from... Regards MM |
AW: Exception in IsFormSizeStored
Zitat:
Verliert eine Anwendung komplett den Fokus, dann verliert sie die Eingabekontrolle und wird von Windows in den Hintergrund verschoben. (hinter Fenster anderer Anwendungen) z.B. beim Anzeigen eines Dialogs oder ShowModal einer Form, merkt sich Delphi welches Fenster aktuell vorher aktiv war und beim Close wird versucht an jenes Fenster den Fokus "zurück" zu übergeben ... besonders gut funktioniert das, wenn dieses Fenster inzwischen auch nicht mehr existiert oder nicht fokusierbar ist. :freak: Wurde das SetFocus durch ein PostMessage ausgelöst, dann kann man den Sender eh nicht mehr rausbekommen, welcher das vor einer "Weile" in die MessageQueue schrieb. Beim SendMessage wäre es eigentlich möglich, aber der Stacktrace im GetMessage/PeekMessage verläuft sich gern und dann bricht der Stack meistens mittendrin ab, so dass man da auch nichts sieht. Wurde der Focus durch eine programmseitige Aktion in der VCL ausgelöst, also durch Aufruf von Control.SetFocus oder Zuweisung an Form.ActiveControl bzw. Screen.ActiveControl oder beim Wechsel der VCL-Forms, dann sollte man die Stelle im Debugger/Stacktrace finden können, was aber auch nicht immer funktioniert. Leider gibt es nicht nur ein einziges SetFocus und sie nutzen keine gemeinsamme, globale Funktion, so dass man nur die DebugDCUs in den Projektoptionen aktivieren kann und dann auf "alle" SetFocus einen Haltepunkt setzen müsste. Ich wollte mal "dem" SetFocus beibringen den Namen der VCL-Komponente in die Fehlermeldung zu schreiben, damit man wenigstens das Ziel erfährt und nicht nur sowas wie "Ein inaktives Control kann keinen Focus erhalten", weil irgendwo ein SetFocus aufgerufen wird, obwohl das Control, ein Parent oder die Form disabled oder invisible sind. Das war echt ein Vorhaben, wo man fast nur aufgeben kann. (und Emba sich weigert dieses Verhalten zu "reparieren") |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:14 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