High DPI/de
│
Deutsch (de) │
English (en) │
español (es) │
русский (ru) │
Zurück zu den Zusätzlichen Informationen.
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.
Unter 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) *.
High DPI awareness (= Berücksichtigung der Hochauflösung) bedeutet also, dass eine Anwendung diese DPI-Einstellungen beachtet.
Pixel und Punkte
Zum 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:
300 Pixel ↔ 1 Inch
300/72 Pixel ↔ 1 Punkt
4.16 Pixel ↔ 1 Punkt
Im Fall von 96 DPI gilt:
72 Pixel ↔ 1 Inch
1.33 Pixel ↔ 1 Punkt
und bei 144 DPI:
144 Pixel ↔ 1 Inch
2 Pixel ↔ 1 Punkt
Benutzerdefinierte Textgröße (High DPI) in Windows festlegen
Unter Windows 7 gehen Sie zu Systemsteuerung > Darstellung und Anpassung > Anzeige.
Wä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.
Bei 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.
Bei 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.
Sie können den DPI-Wert auch mit dem Dialog "Benutzerdefinierte Textgröße (DPI) festlegen" einstellen und die DPI Virtualisierung aktivieren/ deaktivieren.
Beispiel
Hier 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:
Jetzt mit 120 DPI (125%) wird es zu:
Wie 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.
Um 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.
Ber einer fixierten Schriftgröße von 9 Punkt bei 96 DPI (100%), erhalten wir dies:
Wenn jetzt das selbe Programm bei 120 DPI (125%) läuft, wird daraus:
Das 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.
Als 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.
Beispiel (Windows)
CPickSniff ist eine Anwendung zum Abfragen der Farben am Bildschirm. Wir nehmen sie als Beispiel, wie sich High DPI unter Windows auswirkt.
Standard DPI
Das ist das Programm bei 96 DPI (100%). Es ist der Vorgabemodus, in dem keine Skalierung nötig ist.
Windows DPI Skalierung
Dies ist das gleiche Programm bei 144 DPI (150%) ohne ein Manifest, also skaliert Windows es wie eine Bitmap. Das Ergebnis ist ein verwaschenes Bild.
Mit Manifest
Ebenfalls 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.
High DPI
Zuletzt mit Manifest und einem Skalierungshandler, die Anwendung ist in High DPI.
Hochauflösender Text in Lazarus
Mit Lazarus erzeugen Sie eine Anwendung für hochauflösende Schriftgrößen unter Windows 7 mit den beiden folgenden Schritten.
SCHRITT 1 - Deklarieren Sie High DPI Awareness
Dazu 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 +)".
SCHRITT 2 - Skalieren Sie die Formulare und Steuerelemente
Dazu rufen Sie die folgende Prozedur 'ScaleDPI' im Ereignis 'OnCreate' eines jeden Formulars aus Ihrem Projekt auf.
Kopieren Sie zuerst den nachfolgenden Code und speichern Sie ihn in einer Textdatei namens "uscaledpi.pas":
unit uscaledpi;
{$mode objfpc}{$H+}
interface
uses
Forms, Graphics, Controls;
procedure HighDPI(FromDPI: Integer);
procedure ScaleDPI(Control: TControl; FromDPI: Integer);
implementation
procedure HighDPI(FromDPI: Integer);
var
i: Integer;
begin
for i:=0 to Screen.FormCount-1 do
ScaleDPI(Screen.Forms[i],FromDPI);
end;
procedure ScaleDPI(Control: TControl; FromDPI: Integer);
var
n: Integer;
WinControl: TWinControl;
begin
if Screen.PixelsPerInch = FromDPI then exit;
with Control do begin
Left:=ScaleX(Left,FromDPI);
Top:=ScaleY(Top,FromDPI);
Width:=ScaleX(Width,FromDPI);
Height:=ScaleY(Height,FromDPI);
Font.Height := ScaleY(Font.GetTextHeight('Hg'),FromDPI);
end;
if Control is TWinControl then begin
WinControl:=TWinControl(Control);
if WinControl.ControlCount > 0 then begin
for n:=0 to WinControl.ControlCount-1 do begin
if WinControl.Controls[n] is TControl then begin
ScaleDPI(WinControl.Controls[n],FromDPI);
end;
end;
end;
end;
end;
end.
Kopieren Sie diese Datei "uscaledpi.pas" in den Hauptordner Ihres Projekts:
MyProject\uscaledpi.pas
Fügen Sie im Abschnitt "uses" von Ihrem Projekt den Ausdruck "uScaleDPI" hinzu:
unit form1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
uScaleDPI; // Dies enthält die Prozedur 'ScaleDPI'
Das OnCreate-Ereignis jedes Formulars ruft die Prozedur so auf:
procedure TForm1.FormCreate(Sender: TObject);
begin
ScaleDPI(Self,96); // 96 ist der DPI-Wert beim Entwurf des Formulars
end;
Skalieren Sie alle Formulare
Sie können den Schritt 2 abändern, um alle Formulare zu skalieren.
Dazu öffnen Sie den Quelltext Ihres Projektes (typischerweise die Datei Project1.lpr) und fügen 'uScaleDPI' im Abschnitt 'uses' hinzu.
Dann rufen Sie die Prozedur HighDPI nach dem Code der die Formulare initialisiert auf:
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
HighDPI(96); // 96 ist der DPI-Wert beim Entwurf der Formulare Form1, Form2 & Form3
Application.Run;
end.
Das Ergebnis sieht so aus:
program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, Forms,
Unit1, Unit2, Unit3,
uScaleDPI;
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
HighDPI(96);
Application.Run;
end.
Fortgeschrittenes
Einige 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.
Sie können die Prozedur 'ScaleDPI' anpassen, sodass der Code alle Steuerelemente in der von Ihnen gewünschten Weise skaliert.
Dies 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.
unit uscaledpi;
{$mode objfpc}{$H+}
interface
uses
Forms, Graphics, Controls, ComCtrls;
procedure HighDPI(FromDPI: Integer);
procedure ScaleDPI(Control: TControl; FromDPI: Integer);
procedure ScaleImageList(ImgList: TImageList; FromDPI: Integer);
implementation
uses BGRABitmap, BGRABitmapTypes;
procedure HighDPI(FromDPI: Integer);
var
i: Integer;
begin
for i:=0 to Screen.FormCount-1 do begin
ScaleDPI(Screen.Forms[i],FromDPI);
end;
end;
procedure ScaleImageList(ImgList: TImageList; FromDPI: Integer);
var
TempBmp: TBitmap;
TempBGRA: array of TBGRABitmap;
NewWidth,NewHeight: integer;
i: Integer;
begin
if Screen.PixelsPerInch = FromDPI then exit;
NewWidth := ScaleX(ImgList.Width,FromDPI);
NewHeight := ScaleY(ImgList.Height,FromDPI);
setlength(TempBGRA, ImgList.Count);
TempBmp := TBitmap.Create;
for i := 0 to ImgList.Count-1 do
begin
ImgList.GetBitmap(i,TempBmp);
TempBGRA[i] := TBGRABitmap.Create(TempBmp);
TempBGRA[i].ResampleFilter := rfBestQuality;
if (TempBGRA[i].width=0) or (TempBGRA[i].height=0) then continue;
while (TempBGRA[i].Width < NewWidth) or (TempBGRA[i].Height < NewHeight) do
BGRAReplace(TempBGRA[i], TempBGRA[i].FilterSmartZoom3(moLowSmooth));
BGRAReplace(TempBGRA[i], TempBGRA[i].Resample(NewWidth,NewHeight));
end;
TempBmp.Free;
ImgList.Clear;
ImgList.Width:= NewWidth;
ImgList.Height:= NewHeight;
for i := 0 to high(TempBGRA) do
begin
ImgList.Add(TempBGRA[i].Bitmap,nil);
TempBGRA[i].Free;
end;
end;
procedure ScaleDPI(Control: TControl; FromDPI: Integer);
var
n: Integer;
WinControl: TWinControl;
ToolBarControl: TToolBar;
begin
if Screen.PixelsPerInch = FromDPI then exit;
with Control do begin
Left:=ScaleX(Left,FromDPI);
Top:=ScaleY(Top,FromDPI);
Width:=ScaleX(Width,FromDPI);
Height:=ScaleY(Height,FromDPI);
Font.Height := ScaleY(Font.GetTextHeight('Hg'),FromDPI);
end;
if Control is TToolBar then begin
ToolBarControl:=TToolBar(Control);
with ToolBarControl do begin
ButtonWidth:=ScaleX(ButtonWidth,FromDPI);
ButtonHeight:=ScaleY(ButtonHeight,FromDPI);
end;
end;
if Control is TWinControl then begin
WinControl:=TWinControl(Control);
if WinControl.ControlCount > 0 then begin
for n:=0 to WinControl.ControlCount-1 do begin
if WinControl.Controls[n] is TControl then begin
ScaleDPI(WinControl.Controls[n],FromDPI);
end;
end;
end;
end;
end;
end.
Abschließende Bemerkungen
Das Entwickeln von Anwendungen, die die DPI-Einstellungen und Themen berücksichtigen, umfasst zwei Schritte:
- 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)
- Skalieren Sie die Komponenten zur Laufzeit
- Passen Sie den ScaleDPI-Code an Ihre Bedürfnisse an
Anmerkung:
Siehe die Diskussionsseite für weitere Informationen: Talk:High_DPI.
Wir verwenden nicht ScaleBy & ScaleControls:
Self.ScaleBy(Screen.PixelsPerInch,96);
Dies 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.
Self.ScaleControls(Screen.PixelsPerInch,96);
Dies skaliert nicht die Breite / Höhe des Formulars. Könnte nützlich sein, wenn Sie diese selbst skalieren.
Externe Links
- High DPI (Windows) MSDN article about High DPI
- Windows Icon How to create icons that work with High DPI.