Sign in Join
Wiki copytemporary

High DPI/de: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
22
33== Definition == DPI (dots per inch = Punkte pro Zoll) ist das Verhältnis zwischen Größe in Pixeln und der tatsächlichen Anzeigegröße. Hier steht "Punkt" (dot) als Äquivalent für Pixel in der Druckterminologie. Anwendungen können entweder Pixelgrößen verwenden, oder die aktuelle Anzeigegröße berücksichtigen. In diesem zweiten Fall sind die Größen in "Punkten" angegeben.
44
55Unter Windows Vista und höher ist es möglich, das DPI-Verhältnis zu ändern, um Elemente größer darzustellen. High DPI ("Hochauflösung") bedeutet jede benutzerdefinierte Textgröße (DPI) mit mehr als 96 DPI (Standard) \[<http://msdn.microsoft.com/en-us/library/ee318406(VS.85>).aspx *\].
66
77High DPI awareness (= Berücksichtigung der Hochauflösung) bedeutet also, dass eine Anwendung diese DPI-Einstellungen beachtet.
88
99## Pixel und Punkte
1010
1111Zum Beispiel bedeutet 300 DPI, dass es 300 Pixel (oder dot) pro Inch gibt. Wenn aber dafür 72 Punkte pro Inch definiert sind, so bedeutet das:
1212
1313300 Pixel ↔ 1 Inch
1414
1515300/72 Pixel ↔ 1 Punkt
1616
17174.16 Pixel ↔ 1 Punkt
1818
1919Im Fall von 96 DPI gilt:
2020
212172 Pixel ↔ 1 Inch
2222
23231.33 Pixel ↔ 1 Punkt
2424
2525und bei 144 DPI:
2626
2727144 Pixel ↔ 1 Inch
2828
29292 Pixel ↔ 1 Punkt
3030
3131## Benutzerdefinierte Textgröße (High DPI) in Windows festlegen
3232
3333Unter Windows 7 gehen Sie zu Systemsteuerung \> Darstellung und Anpassung \> Anzeige.
3434
3535Wählen Sie: Kleiner 100% (Standard), Mittel 125% oder Größer 150%. Wenn Sie 100% (96 DPI) ausgewählt haben, ist das die Standardeinstellung von Windows für den DPI-Wert, aber nicht High DPI.
3636
3737Bei 125% (120 DPI) ist die Option "DPI-Skalierung im Stil von Windows XP verwenden" aktiviert, Anwendungen werden unter diesen Einstellungen wie bei Windows XP skaliert.
3838
3939Bei 150% (144 DPI) ist die Option "DPI-Skalierung im Stil von Windows XP verwenden" deaktiviert (die DPI Virtualisierung ist aktiviert). Anwendungen, die mit dieser Einstellung ablaufen, müssen selbst die Hochauflösung verwalten ("High DPI Awareness") ansonsten liefert die Skalierung des Systems ein verwischtes, unscharfes Bild.
4040
4141Sie können den DPI-Wert auch mit dem Dialog "Benutzerdefinierte Textgröße (DPI) festlegen" einstellen und die DPI Virtualisierung aktivieren/ deaktivieren.
4242
4343## Beispiel
4444
4545Hier ist ein Formular mit undefinierter Fontgröße (Size ist auf 0 gesetzt; das ist der Vorgabewert). Entworfen bei 96 DPI (100%), sieht das so aus:
4646
4747![](/wiki-images/7/75/Testdpi100.png)
4848
4949Jetzt mit 120 DPI (125%) wird es zu:
5050
5151![](/wiki-images/0/03/Testdpi125.png)
5252
5353Wie Sie sehen wird die Schrift größer und abgeschnitten. Der Fenstertitel wird größer, aber der Clientbereich behält seine Abmessungen. Beachten Sie, dass diese Größenänderungen beim Einsatz verschiedener Windows-Themen oder eines anderen Betriebssystems auftreten können.
5454
5555Um dies zu vermeiden setzen Sie die Schriftgröße (Size) auf einen Wert ungleich 0. Beachten Sie, dass Font.Size in Punkten angegeben wird und Font.Height in Pixel. Tatsächlich wird nur der Wert von Font.Height gespeichert und Font.Size ändert sich abhängig vom aktuellen DPI-Wert. Wenn wir also Font.Size angeben, wird die Schriftgröße auf eine bestimmte Größe in Pixeln festgelegt.
5656
5757Ber einer fixierten Schriftgröße von 9 Punkt bei 96 DPI (100%), erhalten wir dies:
5858
5959![](/wiki-images/f/fe/Testdpi100fixedM12P9.png)
6060
6161Wenn jetzt das selbe Programm bei 120 DPI (125%) läuft, wird daraus:
6262
6363![](/wiki-images/a/a1/Testdpi125fixedM12P9.png)
6464
6565Das Ergebnis ist fast das selbe. Die Titelzeile ist größer, aber der Clientbereich und dessen Schriftgröße blieben gleich. Beachten Sie aber, dass sich die Punktgröße der Titelschriftart geändert hat.
6666
6767Als Schlussfolgerung ist es möglich, Inkonsistenzen der Anzeige durch Festlegung der Schriftgrößen zu vermeiden. Aber wir berücksichtigen dabei nicht, dass die grafischen Elemente durch die aktuellen DPI des Bildschirms weniger Platz lassen. Bei Berücksichtigung der Hochauflösung ist es möglich, dass sich Anwendungen so verhalten, als wüßten sie die wirkliche Größe der Pixel.
6868
6969## Beispiel (Windows)
7070
7171[CPickSniff](http://sourceforge.net/projects/cpicksniff2/) ist eine Anwendung zum Abfragen der Farben am Bildschirm. Wir nehmen sie als Beispiel, wie sich High DPI unter Windows auswirkt.
7272
7373### Standard DPI
7474
7575Das ist das Programm bei 96 DPI (100%). Es ist der Vorgabemodus, in dem keine Skalierung nötig ist.
7676
7777![](/wiki-images/4/4b/Cpicksniff_defaultdpi.png)
7878
7979### Windows DPI Skalierung
8080
8181Dies ist das gleiche Programm bei 144 DPI (150%) ohne ein Manifest, also skaliert Windows es wie eine Bitmap. Das Ergebnis ist ein verwaschenes Bild.
8282
8383![](/wiki-images/5/54/Cpicksniff_blured.png)
8484
8585### Mit Manifest
8686
8787Ebenfalls bei 144 DPI (150%). Dieses Mal enthält die Anwendung ein Manifest, aber sie enthält keinen Code, um mit der Skalierung umzugehen. Die Elemente werden nicht skaliert, die Schrift schon (Windows macht das automatisch), also wird der Text abgeschnitten.
8888
8989![](/wiki-images/1/1b/Cpicksniff_nohighdpi.png)
9090
9191### High DPI
9292
9393Zuletzt mit Manifest und einem Skalierungshandler, die Anwendung ist in High DPI.
9494
9595![](/wiki-images/b/bd/Cpicksniff_highdpi.png)
9696
9797## Hochauflösender Text in Lazarus
9898
9999Mit Lazarus erzeugen Sie eine Anwendung für hochauflösende Schriftgrößen unter Windows 7 mit den beiden folgenden Schritten.
100100
101101### SCHRITT 1 - Deklarieren Sie High DPI Awareness
102102
103103Dazu brauchen Sie eine Manifest-Datei die diese Deklaration enthält. Mit Lazarus 0.9.30 erreichen Sie dies mit Projekt \> Projekteinstellungen \> dann wählen Sie die Optionen "Themen mit Manifest-Datei einschalten (nur in Windows)" und "dpi-abhängige Anwendung (für Vista +)".
104104
105105### SCHRITT 2 - Skalieren Sie die Formulare und Steuerelemente
106106
107107Dazu rufen Sie die folgende Prozedur 'ScaleDPI' im Ereignis 'OnCreate' eines jeden Formulars aus Ihrem Projekt auf.
108108
109109Kopieren Sie zuerst den nachfolgenden Code und speichern Sie ihn in einer Textdatei namens "uscaledpi.pas":
110110
111111``` pascal
112112unit uscaledpi;
113113
114114{$mode objfpc}{$H+}
115115
116116interface
117117
118118uses
119119 Forms, Graphics, Controls;
120120
121121procedure HighDPI(FromDPI: Integer);
122122procedure ScaleDPI(Control: TControl; FromDPI: Integer);
123123
124124implementation
125125
126126procedure HighDPI(FromDPI: Integer);
127127var
128128 i: Integer;
129129begin
130130 for i:=0 to Screen.FormCount-1 do
131131 ScaleDPI(Screen.Forms[i],FromDPI);
132132end;
133133
134134procedure ScaleDPI(Control: TControl; FromDPI: Integer);
135135var
136136 n: Integer;
137137 WinControl: TWinControl;
138138begin
139139 if Screen.PixelsPerInch = FromDPI then exit;
140140
141141 with Control do begin
142142 Left:=ScaleX(Left,FromDPI);
143143 Top:=ScaleY(Top,FromDPI);
144144 Width:=ScaleX(Width,FromDPI);
145145 Height:=ScaleY(Height,FromDPI);
146146 Font.Height := ScaleY(Font.GetTextHeight('Hg'),FromDPI);
147147 end;
148148
149149 if Control is TWinControl then begin
150150 WinControl:=TWinControl(Control);
151151 if WinControl.ControlCount > 0 then begin
152152 for n:=0 to WinControl.ControlCount-1 do begin
153153 if WinControl.Controls[n] is TControl then begin
154154 ScaleDPI(WinControl.Controls[n],FromDPI);
155155 end;
156156 end;
157157 end;
158158 end;
159159end;
160160
161161end.
162162```
163163
164164Kopieren Sie diese Datei "uscaledpi.pas" in den Hauptordner Ihres Projekts:
165165
166-` MyProject\uscaledpi.pas`\
167-` `
166+```text
167+ MyProject\uscaledpi.pas
168+```
168169
169170Fügen Sie im Abschnitt "uses" von Ihrem Projekt den Ausdruck "uScaleDPI" hinzu:
170171
171172``` pascal
172173unit form1;
173174
174175{$mode objfpc}{$H+}
175176
176177interface
177178
178179uses
179180 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
180181 uScaleDPI; // Dies enthält die Prozedur 'ScaleDPI'
181182```
182183
183184Das OnCreate-Ereignis jedes Formulars ruft die Prozedur so auf:
184185
185186``` pascal
186187procedure TForm1.FormCreate(Sender: TObject);
187188begin
188189 ScaleDPI(Self,96); // 96 ist der DPI-Wert beim Entwurf des Formulars
189190end;
190191```
191192
192193### Skalieren Sie alle Formulare
193194
194195Sie können den Schritt 2 abändern, um alle Formulare zu skalieren.
195196
196197Dazu öffnen Sie den Quelltext Ihres Projektes (typischerweise die Datei *Project1.lpr*) und fügen 'uScaleDPI' im Abschnitt 'uses' hinzu.
197198
198199Dann rufen Sie die Prozedur *HighDPI* nach dem Code der die Formulare initialisiert auf:
199200
200201``` pascal
201202begin
202203 RequireDerivedFormResource := True;
203204 Application.Initialize;
204205 Application.CreateForm(TForm1, Form1);
205206 Application.CreateForm(TForm2, Form2);
206207 Application.CreateForm(TForm3, Form3);
207208 HighDPI(96); // 96 ist der DPI-Wert beim Entwurf der Formulare Form1, Form2 & Form3
208209 Application.Run;
209210end.
210211```
211212
212213Das Ergebnis sieht so aus:
213214
214215``` pascal
215216program Project1;
216217
217218{$mode objfpc}{$H+}
218219
219220uses
220221 {$IFDEF UNIX}{$IFDEF UseCThreads}
221222 cthreads,
222223 {$ENDIF}{$ENDIF}
223224 Interfaces, Forms,
224225 Unit1, Unit2, Unit3,
225226 uScaleDPI;
226227
227228{$R *.res}
228229
229230begin
230231 RequireDerivedFormResource := True;
231232 Application.Initialize;
232233 Application.CreateForm(TForm1, Form1);
233234 Application.CreateForm(TForm2, Form2);
234235 Application.CreateForm(TForm3, Form3);
235236 HighDPI(96);
236237 Application.Run;
237238end.
238239```
239240
240241### Fortgeschrittenes
241242
242243Einige Steuerelemente haben mehr Eigenschaften oder abweichende Eigenschaftsnamen wie TToolBar-Buttons (ButtonHeight / ButtonWidth anstelle von Width / Height). Ebenso kann sich das Verhalten unter verschiedenen Betriebssystemen ändern, wenn Sie festgelegte Schriftgrößen verwenden.
243244
244245Sie können die Prozedur 'ScaleDPI' anpassen, sodass der Code alle Steuerelemente in der von Ihnen gewünschten Weise skaliert.
245246
246247Dies ist die in [[LazPaint]] verwendete Unit *uscaledpi*. Sie ist beim Skalieren von ToolBars und ToolBox hilfreich. LazPaint verwendet auch fixe Schriftgrößen für eine einheitliche Darstellung unter verschiedenen Betriebssystemen.
247248
248249``` pascal
249250unit uscaledpi;
250251
251252{$mode objfpc}{$H+}
252253
253254interface
254255
255256uses
256257 Forms, Graphics, Controls, ComCtrls;
257258
258259procedure HighDPI(FromDPI: Integer);
259260procedure ScaleDPI(Control: TControl; FromDPI: Integer);
260261procedure ScaleImageList(ImgList: TImageList; FromDPI: Integer);
261262
262263implementation
263264
264265uses BGRABitmap, BGRABitmapTypes;
265266
266267procedure HighDPI(FromDPI: Integer);
267268var
268269 i: Integer;
269270begin
270271 for i:=0 to Screen.FormCount-1 do begin
271272 ScaleDPI(Screen.Forms[i],FromDPI);
272273 end;
273274end;
274275
275276procedure ScaleImageList(ImgList: TImageList; FromDPI: Integer);
276277var
277278 TempBmp: TBitmap;
278279 TempBGRA: array of TBGRABitmap;
279280 NewWidth,NewHeight: integer;
280281 i: Integer;
281282
282283begin
283284 if Screen.PixelsPerInch = FromDPI then exit;
284285
285286 NewWidth := ScaleX(ImgList.Width,FromDPI);
286287 NewHeight := ScaleY(ImgList.Height,FromDPI);
287288
288289 setlength(TempBGRA, ImgList.Count);
289290 TempBmp := TBitmap.Create;
290291 for i := 0 to ImgList.Count-1 do
291292 begin
292293 ImgList.GetBitmap(i,TempBmp);
293294 TempBGRA[i] := TBGRABitmap.Create(TempBmp);
294295 TempBGRA[i].ResampleFilter := rfBestQuality;
295296 if (TempBGRA[i].width=0) or (TempBGRA[i].height=0) then continue;
296297 while (TempBGRA[i].Width < NewWidth) or (TempBGRA[i].Height < NewHeight) do
297298 BGRAReplace(TempBGRA[i], TempBGRA[i].FilterSmartZoom3(moLowSmooth));
298299 BGRAReplace(TempBGRA[i], TempBGRA[i].Resample(NewWidth,NewHeight));
299300 end;
300301 TempBmp.Free;
301302
302303 ImgList.Clear;
303304 ImgList.Width:= NewWidth;
304305 ImgList.Height:= NewHeight;
305306
306307 for i := 0 to high(TempBGRA) do
307308 begin
308309 ImgList.Add(TempBGRA[i].Bitmap,nil);
309310 TempBGRA[i].Free;
310311 end;
311312end;
312313
313314procedure ScaleDPI(Control: TControl; FromDPI: Integer);
314315var
315316 n: Integer;
316317 WinControl: TWinControl;
317318 ToolBarControl: TToolBar;
318319begin
319320 if Screen.PixelsPerInch = FromDPI then exit;
320321
321322 with Control do begin
322323 Left:=ScaleX(Left,FromDPI);
323324 Top:=ScaleY(Top,FromDPI);
324325 Width:=ScaleX(Width,FromDPI);
325326 Height:=ScaleY(Height,FromDPI);
326327 Font.Height := ScaleY(Font.GetTextHeight('Hg'),FromDPI);
327328 end;
328329
329330 if Control is TToolBar then begin
330331 ToolBarControl:=TToolBar(Control);
331332 with ToolBarControl do begin
332333 ButtonWidth:=ScaleX(ButtonWidth,FromDPI);
333334 ButtonHeight:=ScaleY(ButtonHeight,FromDPI);
334335 end;
335336 end;
336337
337338 if Control is TWinControl then begin
338339 WinControl:=TWinControl(Control);
339340 if WinControl.ControlCount > 0 then begin
340341 for n:=0 to WinControl.ControlCount-1 do begin
341342 if WinControl.Controls[n] is TControl then begin
342343 ScaleDPI(WinControl.Controls[n],FromDPI);
343344 end;
344345 end;
345346 end;
346347 end;
347348end;
348349
349350end.
350351```
351352
352353## Abschließende Bemerkungen
353354
354355Das Entwickeln von Anwendungen, die die DPI-Einstellungen und Themen berücksichtigen, umfasst zwei Schritte:
355356
356357- Legen Sie eine fixe Schriftgröße fest zum Zeitpunkt der Entwickung (Nützlich für cross-platform Anwendungen, aber unnötig wenn nur Windows als Zielsystem)
357358- Skalieren Sie die Komponenten zur Laufzeit
358359- Passen Sie den ScaleDPI-Code an Ihre Bedürfnisse an
359360
360361**Anmerkung:**
361362
362363Siehe die Diskussionsseite für weitere Informationen: Talk:High_DPI.
363364
364365Wir verwenden nicht ScaleBy & ScaleControls:
365366
366367``` pascal
367368Self.ScaleBy(Screen.PixelsPerInch,96);
368369```
369370
370371Dies skaliert die Schrift, ist aber unter Windows überflüssig, weil das Betriebssystem die Schrift selbst ändert. Könnte nützlich sein, wenn Sie eine fixierte Schriftgröße verwenden.
371372
372373``` pascal
373374Self.ScaleControls(Screen.PixelsPerInch,96);
374375```
375376
376377Dies skaliert nicht die Breite / Höhe des Formulars. Könnte nützlich sein, wenn Sie diese selbst skalieren.
377378
378379## Externe Links
379380
380381- \[<http://msdn.microsoft.com/en-us/library/dd464646(v=VS.85>).aspx High DPI (Windows)\] MSDN article about High DPI
381382- [[Windows Icon]] How to create icons that work with High DPI.
382383
383384---
384385*From the Free Pascal wiki, page "High DPI/de", as it stood on 2020-02-17 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history