![]() |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Danke für die Demo.
Zitat:
Sieht gut und verständlich aus. Vom Prinzip her genau wie mein OnPaint-Ansatz, nur dass du mit deiner Umsetzung keine nervige Variable brauchst, um dir den Status zu merken. Hat Vorteile die nicht mehr zu haben finde ich. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Hmm..
Kannst das Test-Tool ja mal gegen deine VMs testen und sehen, wann dort das 'AfterShow' kommt. Eventuell eine bessere Alternative, wenn das OnActivate kommt, wann es will ;) |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Verstehe nicht was du damit sagen möchtest?
Ist es OS-abhängig, ob dein Ansatz funktioniert oder nicht? Edit spät in der Nacht einen Nachteil habe ich wohl gefunden. Wenn man ein Programm mit diesem Mechanismus ins Systemtray minimiert und zurückholt, wird DoAfterShow trotzdem wieder ausgeführt. Um eine Zwischenvariable kommt man also in beiden Fällen nicht drumherum. Außer man minimiert das Programm niemals in den Systemtray. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Hmm..
Also, wenn ich meine D6 Applikation minimiere und dann wieder hochhole wird bei mir nur OnPaint aufgerufen, jedoch kein OnShow und somit kein AfterShow. (Windows 8.1 64Bit auf Notebook) Ich dachte es geht um OnActivate VOR OnShow? Es sollte doch in der VM falsch sein... Teste mal mit meinem Tool, ob auch dort AfterShow vor OnCreate kommt... |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Ich habe dort dieselben Ergebnisse bekommen wie unter dem Windows 10 Host. Zitat:
Zum Minimieren: ich meine zum Systemtray, also komplett weg aus der Taskleiste und nur noch ein kleines Icon im Statusbereich. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Der Hinweis auf das SetFocusControl und die DPI Umrechnung ist ja durchaus hilfreich. Ohne einen reproduzierbaren Testfall ist es aber nahezu unmöglich den Fehler zu lokalisieren und zu beheben. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Aktuell habe ich auf besagte Monitor-Kombination keinen Zugriff (Geschäfts-Monitor), aber beim testen mit zwei unterschiedlichen Notebooks (W10, HD-Auflösung) kann ich das Problem problemfrei nachstellen. Zitat:
Schlussendlich scheint die Kombination HD/4k keinen Einfluss zu haben, es reicht zumindest bei mir aus, wenn die Auflösung > 100% (> 96 DPI) ist. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
|
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):
![]() 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); |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Zitat:
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Delphi-Quellcode:
Hallo Uwe
OK! Ich kann das hier immer noch nicht reproduzieren bzw. hatte noch keine Zeit eine passende VM zu erstellen.
Ich nutze dazu keine VM, sondern ein Notebook mit einem "normalen" Windows Home mit Anzeige Skalierung 125%, ohne zweiten Monitor Windows Home Version 10.0.17763 Build 17763 und Delphi 10.3 Version 26.0.33219.4899 (Ich wiess grad nicht, ob es da bereits ein Update gab (?) und damit vielleicht bereits einen Fix.) |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Wenn eine automatische Größenveränderung / -berechnung eines Formulares durchzuführen ist, ist mit dem Auftreten eines Fehlers (falscher Abfolge der Ereignisse OnCreate und OnActivate), bedingt durch den Aufruf von ![]() |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
- Primär Monitor (4k) auf 100%, Sekundär > 100% -> Kein Fehler feststellbar - Primär Monitor (4k) > 100%, Sekundär >= 100% -> Der Fehler tritt auf - Notebook mit HD-Auflösung -> Sobald die Skalierung >100% ist, tritt der Fehler auf - Wenn beim Minimalbeispiel (2 Forms) beim Form2 "wsMaximized" und "Scaled = False" eingestellt ist, wird das Form2 nicht angezeigt. - Der Fehler tritt grundsätzlich auch bei W7 Pro auf - Bei 10.2.3 tritt der Fehler auch auf, wenn aber der Patch von Uwe eingespielt ist, funktioniert es wie gewohnt. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Wenn ich den Code in VCL.Forms und VCL.Controls korrekt lese, dann tritt Activate vor Create auf, wenn WindowState=wsMaximized gesetzt wird, Scaled=TRUE belassen wird, mindestens Windows 6.3 installiert ist und wenn
Winapi.Windows.USER_DEFAULT_SCREEN_DPI <> GetCurrentPPIScreen( ) Bei meinem System: Winapi.Windows.USER_DEFAULT_SCREEN_DPI 96 GetCurrentPPIScreen( ) 120 => procedure TCustomForm.ScaleNormalSize(M, D: Integer); wird aufgerufen und damit, weil WindowState = wsMaximized dann irgendwann SetWindowPlacement(Handle, @WindowPlacement); => OnActivate Falls jemand nach der Änderung (Code unten) (and not ( fsCreating in FFormState)
Delphi-Quellcode:
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var WindowPlacement: TWindowPlacement; begin if ( WindowState = wsMaximized ) and not ( fsCreating in FFormState ) then begin noch Probleme hat, dann suche ich noch einmal :-D. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Aber einfach and not ( fsCreating in FFormState in der offiziellen Emba-Unit in TCustomForm.ScaleNormalSize einfügen und damit sollte es gut sein? Darf ich das als CE_Nutzer überhaupt? :lol: |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
Testweise habe ich die 32-Bit VCL-Version neu kompiliert und das Minimalbeispiel mit zwei Formularen funktionierte bei meinem Testrechner (Laptop mit HD Auflösung) wie erwartet :-) |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Wie pflegt man die Änderung ein? Einfach in die Unit schreiben, speichern und vorhandene Projekte bereinigen + kompilieren?
|
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
In der Regel verwende ich für solche gepatchten Delphi Units entweder das Projektverzeichnis oder ein dediziertes Unterverzeichnis. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Dann lasse ich alles so wie es ist statt rumzufummeln und warte auf ein offizielles Update.
Denn irgendwann ist die gepatchte Unit auch wieder veraltet und nicht mehr up to date und dann hat man doppelte oder dreifache Arbeit. |
AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt
Zitat:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:16 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