AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Exception in IsFormSizeStored

Ein Thema von BlueStarHH · begonnen am 13. Apr 2021 · letzter Beitrag vom 28. Feb 2024
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.318 Beiträge
 
Delphi 12 Athens
 
#1

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 13:49
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;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (13. Apr 2021 um 13:59 Uhr)
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
855 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 14:10
Das sagt die Delphi-Hilfe:

Code:
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.
Quelle: http://docwiki.embarcadero.com/Libra...m.TObject.Free
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.318 Beiträge
 
Delphi 12 Athens
 
#3

AW: Exception in IsFormSizeStored

  Alt 13. Apr 2021, 14:25
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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
ECHTERNMM

Registriert seit: 29. Sep 2004
Ort: Jena
6 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Exception in IsFormSizeStored

  Alt 27. Feb 2024, 10:59
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

Geändert von ECHTERNMM (27. Feb 2024 um 11:11 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
386 Beiträge
 
#5

AW: Exception in IsFormSizeStored

  Alt 27. Feb 2024, 11:32
Hi

Zitat:
was ist das und wo kommt das her?
Its usage in in the name, callback from the kernel, essential and everywhere, in essence it is you main thread loop origin.

Zitat:
And above all: how can you prevent this?
If you are talking about KiUserCallbackDispatcher, then the answer is no you can't prevent passing or remove it from your application logic using GUI.

Now to the discuss the call stack you provided:

I can see the problem pinpoint it
Zitat:
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
005c755 0 +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 // Creating Handle for most likely already freed parent or owner
005cbbe0 +01c My_ Prog.exe Vcl .Controls TWinControl.HandleNeeded
005cbbed + 005 My_Prog.exe Vcl .Controls TWinControl.GetHandle // GetHandle
006cf205 +0f1 My_Prog.exe Vcl .Forms TCustomForm.SetFocusedControl // <----- Oops !! the code is trying to set focus to another form or a component !!
005c872f +21f My_Prog.exe Vcl .Controls TWinControl.WndProc
006ccc61 +64d My_Prog.exe Vcl .Forms TC ustomForm.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 // <------- more messages after the destruction
7751507b +04b ntdll.dll KiUserCallbackDispatcher
0040a8c4 +008 My_Prog.exe System 168 +0 TObject.Free // <------- last free before end the destruction
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
I may be wrong but from what i see it is a SetFocus called without checking for free/exiting...
If you had a decent logging you could have found it earlier, when forms/frames/modules report creation and destruction.

Hope that helps.
Kas
  Mit Zitat antworten Zitat
ECHTERNMM

Registriert seit: 29. Sep 2004
Ort: Jena
6 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Exception in IsFormSizeStored

  Alt 28. Feb 2024, 17:06
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
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.318 Beiträge
 
Delphi 12 Athens
 
#7

AW: Exception in IsFormSizeStored

  Alt 28. Feb 2024, 17:34
Zitat:
Oops !! the code is trying to set focus to another form or a component
Wenn die Komponente/Form freigegeben wird, welche aktuell den Focus besitzt, dann wird der Focus an den Nächsten weitergegeben.

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.



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")
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (28. Feb 2024 um 17:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:41 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 by Thomas Breitkreuz