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
Seite 1 von 3  1 23      
Michael II

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

Delphi 11 -GetSystemMetrics( SM_CXSIZEFRAME ) ermittelt andere Werte

  Alt 24. Okt 2021, 00:36
VCL

Mir ist in einer App (mit zugegeben etwas altem Code) aufgefallen, dass zur Laufzeit die Fenster nicht mehr ganz genau gleich positioniert werden wie vor Delphi 11.

Grund: Folgender Code meldet nach Klick auf Button1 bis und mit Delphi 10.4 (für mein System erwartet) für cxsizeframe 9 zurück, bei Delphi 11 4.

Delphi-Quellcode:
function cxsizeframe : integer;
begin
  Result := GetSystemMetrics(SM_CXSIZEFRAME);
end;


procedure TForm195.Button1Click(Sender: TObject);
begin
  Showmessage( GetSystemMetrics(SM_CXSIZEFRAME).ToString + #10 +
               cxsizeframe.ToString );
end;

Weiss jemand wieso Delphi 11 hier einen anderen Wert ermittelt und damit das Verhalten von Anwendungen ändert?

Mir ist bewusst, dass ich Fenster anders positionieren kann/soll. Es interessiert mich aber, wieso Delphi 11 hier mit dem bisherigen Verhalten bricht.
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 24. Okt 2021, 01:44
Hast du mal die Manifeste verglichen?

Kannst auch direkt in der EXE nachsehn, mit einem Ressourcen-Editor oder einem Texteditor (siehe <assembly ).
Das ist ja eine bekannte Stelle, welche auch derartige APIs beeinflusst.



Bloß nicht wundern, dass es für Windows 11 keine neue supportedOS-ID gibt, denn hier gilt die von Windows 10 weiterhin.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Michael II

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

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

  Alt 24. Okt 2021, 02:14
Besten Dank himitsu für den Tipp.

Ich habe eine "alte" App ins neue Delphi geladen und bin dabei aufs Problem gestossen. Ich nehme mal an, dass Delphi 11 das Manifest beim Laden nicht abgeändert hat.

Beim Testen mit obigem Minimalbeispiel habe ich's genau gleich getan.

Werde das mit dem Manifest in der exe aber natürlich mal prüfen - aber nicht mehr heute Nacht .
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.289 Beiträge
 
Delphi 12 Athens
 
#4

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

  Alt 24. Okt 2021, 07:37
Moin...
[OT]
Zitat:
TForm195
...du solltest dringed mal aufräumen.
[/OT]
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

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

  Alt 24. Okt 2021, 11:10
Keine Sorge, ab oberen 4-stellig fangen es erst die Problemchen mit dem Dateisystem Dateisystembetrachtungs-&Backupprogrammen an.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Achim Kalwa

Registriert seit: 2. Apr 2005
Ort: Lienen
103 Beiträge
 
Delphi 11 Alexandria
 
#6

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

  Alt 24. Okt 2021, 14:01
VCL
Grund: Folgender Code meldet nach Klick auf Button1 bis und mit Delphi 10.4 (für mein System erwartet) für cxsizeframe 9 zurück, bei Delphi 11 4.

Delphi-Quellcode:
function cxsizeframe : integer;
begin
  Result := GetSystemMetrics(SM_CXSIZEFRAME);
end;
...
Weiss jemand wieso Delphi 11 hier einen anderen Wert ermittelt und damit das Verhalten von Anwendungen ändert?
Ab Delphi gibt es zusätzlich zu Winapi.Windows.GetSystemMetrics() in der VCL eine gleichnamige function in TControl.GetSystemMetrics(), welche intern dann Winapi.Windows.GetSystemMetricsForDpi() aufruft, und zwar abhängig davon ob die Anwendung mit PerMonitorV2-Skalierung läuft.

Vergleiche mal die Ergebnisse von
Winapi.Windows.GetSystemMetrics(SM_CXSIZEFRAME)
und
(Self.)GetSystemMetrics(SM_CXSIZEFRAME);

Im Grunde ist das eine gute Idee, denn damit wird bestehender Code ohne Anpassung HighDPI-fähig. Warum SM_CXSIZEFRAME bei aktiver Skalierung nur noch 4 statt 9 ist, kann ich aber auch nicht erklären.
Achim
  Mit Zitat antworten Zitat
Michael II

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

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

  Alt 25. Okt 2021, 00:28
Hallo alle...

danke fürs Feedback; natürlich auch für die wertvollen Tipps, wie ich meine Platte besser füllen soll .

Ich habe die beiden "Exes" geöffnet, die Manifeste extrahiert und vergleichen lassen. Resultat: "Die zwei Texte sind völlig gleich."

Danke für den Vorschlag, GetSystemMetrics() von VCL.Controls und von Winapi.Windows zu nutzen. Das macht der Code in #1 bereits.

Delphi-Quellcode:
procedure TForm195.Button1Click(Sender: TObject);
begin
  Showmessage( GetSystemMetrics(SM_CXSIZEFRAME).ToString + #10 + // VCL.Controls
               cxsizeframe.ToString ); // Winapi.Windows
end;

function cxsizeframe : integer; (siehe #1) nutzt Winapi.Windows. Bei Delphi 10.4 gibt cxsizeframe noch 9 zurück, bei Delphi 11 nun 4.

GetSystemMetrics() von VCL.Controls gibt bei D10.4 und D11 4 zurück.

Ich weiss immer noch nicht was den Unterschied ausmacht.
Wahrscheinlich rechnen D10.4 und D11 irgendwie richtig...

Wer noch Code mit GetSystemMetrics(SM_CXSIZEFRAME) aus der Winapi.Windows nutzt, muss nach dem Umstieg auf Delphi 11 die Fenster eventuell auch anders/neu positionieren.
Michael Gasser
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#8

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

  Alt 25. Okt 2021, 07:45
Zitat:
Wer noch Code mit GetSystemMetrics(SM_CXSIZEFRAME) aus der Winapi.Windows nutzt, muss nach dem Umstieg auf Delphi 11 die Fenster eventuell auch anders/neu positionieren.
Dann ist es ein Fehler von Delphi 11.
Ein Betriebssystem bzw. die API der jeweiligen Funktion von diesen) gibt die Breite des Borders vor und wenn ein Programm in dem fall Delphi von der Norm abweicht ist es schlichtweg Falsch.

Wenn ich mein Fenster (nonVcl) mit Delphi kompiliere dann hat mir Delphi die Werte zur Verfügung zu stellen die dem Betriebssystem entsprechen.
Und zwar diese aus der WinApi nix anderes.

Wo kommen wir da hin wenn jede Programmiersprache sein eigenes Süppchen kocht.

Delphi-Quellcode:
        if IsWindowVisible(GetDlgItem(WinHandle, ID_MAXIMIZE)) then
        begin
          GetClientRect(WinHandle, rc);

          xF := rc.Right;
          yF := rc.Bottom;
          xSide := 0;
          BORDER := GetSystemMetrics(SM_CXFRAME); // SM_CXSIZEFRAME ist das gleiche
          if ((P.X >= xF - BORDER) and ((P.Y >= yF - BORDER))) then
          begin
            HITTEST := HTBOTTOMRIGHT;
          end
Ich muß mich darauf verlassen das die Koordinaten bzw. Border mir die richtigen Werte aus der WinApi zurück gibt.
Die dürfen vom Delphi Compiler nicht verändert werden.

Sollte es jedoch nur die Fenster in der IDE von Delphi betreffen kann es mir egal sein was die da rummurksen.

EDIT:
Es sollte nicht die Aufgabe einer Programmiersprache sein eine Anwendung High DPI fähig zu machen.
Das unterliegt dem Programmierer und zwar mit Altbewährten Methoden unter Verwendung der vom System bereitgestellten API.

Geändert von venice2 (25. Okt 2021 um 08:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

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

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
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

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

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

  Alt 25. Okt 2021, 08:41
Es sollte nicht die Aufgabe einer Programmiersprache sein eine Anwendung High DPI fähig zu machen.
Das unterliegt dem Programmierer und zwar mit Altbewährten Methoden unter Verwendung der vom System bereitgestellten API.
Da bin ich aber vollkommen anderer Meinung. Zum einen ist es nicht die Programmiersprache, die hier die High-DPI Funktionalität zur Verfügung stellt, sonder das verwendete GUI-Framework (VCL), und zum anderen sehe ich genau diese Unterstützung des Frameworks als mittlerweile zu erwartendes Feature an. Wenn jemand das Framework nicht benutzen möchte ist ihm das natürlich unbenommen. Darunter fällt aber nur eine Minderheit der Delphi Entwickler.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 09:57 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