AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Weitere Tests, die ich gerade noch gemacht habe: ändere ich in der VM die Skalierung von den aktuell 125% auf 150%, dann tritt der Effekt ebenfalls auf. Ändere ich die Skalierung auf 100%, dann tritt der Effekt nicht auf. Ändere ich im Form das Scaled auf "false" (Danke an Edelfix für den Querverweis), dann tritt das Problem nicht mehr auf. Und die Codestelle, die, wenn das Problem auftritt, letztlich verantwortlich ist, ist die folgende Funktion in VCL.Forms:
Delphi-Quellcode:
Die letzte Zeile, also das SetWindowPlacement, ist ein WinAPI-Aufruf, durch den dann letztlich das vorzeitige Activate vom Formular ausgelöst wird.
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var WindowPlacement: TWindowPlacement; begin if WindowState = wsMaximized then begin WindowPlacement.length := SizeOf(WindowPlacement); if GetWindowPlacement(Handle, @WindowPlacement) then begin WindowPlacement.rcNormalPosition.Right := WindowPlacement.rcNormalPosition.Left + MulDiv(WindowPlacement.rcNormalPosition.Width, M, D); WindowPlacement.rcNormalPosition.Bottom := WindowPlacement.rcNormalPosition.Top + MulDiv(WindowPlacement.rcNormalPosition.Height, M, D); SetWindowPlacement(Handle, @WindowPlacement); end; end; end; Soweit mein Stand der Forschung. :-) |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Liste der Anhänge anzeigen (Anzahl: 1)
Zur grundlegenden Frage "welches Ereignis kommt wann" hatte ich mal ein kleines Tool geschrieben das zu Fragen dieser Art vielleicht interessant ist.
Es werden alle in den WindowProcs() der vorhandenen Kompoonenten sowie in Application.OnMessage() ankommenden Botschaften decodiert und auf CodeSite ausgegeben, außerdem "einige" VCL-Ereignisse. Die Schachtelung wird ggf durch das Einrücken angezeigt. Mit den CheckBoxen der rechten Hälfte kann man etwas Selektieren, es kommt sonst sehr viel! Werde das Ganze bei Gelegenheit noch etwas aufhübschen und mit Quellen hier posten. Wie oben schon gesagt: CodeSite wird benötigt. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Bei meinem Windows (10.0.17763 Build 17763) und Delphi (10.3 Version 26.0.33219.4899) gleich.
Ich benötige auch nur - wie weiter oben beschrieben wird - 2 Formulare und nur 1 Monitor für Activate vor Create. Erstes Formular: nix ändern Zweites Formular: WindowsState=wsMaximized Wenn ich das nun mit Anzeigeeinstellung >100% laufen lasse, dann werden beide Formulare angezeigt. Beim ersten Formular wie erwartet: Create vor Activate. Beim zweiten Formular: Wider Erwarten wird es angezeigt und Activate vor Create. Formular 2 lässt sich nicht schliessen. (Create 1 -> Activate 2 -> Create 2 -> Activate 1) Wenn ich Anzeigeeinstellung 100% wähle, dann wird wie erwartet nur Formular 1 angezeigt. Wenn ich für Formular 2 Scaled=FALSE setze, dann funktioniert's unabhängig von der Anzeigeeinstellung wie erwartet. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Da fehlt eine Abfrage auf
Delphi-Quellcode:
. Das müsste so lauten:
HandleAllocated
Delphi-Quellcode:
if (WindowState = wsMaximized) and HandleAllocated then
begin |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Genau... Uwe war schneller.. ;-)
Es reicht natürlich auch nur ein Formular und ein Monitor und windowstate=wsmaximized für Activate vor Create. Wenn skaliert wird, dann biegt man hier ab:
Delphi-Quellcode:
und landet da:
procedure TCustomForm.ScaleForCurrentDpi;
if ShouldScale(self) then
Delphi-Quellcode:
Aber da ist das Formular noch im state fsCreating.
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var WindowPlacement: TWindowPlacement; begin if WindowState = wsMaximized then SetWindowPlacement(Handle, @WindowPlacement); // => OnActivate |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Hoi Uwe
zu deinem Vorschlag
Delphi-Quellcode:
HandleAllocated ist bei meinem Delphi bereits TRUE.
if (WindowState = wsMaximized) and HandleAllocated then
begin Es wird deshalb weiterhin Activate vor Create ausgelöst. Ich schlage deshalb vor:
Delphi-Quellcode:
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var WindowPlacement: TWindowPlacement; begin if ( WindowState = wsMaximized ) and not ( fsCreating in FFormState ) then begin |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Wenn ich das richtig sehe, dann gibt es den passenden Eintrag im QP sogar schon (allerdings ohne Lösungsvorschlag):
https://quality.embarcadero.com/browse/RSP-23179 Ich werde mal die Erkenntnisse hier aus der Diskussion ergänzen. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Ich frage mich, ob dieses ScaleNormalSize dort überhaupt immer aufgerufen werden muss. Das ist doch eh nur sinnvoll, wenn das Form beim DPI change bereits sichtbar ist. Vielleicht wäre eine diesbezügliche Abfrage da eher sinnvoll. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Wann tritt dieser Fehler denn jetzt genau auf? Es gibt hier soviele Ideen, Vorschläge und Nachbildungen des Fehlers, dass ich nicht mehr durchblicke.
Weiter oben kam dann auch noch Scaled := False hinzu, was die Verwirrung komplett macht. Soll man Scaled nicht so oder so immer auf False stellen? Ich benutze grundsätzlich immer Form123.ScaleBy(Screen.PixelsPerInch, originale-auflösung-während-der-entwicklung); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:59 Uhr. |
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