AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

Ein Thema von Michael II · begonnen am 24. Okt 2021 · letzter Beitrag vom 27. Okt 2021
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 25. Okt 2021, 08:35
TControl.GetSystemMetrics verwendet die DPI-konforme Version GetSystemMetricsForDPI wenn die Anwendung als Per Monitor V2 aware läuft, ansonsten die normale GetSystemMetrics Version. Dies entspricht der Empfehlung in der Windows Dokumentation zu GetSystemMetrics:
Zitat:
This API is not DPI aware, and should not be used if the calling thread is per-monitor DPI aware. For the DPI-aware version of this API, see GetSystemMetricsForDPI.
Delphi liefert da also exakt die Werte zurück, die Windows bei der jeweiligen Funktion zurückliefert. Umgerechnet wird da gar nichts.

Wenn also Windows.GetSystemMetrics und TControl.GetSystemMetrics unterschiedliche Werte liefern, dann weil die Anwendung sich als Per Monitor V2 aware registriert. In dem Fall ist aber der Aufruf von Windows.GetSystemMetrics schlichtweg falsch. Microsoft schweigt sich auch aus, wie die Rückgaben von Windows.GetSystemMetric bei solch falscher Verwendung aussehen. Das kann vom Windows-Build oder auch von der Skalierung des Monitors abhängen, auf dem das abfragende Control gerade dargestellt wird.

In jedem Fall liefert aber TControl.GetSystemMetrics den korrekten Wert und ist demnach vorzuziehen.

Ich gehe mal davon aus, dass sowohl die Delphi 10.4 als auch die Delphi 11 Exe auf demselben Windows und demselben Monitor gestartet wurden. Andernfalls wären Unterschiede durchaus zu erwarten.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Michael II

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 25. Okt 2021, 23:07
Wenn also Windows.GetSystemMetrics und TControl.GetSystemMetrics unterschiedliche Werte liefern, dann weil die Anwendung sich als Per Monitor V2 aware registriert. In dem Fall ist aber der Aufruf von Windows.GetSystemMetrics schlichtweg falsch.
Besten Dank für die microsoft Info/Warnung.

Wie bereits erwähnt: Es ist mittlerweile ausgebauter Uraltcode, welcher seit Delphi 2 "gepflegt" wird und bis Delphi 10.4 Update 2 in diesem Bereich problemlos lief. Bis da war mir kein Fall bekannt, in welchem beim Aufruf der WinApi Funktion ein Problem aufgetreten ist. (Das Programm wurde bis jetzt auf über 44'000 voneinander verschiedenen Windows Kisten (auch mit Monitoren mit enormer Auflösung) installiert. Bis vor Delphi 11 gab es kein negatives Feedback.) Wenn du mir ein Gegenbeispiel hast, dann sehr gern.

Aber ich bin natürlich deiner Meinung: Wenn microsoft das empfiehlt, dann sollte man microsofts Vorschlag folgen. Delphi macht die Unterscheidung korrekt mittels Vcl.Controls.CheckPerMonitorV2SupportForWindow.

Aber:
Wenn ich in Delphi unter Projekt > Optionen > Manifest > DPI-Unterstützung die drei Fälle "Keine", "Monitor" und "Monitor V2" teste, dann erhalte ich diese Werte für GetSystemMetrics(SM_CXSIZEFRAME):

Delphi 10.4 Update 2

Keine 8 breiter Fensterrand VCL meldet 8 WIN meldet 8
Monitor 9 breiter Rand VCL:9 WIN:9
Monitor V2 9 breiter Rand VCL:4 WIN:9

Delphi 11
Keine 8 breiter Rand VCL:4 WIN:4
Monitor 9 breiter Rand VCL:4 WIN:4
Monitor V2 9 breiter Rand VCL:4 WIN:4

Beim Testen fällt auf:
- Bei Delphi 10.4 wird beim Winapi Aufruf von GetSystemMetrics(SM_CXSIZEFRAME) immer die "Fensterrandbreite" gemeldet.
- Die VCL Version meldet in den beiden Fällen "Keine" und "Monitor" ab Delphi 11 andere Werte. Die VCL Version liefert in Delphi 11 in keinem der Fälle die "Randbreite".
- Die Winapi Version meldet ab Delphi 11 in allen drei Fällen (Keine, Monitor, Monitor2) andere Werte.

Für andere Windows Skalierungen ähnlich.
______________________

Wenn wir zusätzlich die Werte von GetSystemMetrics(SM_CXPADDEDBORDER) betrachten, dann gilt:

Delphi 10.4 Update 2
Keine 8 VCL:8 0 WIN:8 0
Monitor 9 VCL:9 0 WIN:9 0
Monitor V2 9 VCL:4 5 WIN:9 0

Delphi 11
Keine 8 VCL:4 4 WIN:4 4
Monitor 9 VCL:4 5 WIN:4 5
Monitor V2 9 VCL:4 5 WIN:4 5


Wer also noch alten Code rumliegen hat, in welchem GetSystemMetrics(SM_CXSIZEFRAME) drin steht, sollte natürlich die VCL Version verwenden [Den Winapi Werten kann man nach Wechsel der Windows Skalierung kurz nicht trauen und laut m$ (siehe Info UR) gar nicht] und u.U. beim Wechsel auf Delphi 11 prüfen, ob auch GetSystemMetrics(SM_CXPADDEDBORDER) berücksichtigt worden ist.


Wieso rechnet Delphi 11 anders als Delphi 10.4 Update 2? Es liegt wohl an Projekt > Optionen > Erzeugen > Delphi Compiler > Linken > Untersystem Versionsfelder in PE Header. In Delphi 11 5.0 statt 6.0. setzen und Delphi 11 rechnet wie früher. (Dies ist natürlich keine Empfehlung... )
Michael Gasser

Geändert von Michael II (25. Okt 2021 um 23:15 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 25. Okt 2021, 23:58
In Delphi 11 5.0 statt 6.0. setzen und Delphi 11 rechnet wie früher.
Interessant. Damit wird eigentlich die minimale Windows-Version festgelegt, mit der die EXE gestartet werden kann. Dabei entspricht 5.0 dem guten alten Windows 2000, die 6.0 wäre dann Windows Vista. Mir ist nicht bekannt, dass sich das irgendwie auf die SystemMetrics auswirkt.

Vielleicht solltest du dazu einen QP-Eintrag aufmachen. Beispielcode und einen (magischen) Workaround gibt es ja. Ich werde dann mal jemanden antriggern, der das mal hinterfragen kann.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 26. Okt 2021, 09:51
Es liegt wohl an Projekt > Optionen > Erzeugen > Delphi Compiler > Linken > Untersystem Versionsfelder in PE Header. In Delphi 11 5.0 statt 6.0. setzen und Delphi 11 rechnet wie früher.
Ich habe das mal auf ein simples Konsolenprogramm heruntergebrochen:
Delphi-Quellcode:
program TestSystemMetrics;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows;

begin
  try
    Writeln(GetSystemMetrics(SM_CXSIZEFRAME).ToString);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Unter Delphi 10.4.2 wird hier 8 ausgegeben, während Delphi 11 eine 4 ausspuckt.

Die Änderung des besagten PE-Eintrags von 6.0 auf 5.0 in Delphi 11 ergibt dann in der Tat eine 8, während eine Änderung von 5.0 auf 6.0 das Ergebnis in Delphi 10.4.2 erwartungsgemäß auf 4 ändert.

Da es sich um eine Konsolenanwendung ohne eingebundene Resource und somit auch ohne Manifest handelt, fällt auch die DPI-Awareness als Beteiligte aus.

Erklären kann ich dieses Verhalten nicht und eine Dokumentation dafür konnte ich auch nicht finden. Es ist aber vermutlich schon seit einigen Delphi-Versionen so. Auf die Schnelle ließ sich das hier auch mit Delphi 10.1 Berlin reproduzieren.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 26. Okt 2021, 09:58
Den gleichen Effekt kann man übrigens auch erreichen, wenn man im Eigenschaften-Dialog des Windows-Explorers für die Exe (mit PE 5.0 compiliert) den Kompatibilitätsmodus aktiviert. Dann wird aus der 8 auch plötzlich eine 4.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 26. Okt 2021, 16:38
Informelle Aussage seitens Embarcadero: Die Einstellung bleibt auch in Zukunft auf 6.0!

Da dieses Problem ja auch vom Anwender selbst durch Aktivierung des Kompatibilitätsmodus forciert werden kann, wird man an eine Anpassung seiner Anwendungen an dieses Verhalten mittelfristig wohl nicht herum kommen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
492 Beiträge
 
Delphi 12 Athens
 
#7

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 26. Okt 2021, 16:55
Zitat:
...Anpassung seiner Anwendungen..
Da PE 6.0 z.B. auch die Höhe des Fenstertitels eines Toolwindows vergrößert, ist doch eine Anpassung der Vcl zu machen.
Ich wüsste jetzt nicht, wie ich das in der Anwendung berücksichtigen sollte.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 26. Okt 2021, 17:06
Zitat:
...Anpassung seiner Anwendungen..
Da PE 6.0 z.B. auch die Höhe des Fenstertitels eines Toolwindows vergrößert, ist doch eine Anpassung der Vcl zu machen.
Ich wüsste jetzt nicht, wie ich das in der Anwendung berücksichtigen sollte.
Hab da gerade mal jemanden mit der Nase drauf gestupst.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  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 14:53 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