AGB  ·  Datenschutz  ·  Impressum  







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

10.3.1: OnActivate wird vor OnCreate ausgeführt

Ein Thema von Bbommel · begonnen am 21. Mär 2019 · letzter Beitrag vom 26. Mär 2019
Antwort Antwort
Seite 6 von 8   « Erste     456 78      
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
655 Beiträge
 
Delphi 12 Athens
 
#51

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 08:57
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.
Jepp, das sehe ich ähnlich, daher habe ich auch noch nichts bei Emba gemeldet bisher. Da es in einem anderen Thread (nicht von mir) Thema war, bei dem es auch um die Kombination Rio+Win8.1 ging, hier noch der Hinweis, dass es der VMware Workstation Player in der Version 12 ist. Windows ist die Version 6.3 Build 9600.

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:
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;
Die letzte Zeile, also das SetWindowPlacement, ist ein WinAPI-Aufruf, durch den dann letztlich das vorzeitige Activate vom Formular ausgelöst wird.

Soweit mein Stand der Forschung.
  Mit Zitat antworten Zitat
DenkDirNix

Registriert seit: 13. Dez 2018
69 Beiträge
 
Delphi 11 Alexandria
 
#52

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 11:25
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.
Angehängte Dateien
Dateityp: zip WinMessages.zip (3,61 MB, 4x aufgerufen)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#53

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 11:36
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.
Michael Gasser

Geändert von Michael II (25. Mär 2019 um 11:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#54

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 11:56
Delphi-Quellcode:
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var
  WindowPlacement: TWindowPlacement;
begin
  if WindowState = wsMaximized then
  begin

Da fehlt eine Abfrage auf HandleAllocated . Das müsste so lauten:
Delphi-Quellcode:
  if (WindowState = wsMaximized) and HandleAllocated then
  begin
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
655 Beiträge
 
Delphi 12 Athens
 
#55

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 12:04
Da fehlt eine Abfrage auf HandleAllocated .
Danke! Das heißt, das könnte man dann so mit dem Lösungsvorschlag bei Emba melden, oder?
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#56

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 12:19
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:
procedure TCustomForm.ScaleForCurrentDpi;

    if ShouldScale(self) then
und landet da:

Delphi-Quellcode:
procedure TCustomForm.ScaleNormalSize(M, D: Integer);
var
  WindowPlacement: TWindowPlacement;
begin
  if WindowState = wsMaximized then

   SetWindowPlacement(Handle, @WindowPlacement); // => OnActivate
Aber da ist das Formular noch im state fsCreating.
Michael Gasser
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#57

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 12:36
Hoi Uwe

zu deinem Vorschlag

Delphi-Quellcode:
if (WindowState = wsMaximized) and HandleAllocated then
  begin
HandleAllocated ist bei meinem Delphi bereits TRUE.


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
Michael Gasser
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
655 Beiträge
 
Delphi 12 Athens
 
#58

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 12:37
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#59

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 12:52
HandleAllocated ist bei meinem Delphi bereits TRUE.
OK! Ich kann das hier immer noch nicht reproduzieren bzw. hatte noch keine Zeit eine passende VM zu erstellen.

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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#60

AW: 10.3.1: OnActivate wird vor OnCreate ausgeführt

  Alt 25. Mär 2019, 13:14
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);
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 6 von 8   « Erste     456 78      


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 14:58 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