Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte (https://www.delphipraxis.net/195924-vcl-ersatz-fuer-getsystemmetrics-sm_cysize-bitte.html)

KodeZwerg 7. Apr 2018 09:08

VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Guten Tag, unter WinApi benutze ich diesen Aufruf
Delphi-Quellcode:
Handle := CreateWindowEx(WS_EX_WINDOWEDGE {$IFDEF DEFONTOP} or WS_EX_TOPMOST {$ENDIF DEFONTOP},
                         PChar('Class'),
                         PChar('Caption'),
                         WS_VISIBLE or WS_CAPTION or WS_SYSMENU or WS_BORDER or WS_MINIMIZEBOX,
                         ((GetSystemMetrics(SM_CXFULLSCREEN) DIV 2)-(ZahlX DIV 2)),
                         ((GetSystemMetrics(SM_CYFULLSCREEN) DIV 2)-((ZahlY-(GetSystemMetrics(SM_CYSIZE)+GetSystemMetrics(SM_CYMIN))) DIV 2)),
                         ZahlX, ZahlY+GetSystemMetrics(SM_CYSIZE), 0, 0, Inst, NIL);
um ein Fenster mittig auf dem Bildschirm zu erstellen, inklusive DPI check für Titelleisten Höhe (GetSystemMetrics(SM_CYSIZE)).
Das mit der Fenstermitte unter VCL hab ich raus aber wie ermittle ich unter VCL wie hoch eine Titelleiste von Windows ist/sein sollte? Also ein VCL Ersatz für GetSystemMetrics(SM_CYSIZE). Hat da jemand eine Idee für mich? Ist bestimmt eine Property die ich nur abfragen brauche .....oder?

Uwe Raabe 7. Apr 2018 09:25

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398365)
um ein Fenster mittig auf dem Bildschirm zu erstellen, inklusive DPI check für Titelleisten Höhe

Soll die Mitte des Forms zentriert werden oder die Mitte des Client-Bereichs des Forms?

KodeZwerg 7. Apr 2018 09:50

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398365)
.......wie ermittle ich unter VCL wie hoch eine Titelleiste von Windows ist/sein sollte? Also ein VCL Ersatz für GetSystemMetrics(SM_CYSIZE).......

Ich will nicht grob klingen aber ich brauch eine Antwort darauf.
Um Deine Frage zu beantworten:
In dem gezeigten Code wird das Fenster (Window) mittig auf dem Bildschirm zentriert dargestellt/erstellt.
ZahlX und ZahlY ist die tatsächliche Fenstergröße des Client-Bereichs (in VCL = Fenster.Width/Height) wobei ZahlY nachkorrigiert wird um das DPI Verhältniss der Caption zu berücksichtigen.

Delphi.Narium 7. Apr 2018 10:38

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Nur mal so grob geraten:

Delphi-Quellcode:
TitleHeight := Form.Height - Form.ClientHeight - (2 * Form.BorderWidth);


Lässt sich so mit Delphi 7 im Objectinspector nachvollziehen. Kommt bei meinem Rechner immer 27 raus.

KodeZwerg 7. Apr 2018 10:45

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Das würde mir doch nur meine Eigene Höhe wiedergeben aber nicht die Höhe die das System vorsieht, oder liege ich falsch?
Vielleicht ist es ja unter VCL auch total Wurst.
Ich werde noch ein wenig herum experimentieren um zu Wissen ob ich es überhaupt benötige wie in meinem WinApi Beispiel.
Ich glaube unter VCL sind das getrennte Sachen unter WinApi ist es ein Objekt, weswegen ich's dort berücksichtigen muss.

Delphi.Narium 7. Apr 2018 10:51

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Ist die eigene Höhe nicht die vom System vorgegebene?

Habe jedenfalls die Höhe der Formulartitelleiste noch nie verändert.

Egal wie ich die Größe von Schrift, Komponenten ... in 'nem Formular zur Laufzeit oder im Objektinspektor verändere: Die Titelleiste des Formulars ist immer so, wie vom System vorgegeben.

Schau mal bitte hier: http://www.mindspring.com/~cityzoo/ttlbar3.html unter 3. Setting the Minimum Window Size.

Wäre da ein Ansatz bei?

Gefunden über Bei Google suchendelphi source tForm caption height

Uwe Raabe 7. Apr 2018 11:14

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Mit folgender Methode bekommt man ein Form um einen bestimmten Punkt auf dem Desktop zentriert:
Delphi-Quellcode:
procedure CenterFormOnScreen(AForm: TForm; ACenter: TPoint);
var
  diff: TPoint;
begin
  diff := ACenter - AForm.ClientToScreen(AForm.ClientRect.CenterPoint);
  AForm.Left := AForm.Left + diff.X;
  AForm.Top := AForm.Top + diff.Y;
end;
Je nachdem, ob man die Taskleiste bei der Berechnung des Mittelpunkts berücksichtigen will, kann der Aufruf für einen Zielmonitor so aussehen:
Delphi-Quellcode:
    // ganzer Bereich
    CenterFormOnScreen(form, Monitor.BoundsRect.CenterPoint);

    // alternativ Bereich ohne Taskleiste
    CenterFormOnScreen(form, Monitor.WorkAreaRect.CenterPoint);

    // das Form dann z.B. modal anzeigen
    form.Position := poDesigned;
    form.ShowModal;
Sollte mit allen Auflösungen, DPI-Einstellungen und Monitor-Layouts funktionieren.

KodeZwerg 7. Apr 2018 11:38

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Also, unter WinApi, wenn ich da ein Fenster generiere, da muss ich Wissen wie groß alles ist.
Delphi.Narium Du hast Recht mit der Aussage "Die Titelleiste des Formulars ist immer so, wie vom System vorgegeben.", aber unter WinApi muss ich eben genau diese Größe berücksichtigen da sonst das Fenster was erstellt wird zu groß/klein ist (falls DPI <> 96).
WinApi behandelt ein Window anders als ein TForm, WinApi ist da eher steif und stur.
Ein Aufruf von "GetSystemMetrics(SM_CYSIZE)" gibt mir die OS-Information wieviel Höhe die Caption aktuell haben sollte/braucht.
Du kannst ja gerne mal GetSystemMetrics(SM_CYSIZE) testen, der Aufruf ist nicht gefährlich, ist ein Integerwert der rauskommt, wenn dein Beispiel korrekt funktioniert sollte das Ergebniss idealerweise identisch sein. Wenn nicht haut was mit Border-Thickness nicht hin.


@Uwe Raab: Ich schrieb doch das ich das Zentrieren bereits hinbekommen habe, aber Danke nochmals dafür.
Ich bin da etwas grob rangegangen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Left := (Screen.Width-Width)  div 2;
  Top := (Screen.Height-Height) div 2;
end;

Codehunter 7. Apr 2018 11:41

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Kann sein dass ich die Frage nicht ganz verstehe, aber reicht ein schnödes
Delphi-Quellcode:
Form.Position:= poScreenCenter
nicht aus?

KodeZwerg 7. Apr 2018 11:51

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Bestimmt klappt das auch, aber, in diesem Thread geht es nicht darum wie man etwas zentriert darstellt sondern wie ich per VCL die Höhe der Titelleiste herausfinde da ich gerade mein WinApi Beispiel 1:1 nach VCL portiere um eine Skalierungs-Fehler Demo für Uwe Raab zu erstellen bzw herausfinden ob VCL den gleichen "Mist" produziert wie ein WinApi Aufruf.

Das in meinem Beispiel eine Zentrierung vorliegt, bitte ignoriert das, Danke.

Delphi.Narium 7. Apr 2018 11:56

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Um erstmal alle Missverständnisse zu beseitigen:

Du möchtest wissen wie hoch das "farbige Dingen" ist, in dem in einem VCL-Formular der Text ausgegeben wird, den man Form.Caption zuweist?

Uwe Raabe 7. Apr 2018 12:59

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von Codehunter (Beitrag 1398387)
Kann sein dass ich die Frage nicht ganz verstehe, aber reicht ein schnödes
Delphi-Quellcode:
Form.Position:= poScreenCenter
nicht aus?

poScreenCenter zentriert das Form in seiner Gesamtausdehnung. Will man den Clientbereich zentrieren, muss man das Form etwas weiter nach oben schieben.

Uwe Raabe 7. Apr 2018 13:06

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von KodeZwerg (Beitrag 1398388)
wie ich per VCL die Höhe der Titelleiste herausfinde

Delphi-Quellcode:
TitleHeight := Form.ClientToScreen(Point(0,0)).Y - Form.Top;


Allerdings bin ich der Meinung, daß die Notwendigkeit diesen Wert wissen zu müssen, schon ein Zeichen für einen Designfehler ist (zumindest wenn man mit der VCL arbeitet). In der Regel erreicht man das Gewünschte auch ohne solche Angaben.

Codehunter 7. Apr 2018 13:36

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Mich irritiert vor allem die gedankliche Trennung zwischen VCL und Win32. Die VCL ist aber keine Alternative dazu sondern ein Aufsatz. Daher sehe ich nicht dass man in der VCL etwas fände das einem GetSystemMetrics überlegen wäre. Ich vermute hinter der Ausgangsfrage steckt ein komplexeres Problem mit HighDPI-Anwendungen. Leider bin ich da mangels entsprechender Hardware raus. Allerdings wäre es sicher für die anderen gut zu wissen, um was es eigentlich wirklich geht.

Uwe Raabe 7. Apr 2018 13:53

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von Codehunter (Beitrag 1398399)
Mich irritiert vor allem die gedankliche Trennung zwischen VCL und Win32. Die VCL ist aber keine Alternative dazu sondern ein Aufsatz. Daher sehe ich nicht dass man in der VCL etwas fände das einem GetSystemMetrics überlegen wäre. Ich vermute hinter der Ausgangsfrage steckt ein komplexeres Problem mit HighDPI-Anwendungen.

Die Intention bei der Verwendung der VCL gegenüber des direkten WinApi-Zugriffs ist, daß man sich nicht mehr um solche DPI-Probleme kümmern muss. Natürlich basiert die VCL auf der WinApi und nutzt intern auch deren Funktionen, allerdings kapselt sie auch einen Großteil der Komplexität und verbirgt diese vor dem Programmierer. Es kann natürlich sein, daß die VCL das nicht immer richtig handhabt, aber das muss man dann eben beheben.

Meine Erwartung in dieser Hinsicht ist ganz klar, daß eine VCL-Anwendung (zumindest mit Standard-Controls) ohne irgendwelche manuellen Eingriffe High-DPI fähig ist. Arbeite ich mit Icons muss ich diese natürlich in den verschiedenen Auflösungen bereitstellen oder mich mit einem Auto-Scaling zufrieden geben. Da steht eben Aufwand gegen Aussehen und das muss man halt gegeneinander abwägen.

Wer nun partout direkt mit der WinApi hantieren muss, steht bei High-DPI mit GetSystemMetrics schnell auf verlorenem Posten. In dem Fall wäre dann vielleicht GetSystemMetricsForDpi die bessere Alternative. Ob das allein dann wirklich ausreicht ist allerdings fraglich.

EWeiss 7. Apr 2018 16:15

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Wer nun partout direkt mit der WinApi hantieren muss, steht bei High-DPI mit GetSystemMetrics schnell auf verlorenem Posten.
Ist das eine Annahme(Wissen) oder nur eine Vermutung.. Ich denke das letztere.

Wenn man seine Anwendung DPI fähig machen will kommt man nun mal nicht Drumherum dann auch jedes erstellte Fenster bzw. Control dementsprechend zu behandeln was die Weite und Höhe angeht.
Wie du schon sagst die VCL macht es automatisch wenn (dementsprechend angepasst).

Aber mir ist es egal ob ich DPI mit übergebe oder nur Clientweite, Clienthöhe.
Letztendlich sind das bei jedem wert nur 3 Buchstaben die ich vorhängen muss.

Und nein man steht mit GetSystemMetrics nicht auf verlorenen Posten warum auch?
Erkläre das bitte näher.

bsp: Aus meinem Player.. C++64
Man beachte das vorgehängte dpi zum Beispiel beim erstellen des Rect.
Code:
            DWORD dwStyle = WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
            RECT rc;
            SetRect(&rc, 0, 0, dpi(CLIENT_WIDTH), dpi(CLIENT_HEIGHT));
            AdjustWindowRectEx(&rc, dwStyle, FALSE, 0);
            long w = Width(rc); long x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
            long h = Height(rc); long y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
            gP.hMainMenu = BuildMenu();
            gP.hMain = CreateWindowEx(WS_EX_ACCEPTFILES, STR_CLASS, STR_TITLE, dwStyle, x, y, w, h, nullptr, gP.hMainMenu, hInstance, nullptr);
            if (gP.hMain) {
                if (InitKVPlayer(hInstance)) {
                    GetClientRect(gP.hMain, &rc);
                    y = Height(rc) - 80;

                    // Create movie slider
                    dwStyle = WS_VISIBLE | WS_CHILD | TBS_NOTICKS | TBS_FIXEDLENGTH;
                    CreateWindowEx(0, L"msctls_trackbar32", NULL, dwStyle, 0, y - 17, dpi(Width(rc)), dpi(18), gP.hMain, (HMENU)ID_SLIDER, hInstance, NULL);
Nun wo soll also hier nun ein Problem sein ?
Bin auch schon wieder weg da es hier um VCL geht .. wollte nur deine Behauptung (verlorener posten) widerlegen.

gruss

Daniel 7. Apr 2018 16:20

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Was hast Du denn bei diesem schönen Wetter für schlechte Laune? Und warum musst Du die gerade hier rauslassen? Zwingt Dich doch keiner ...

EWeiss 7. Apr 2018 16:29

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von Daniel (Beitrag 1398410)
Was hast Du denn bei diesem schönen Wetter für schlechte Laune? Und warum musst Du die gerade hier rauslassen? Zwingt Dich doch keiner ...

Ich habe nur gesagt das seine Annahme falsch ist.

gruss

KodeZwerg 7. Apr 2018 17:23

AW: VCL Ersatz für GetSystemMetrics(SM_CYSIZE) bitte
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1398390)
Um erstmal alle Missverständnisse zu beseitigen:

Du möchtest wissen wie hoch das "farbige Dingen" ist, in dem in einem VCL-Formular der Text ausgegeben wird, den man Form.Caption zuweist?

Jain, Wissen wollte ich wie ich per VCL die Größe auslese die Windows für Captions im aktuellen DPI setting benutzt/vorgibt, nicht wie hoch meine Eigene Caption ist.
Ich dachte an so etwas banales wie eine "Systems.Windows.Caption.Size.Height" Property. (<- von mir erfundene Wort-Kette)

Ich finde allerdings auch keinen VCL Ersatz mit dem ich die Höhe beeinflussen kann, von daher vermute ich mal das es mit VCL nicht funktioniert und das Thema hiermit am Ende ist.
In VCL ist das wohl vom Client-Bereich getrennt, Caption kommt vom System/Theme/Skin/o.ä..
Ich finde nur Wege wie ich VCL Captions selber ändern kann indem ich ein Borderless Window erstelle und Kombination aus Image + Text + Knöpfe alles selber zeichne, was am WinApi Skalierungs-Fehler Meilenweit fern ist.

Das war halt das blöde, eine 1:1 Portierung klappt nicht wenn ich Api Aufrufe mit VCL Aufrufen ersetzen will.
Bei all meinen Anstrengungen eine Fehlerhafte Skalierung aufzudecken so wie ich es mit WinApi in ein paar Minuten hinbekomme, was soll ich sagen, da fehlen der VCL halt ein paar funktionen, was ja auch gut ist, so entsteht zumindest nicht dieser Fehler, aber ich probiere und teste noch ein wenig herum.
VCL scheint etwas Eigen-Magie mitzubringen die mir diesen Fehler zumindest verbietet nachzuahmen.
Da wird die Caption getrennt vom Client-Bereich erstellt, so das der Client-Bereich immer groß genug ist um bei DPI wechsel die Änderung abzufangen.

[EDIT]
Um es mit VCL nachzustellen, nicht funktionell aber visuell, hier ist das was ich meine:
Man erstellt eine Form, fixe größe, man packt auf diese Form ein Panel, fixe größe / relativ formfüllend.
Nun gibt man der Form eine Sizeable Property, wenn man nun das Window kleiner macht, also kleiner als das Panel, was passiert da bei Euch? Bei mit hat das Fenster dann unten und rechts eine Scrollbar. Auf so einen Fehler war ich aus.
In WinApi passiert so etwas wenn man nicht alle Größen korrekt mit-nutzt, diesen Fehler per VCL hinzubekommen da übe ich noch ein wenig.
[/EDIT]


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:29 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