Discussion:
Fensterproportionen manchmal falsch, Buttons verschwunden etc.
(zu alt für eine Antwort)
Matthias Hanft
2017-08-24 08:32:54 UTC
Permalink
Hallo,

ich verwende Delphi 7 (professional). Das funktioniert eigentlich auch unter
Windows 10 noch ganz prima. In letzter Zeit melden mir allerdings einige An-
wender, dass eine bestimmte Form nicht richtig funktioniert: Da sind Panels
mit Splitter drauf und da drin PageControls mit TabSheets und unten ein Ok-
und Abbrechen-Button. Eigentlich nix besonderes. Die Anchors habe ich so
gemacht, dass bei einer Größenänderung der Form alles entsprechend mitwächst
bzw. -schrumpft.

Das funktioniert bei mir auf Windows 7 und Windows 10 (auf einem 1920x1200-
Bildschirm, aber auch bei anderen Auflösungen - ich habe alle PCs und Bild-
schirme getestet, die ich hier habe).

Nun schreiben mir aber einige Anwender (und schicken auch Screenshots mit),
dass das Fenster z.B. "zu wenig hoch" ist und dadurch unten die beiden Buttons
nicht erreichbar seien. Oder der senkrechte Splitter ist und bleibt so weit
rechts, dass man an das rechte Panel gar nicht herankommt. Auch eine Größen-
änderung des gesamten Fensters hilft nichts; das bleibt so seltsam verzerrt.

Ich kann das hier nicht wirklich nachvollziehen; sowohl in der IDE als auch
standalone funktioniert das hier alles.

Allerdings habe ich inzwischen herausgefunden, dass man in den "Eigenschaften"
des EXE (oder der Verknüpfung) unter "Kompatibilität" unter "Einstellungen"
den Punkt "Verhalten bei hoher DPI-Skalierung überschreiben. Skalierung
durchgeführt von:" ankreuzen und dann von "Anwendung" auf "System" umstellen
kann. Dann scheint es bei den betroffenen Anwendern zu funktionieren.

Leider gibt es diese Auswahl nur unter Windows 10. Unter Windows 7 gibt es
nur "Skalierung bei hohem DPI-Wert deaktivieren", aber da weiß ich nicht,
ob das hilft; da warte ich noch auf Rückmeldung von dem betreffenden An-
wender. Der hat laut Programm-Debug-Ausgaben Screen.Width=1280, Screen.
Height=1024 und Screen.PixelsPerInch=120. So eine geringe Auflösung mit
so einem hohen DPI-Wert kommt mir irgendwie seltsam vor?!

Wobei das natürlich nur die zweitbeste Lösung ist, wenn ich dem Anwender
sagen muss, dass er in den Programmeigenschaften etwas umstellen soll (und
viele können das bzw. finden diesen Punkt auch gar nicht) - und es hilft
auch nicht immer.

Kann ich da im Programm irgendwas besser machen? An der Form selbst habe
ich nichts geändert, die hat im Objektinspektor die Defaultwerte Scaled=
True und PixelsPerInch=96. Und bei 99% der Anwender funktioniert das auch.
(Nicht dass ich jetzt was ändere, damit es bei den restlichen 1% klappt,
aber bei den 99% nicht mehr!)

Hat irgendjemand einen Tipp parat?

Danke & Gruß Matthias.
Peter Below
2017-08-25 08:03:23 UTC
Permalink
Post by Matthias Hanft
Der hat laut Programm-Debug-Ausgaben Screen.Width=1280, Screen.
Height=1024 und Screen.PixelsPerInch=120. So eine geringe Auflösung
mit so einem hohen DPI-Wert kommt mir irgendwie seltsam vor?!
Ist es nicht. Wenn man (wie ich) ziemlich kurzsichtig ist arbeitet es
sich im large font modus (120 dpi) einfach besser, auch wenn man dann
nicht so viel auf den Bildschirm bekommt. Dafür kann man wenigstens den
Text lesen, ohne sich die Augen dabei zu überanstrengen.

Die in der VCL verbaute Skalierungsfunktion funktioniert nicht in allen
Fällen perfekt. Ein Problem sind besonders Dialogforms die eine feste
Größe haben (nicht vom Benutzer veränderbar). Da wird dann zwar der
Inhalt des Forms skaliert, aber nicht das Form selbst, was dann in dem
von Dir geschilderten Problem resultiert (ein Teil der Controls ist
nicht mehr sichtbar da außerhalb der client area des Forms
positioniert. Selbst einige Dialoge der IDE (Berlin in meinem Fall)
haben das Problem.

Als kurzfristige Lösung kannst Du die Autoscroll property der Forms auf
true setzen, das sieht dann zwar nicht so schön aus, aber zumindestens
kann der Benutzer dann die "versteckten" Controls erreichen.

Ansonsten scheint es besser zu funktionieren, wenn man für das Layout
hauptsächlich mit den Align, Margin und Padding-Properties arbeitet und
nicht mit den (alten) Anchors.
--
Peter Below
TeamB
Matthias Hanft
2017-08-25 08:35:39 UTC
Permalink
Post by Peter Below
Die in der VCL verbaute Skalierungsfunktion funktioniert nicht in allen
Fällen perfekt. Ein Problem sind besonders Dialogforms die eine feste
Größe haben (nicht vom Benutzer veränderbar).
Meine "böse" Form ist eine ganz normale "sizeable". Das Sizen selbst
(rechte untere Ecke ziehen) funktioniert ja auch. Bloß die Controls
sind dann irgendwo "unterirdisch" - und/oder der Splitter zwischen
den Panels lässt sich nicht ziehen. Letzteres ist übrigens der einzige
Effekt, den ich hier - manchmal - nachstellen kann: Da positioniert
man die Maus (ganz vorsichtig und akkurat) über dem Splitter, aber
der Mauscursor ändert sich einfach nicht zum "Splitter-Cursor". Das
passiert nur ab und zu; meistens geht es. Ich habe noch nicht heraus-
gefunden, wann/warum es *nicht* geht :-(
Post by Peter Below
Als kurzfristige Lösung kannst Du die Autoscroll property der Forms auf
true setzen, das sieht dann zwar nicht so schön aus, aber zumindestens
kann der Benutzer dann die "versteckten" Controls erreichen.
Autoscroll ist ja defaultmäßig schon True. Laut Screenshots der betrof-
fenen Anwender erscheint dann tatsächlich ein vertikaler Scrollbalken,
mit dem man zum "Ok"-Button runterscrollen kann - aber offenbar *kein*
horizontaler Scrollbalken, mit dem man zum "Abbrechen"-Button (rechts
neben dem "Ok"-Button) rüberscrollen könnte.

Leider begreife ich die Werte von HorzScrollBar bzw. VertScrollBar nicht
so richtig. In letzterer ist die "Range" defaultmäßig 437, in der "Horz"
dagegen 0. Muss man da von Hand was reinschreiben, oder gehen all diese
Scrollbarparameter automagisch?

Evtl. könnte man AutoSize der Form auf True setzen? Das habe ich noch
nicht probiert (da gibt es auch keinen Hilfetext speziell für TForm,
nur für TControl, aber der ist für eine Form wenig aussagekräftig...).
Post by Peter Below
Ansonsten scheint es besser zu funktionieren, wenn man für das Layout
hauptsächlich mit den Align, Margin und Padding-Properties arbeitet und
nicht mit den (alten) Anchors.
Kannst du da ein kurzes Beispiel geben? Margin ist defaultmäßig 0 (sollte
wohl etwas größer sein), Padding finde ich in D7 gar nicht, und was ist
für Align eigentlich das "übergeordnete Steuerelement" einer Form?

Gruß Matthias.
Peter Below
2017-08-26 09:03:09 UTC
Permalink
Post by Matthias Hanft
Post by Peter Below
Die in der VCL verbaute Skalierungsfunktion funktioniert nicht in
allen Fällen perfekt. Ein Problem sind besonders Dialogforms die
eine feste Größe haben (nicht vom Benutzer veränderbar).
Meine "böse" Form ist eine ganz normale "sizeable". Das Sizen selbst
(rechte untere Ecke ziehen) funktioniert ja auch. Bloß die Controls
sind dann irgendwo "unterirdisch" - und/oder der Splitter zwischen
den Panels lässt sich nicht ziehen. Letzteres ist übrigens der einzige
Effekt, den ich hier - manchmal - nachstellen kann: Da positioniert
man die Maus (ganz vorsichtig und akkurat) über dem Splitter, aber
der Mauscursor ändert sich einfach nicht zum "Splitter-Cursor". Das
passiert nur ab und zu; meistens geht es. Ich habe noch nicht heraus-
gefunden, wann/warum es nicht geht :-(
Post by Peter Below
Als kurzfristige Lösung kannst Du die Autoscroll property der Forms
auf true setzen, das sieht dann zwar nicht so schön aus, aber
zumindestens kann der Benutzer dann die "versteckten" Controls
erreichen.
Autoscroll ist ja defaultmäßig schon True. Laut Screenshots der
betrof- fenen Anwender erscheint dann tatsächlich ein vertikaler
Scrollbalken, mit dem man zum "Ok"-Button runterscrollen kann - aber
offenbar kein horizontaler Scrollbalken, mit dem man zum
"Abbrechen"-Button (rechts neben dem "Ok"-Button) rüberscrollen
könnte.
Leider begreife ich die Werte von HorzScrollBar bzw. VertScrollBar
nicht so richtig. In letzterer ist die "Range" defaultmäßig 437, in
der "Horz" dagegen 0. Muss man da von Hand was reinschreiben, oder
gehen all diese Scrollbarparameter automagisch?
Eigentlich sollte das schon automatisch gehen.
Post by Matthias Hanft
Evtl. könnte man AutoSize der Form auf True setzen?
Probier's ruhig mal aus.
Post by Matthias Hanft
Das habe ich noch
nicht probiert (da gibt es auch keinen Hilfetext speziell für TForm,
nur für TControl, aber der ist für eine Form wenig aussagekräftig...).
Post by Peter Below
Ansonsten scheint es besser zu funktionieren, wenn man für das
Layout hauptsächlich mit den Align, Margin und Padding-Properties
arbeitet und nicht mit den (alten) Anchors.
Kannst du da ein kurzes Beispiel geben? Margin ist defaultmäßig 0
(sollte wohl etwas größer sein), Padding finde ich in D7 gar nicht,
und was ist für Align eigentlich das "übergeordnete Steuerelement"
einer Form?
Ach, Delphi 7. Da gab's noch kein Padding, ALignWithMargins, und
Margins für Layout.

Das Problem mit Anchors ist, dass sie quasi einen Referenzpunkt für
Position und Größe des jeweiligen Controls brauchen. Das ist die
Position des Controls nach dem Laden des Forms aus der DFM-Resource. Da
gibt es aber wohl einen Konflikt mit dem Scaling.

Ich kann Dir da leider keine wirkliche Hilfe geben. Manchmal
funktioniert es wirklich am besten, wenn man einfach das Layout in Code
korrigiert (OnCreate event), wenn das Scaling es verhunzt hat.

Borland hat da leider seinerzeit (Delphi 1) die Entscheidung getroffen,
all Positionen und Größen für Controls und Fonts in device units
anzugeben und nicht (wie VB) in device independent units (twips). Das
war sicher sehr gut für performance und vereinfachte das Interface mit
dem API für die VCL, aber es ist mittlerweile ein massives Problem
geworden, seit Windows mit x verschiedenen DPI Werten aufwarten kann.
--
Peter Below
TeamB
Matthias Hanft
2017-08-26 10:46:13 UTC
Permalink
Post by Peter Below
Post by Matthias Hanft
Leider begreife ich die Werte von HorzScrollBar bzw. VertScrollBar
nicht so richtig. In letzterer ist die "Range" defaultmäßig 437, in
der "Horz" dagegen 0. Muss man da von Hand was reinschreiben, oder
gehen all diese Scrollbarparameter automagisch?
Eigentlich sollte das schon automatisch gehen.
Ich hab mal probiert, bei "Margin" was von 0 verschiedenes reinzu-
schreiben. Nach meinem Verständnis ist das dafür da, dass dann auto-
matisch ein Scrollbalken angezeigt wird, wenn ein Control weniger
als "Margin" Pixel vom Rand der Form entfernt ist. Im Real Life
wird dann allerdings zwischen dem oberen und dem unteren Panel
eben dieser "Margin" als Leerraum eingefügt, und/oder das untere
Panel kriegt dann plötzlich eine "Height" in Höhe von "Margin".
Das ist alles irgendwie seltsam...

Wobei ich möglicherweise noch einen Fehler meinerseits gefunden
habe: Das obere Panel hatte Align=alTop und das untere alBottom.
In der Doku zum Splitter habe ich allerdings gelesen, dass das
"letzte" Panel immer alClient (und eben nicht alBottom - bzw.
alRight, wenns horizontale Panels sind) haben muss. Habe das
mal geändert (allerdings noch keine Rückmeldung von den betrof-
fenen Anwendern).
Post by Peter Below
Ach, Delphi 7. Da gab's noch kein Padding, ALignWithMargins, und
Margins für Layout.
Ich hatte mir seinerzeit noch BDS 2006 gekauft, bin aber nie so
richtig damit warm geworden... und seitdem keine Updates, wegen
"nicht-nötig" und "64-bit-Anwendungen-kann-man-immer-noch-nicht-
erzeugen" (letzteres geht mit den aktuellen Delphis wohl, aber
nachdem ich nun eine größere Update-Lücke habe, müsste ich das
für mehrere KiloEuro neu kaufen - da ist der Leidensdruck noch
nicht groß genug).

Für Neuentwicklungen würde ich heute vermutlich eh Visual Studio
Express verwenden (vermutlich Basic, ich bin kein C-Freund), da
gibts alle zwei Jahre eine aktuelle Version (auch noch für kost-
nix), die außerdem stets zur jeweils aktuellen Windows-Version
passt. Da gibts zwar keinen Pascal-Compiler, aber diese Kröte
würde ich schlucken, wenn das EXE nachher auf allen Auflösungen/
Vergrößerungen/etc. problemlos laufen würde...
Post by Peter Below
Das Problem mit Anchors ist, dass sie quasi einen Referenzpunkt für
Position und Größe des jeweiligen Controls brauchen. Das ist die
Position des Controls nach dem Laden des Forms aus der DFM-Resource. Da
gibt es aber wohl einen Konflikt mit dem Scaling.
Ja, sieht so aus. Die Mehrzahl der Probleme scheint bei 1280x1024
aufzutreten, aber wenn ich das hier selber mal einstelle, geht bei
mir seltsamerweise alles. Einen Problemfall hatte ich aber auch
schon mit 1920x1080 (und einer Vergrößerung von 175%, die aber
hier bei mir testweise auch schon funktioniert hat). Ich selber
habe 1920x1200 mit einer Vergrößerung von 150%. Vielleicht sollte
ich die IDE zum Compilieren mal mit 100% laufen lassen?!
Post by Peter Below
Ich kann Dir da leider keine wirkliche Hilfe geben. Manchmal
funktioniert es wirklich am besten, wenn man einfach das Layout in Code
korrigiert (OnCreate event), wenn das Scaling es verhunzt hat.
Reicht das beim OnCreate, oder muss man das nach jedem OnResize
machen?

Wie würde man das prüfen bzw. korrigieren? Auf Anhieb fiele mir
da z.B. ein

if ButtonOk.Top>FormDings.Height then // Ok-Button ist unterhalb der Form
ButtonOk.Top:=FormDings.Height-ButtonOk.Height-24;

also den Ok-Button manuell so weit nach oben positionieren, dass
seine Unterkante 24 Pixel Abstand zum unteren Form-Rand hat? Bzw.
vermutlich eher ClientHeight statt Height.

Blöd, wenn ich das hier dann nicht ausprobieren kann... :-( Na gut,
das manuelle Setzen würde dann auch hier funktionieren. Aber müsste
ich dann diese "24" aus dem obigen Beispiel nicht noch irgendwie
mit Screen.PixelsPerInch anpassen oder so?! Oder eher mit der "Ver-
größerung" aus Windows "Bildschirm anpassen"? Aber kriegt man die
in Delphi überhaupt? Jetzt krieg' ich langsam einen Knoten ins Hirn...
Post by Peter Below
Borland hat da leider seinerzeit (Delphi 1) die Entscheidung getroffen,
all Positionen und Größen für Controls und Fonts in device units
anzugeben und nicht (wie VB) in device independent units (twips). Das
war sicher sehr gut für performance und vereinfachte das Interface mit
dem API für die VCL, aber es ist mittlerweile ein massives Problem
geworden, seit Windows mit x verschiedenen DPI Werten aufwarten kann.
Ja, früher hatte ich solche Probleme eigentlich nie. Das hat alles
erst in den letzten Monaten angefangen...

Gruß Matthias.
Matthias Hanft
2017-08-26 18:20:48 UTC
Permalink
Post by Matthias Hanft
Blöd, wenn ich das hier dann nicht ausprobieren kann...
Ich habs jetzt endlich auf einem virtuellen Windows 7 geschafft,
indem ich dort 125% Vergrößerung eingestellt habe.

Auf meinem Entwicklungsrechner sieht es so (richtig) aus:
Loading Image...

Dieselbe Form auf dem Win7:
Loading Image...
Das untere Panel wird hier gar nicht angezeigt?!

Wenn man das dort größer zieht, bleibt das auch so:
Loading Image...

Was kann man da tun? Momentan hat mein Programm gar kein Manifest.
Könnte ein Manifest mit dpiaware=false oder true helfen?

Oder sonst irgendwas?

Danke & Gruß Matthias.
Peter Below
2017-08-27 09:29:34 UTC
Permalink
Post by Matthias Hanft
Post by Matthias Hanft
Blöd, wenn ich das hier dann nicht ausprobieren kann...
Ich habs jetzt endlich auf einem virtuellen Windows 7 geschafft,
indem ich dort 125% Vergrößerung eingestellt habe.
https://www.myebilanz.de/tmp/myebilanz148.png
https://www.myebilanz.de/tmp/myebilanz149.png
Das untere Panel wird hier gar nicht angezeigt?!
Ja, das Scaling hat da den Inhalt des Forms vergrößert aber das Form
selbst nicht. Dir ist vielleicht auch aufgefallen, dass Border und
Titelleiste unter Win7 höher sind als auf deinem Entwicklungsrechner,
dadurch ist die client area etwas kleiner.
Post by Matthias Hanft
https://www.myebilanz.de/tmp/myebilanz150.png
Ja, weil die Achors halt ihre Referenzwerte *nach* dem Skalieren
gesetzt haben und damit dann die falschen Positionen beibehalten.
Post by Matthias Hanft
Was kann man da tun? Momentan hat mein Programm gar kein Manifest.
Könnte ein Manifest mit dpiaware=false oder true helfen?
Vermutlich nur teilweise. Wenn ein Programm nicht als DPI-aware
markiert ist wird es von Windows angelogen, wenn es nach dem
PixelsPerInch-Wert fragt, was das Skaling noch mehr aus dem Tritt
bringt.

Du kannst hier eigentlich nur eines machen: die Höhe des panels mit
client alignment in OnCreate neu berechenen als

clientpanel.height :=
clientheight - summe der heights aller top und bottom-alignten
controls

Das sollte eigentlich funktionieren.
--
Peter Below
TeamB
Matthias Hanft
2017-08-27 10:00:19 UTC
Permalink
Post by Peter Below
Ja, das Scaling hat da den Inhalt des Forms vergrößert aber das Form
selbst nicht. Dir ist vielleicht auch aufgefallen, dass Border und
Titelleiste unter Win7 höher sind als auf deinem Entwicklungsrechner,
dadurch ist die client area etwas kleiner.
Ja, die TStatusBar im Main Window ist unten auch ein paar Pixel zu
wenig hoch...
Post by Peter Below
Post by Matthias Hanft
Was kann man da tun? Momentan hat mein Programm gar kein Manifest.
Könnte ein Manifest mit dpiaware=false oder true helfen?
Vermutlich nur teilweise. Wenn ein Programm nicht als DPI-aware
markiert ist wird es von Windows angelogen, wenn es nach dem
PixelsPerInch-Wert fragt, was das Skaling noch mehr aus dem Tritt
bringt.
Also ich hab jetzt mal ein Manifest mit dpiaware=false und true
ausprobiert - keinerlei Unterschied. Außer dass das gesamte Lay-
out jetzt "moderner" ausschaut, wenn man in dem Manifest die
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" rein-
schreibt. Kann man das so lassen, oder kann das irgendwelche
negativen Einflüsse haben?

Wobei anscheinend/angeblich richtig skaliert wird, wenn man in
den Skalierungs-Eigenschaften "Anwendung" auf "System" umstellt:
Loading Image...
Aber das gibts nur auf Windows 10...
Post by Peter Below
Du kannst hier eigentlich nur eines machen: die Höhe des panels mit
client alignment in OnCreate neu berechenen als
clientpanel.height :=
clientheight - summe der heights aller top und bottom-alignten
controls
Das sollte eigentlich funktionieren.
Auf welcher Ebene muss man das machen?

OnFormCreate: Form.Height:=PanelTop.Height+PanelBottom.Height+StatusBar.Height

oder

OnPanelCreate: Panel.Height:=PageControl.Height // oder was halt auf dem Panel ist

oder beides? Na, ich werde mal etwas herumexperimentieren... jetzt
hab ich ja ein Testobjekt, wo ichs ausprobieren kann :-)

Gruß Matthias.
Matthias Hanft
2017-08-27 12:40:48 UTC
Permalink
So, vertikal hab ichs jetzt im Griff - da kann man PanelTop.Height geeignet
setzen. Aber horizontal ist das PanelBottom immer noch zu breit - und das
Setzen von PanelBottom.Width wird offenbar ignoriert (egal, ob Align=alBottom
oder Align=alClient).

Entwicklungsrechner mit 96 dpi:
Loading Image...

Windows 7, 1280x1024, 120 dpi:
Loading Image...

Die Buttons werden offenbar selbstständig größer, was auch OK ist, aber
das PanelBottom ist immer noch *viel* zu breit, und ich weiß nicht, wie
ich das weniger breit kriege.

Ideen?

Danke & Gruß Matthias.
Matthias Hanft
2017-08-27 18:02:39 UTC
Permalink
Post by Matthias Hanft
Die Buttons werden offenbar selbstständig größer, was auch OK ist, aber
das PanelBottom ist immer noch *viel* zu breit, und ich weiß nicht, wie
ich das weniger breit kriege.
Hatte doch noch ne Idee:

Bisher wars so:

+-------------------------------------------------------+
| PanelTop |
| +------------------------+ +----------------------+ |
| | PanelTopLeft | | PanelTopRight | |
| +------------------------+ +----------------------+ |
+-------------------------------------------------------+
+-------------------------------------------------------+
| PanelBottom |
+-------------------------------------------------------+

Und jetzt ists so:

+------------------------------------------------------------+ +---------+
| PanelGlobalLeft | | Panel |
| +-------------------------------------------------------+ | | Global |
| | PanelTop | | | Right |
| | +------------------------+ +----------------------+ | | | |
| | | PanelTopLeft | | PanelTopRight | | | | |
| | +------------------------+ +----------------------+ | | | |
| +-------------------------------------------------------+ | | |
| +-------------------------------------------------------+ | | |
| | PanelBottom | | | |
| +-------------------------------------------------------+ | | |
+------------------------------------------------------------+ +---------+

Das PanelGlobalRight hat erst mal Width=1 und Visible=False, und
wenn man im FormCreate PanelGlobalLeft.Width=ClientWidth setzt,
geht's - voilà! (Im "TopRight" ist noch ein untergeordnetes Panel,
aber das kriege ich dann sicher auch noch hin.)

BTW,
Post by Matthias Hanft
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" rein-
schreibt. Kann man das so lassen, oder kann das irgendwelche
negativen Einflüsse haben?
Hat es: Wenn man ALT drückt, verschwinden die Controls, die Enabled=False
haben. Ist wohl ein bekannter Effekt - zumindest unter Vista; scheint aber
auch noch unter Win7 SP1 aufzutreten. Da kehre ich dann wohl doch lieber
wieder zu meiner altbackenen Win2000-Oberfläche zurück :-)

Gruß Matthias.

Loading...