Michael Landenberger
2022-01-24 11:52:36 UTC
Hallo,
ich schreibe gerade an einem Programm, bei dem ich möchte, dass der innerhalb
des Programms verwendete Font derselbe ist wie der, den Windows für
Titelzeilen, Menüs etc. verwendet. Ich möchte auch in jedem Fall
sicherstellen, dass sich das Programm in diesem Punkt nach den
Windows-Einstellungen richtet und dabei auch Änderungen an diesen
Einstellungen durch den Benutzer berücksichtigt.
Um zu ermitteln, welche Schriftarten eingestellt sind, verwende ich die
API-Funktion SystemParametersInfo () mit SPI_GETNONCLIENTMETRICS als
Parameter. Die Funktion füllt eine Struktur vom Typ TNonClientMetrics mit den
entsprechenden Daten.
Die Struktur TNonClientMetrics enthält u. a. die Felder lfMenuFont,
lfStatusFont und lfMessageFont. Alle drei sind vom Typ TLogFont. Dieser
wiederum enthält das Feld lfFaceName mit dem Namen des entsprechenden Fonts.
Ich habe nun festgestellt, dass nach Aufruf der Funktion bei allen drei Fonts
in lfFaceName 'Segoe UI' steht. Das ist aber leider nicht der Font, den
Windows für Menüs etc. verwendet. Vielmehr ist der dort verwendete Font
zumindest auf meinem System 'Tahoma'. Stelle ich diesen Font in meinem
Programm ein, sehen Texte im Programm genauso aus wie die Menüs oder die
Fenster-Titelzeile. Verwende ich dagegen den durch SystemParametersInfo
ermittelten Font 'Segoe UI', unterscheiden sich Texte im Programm minimal von
denen in Menüs und Titelzeile.
Auffällig ist auch, dass 'Tahoma' auch der Standardwert ist, mit dem neu
erstellte Font-Objekte vorbelegt sind. Irgendwoher muss Delphi diesen Font
haben. Aber woher? Sollte dieser Font bei jeder Erstellung eines Formulars von
Windows abgefragt werden, wäre es einfach: ich müsste dann nur einmalig ein
TFont-Objekt erstellen und dessen Namen für spätere Verwendung speichern. Ist
der Font dagegen in der VCL hart codiert [1], nutzt mir das nix, denn es wird
dann immer 'Tahoma' verwendet, auch wenn der Benutzer einen anderen Font
eingestellt hat.
[1] Ich habe durch Analyse der Unit VCL.Graphics festgestellt, dass TFont beim
Erstellen mit einer Struktur namens DefFontData initialisiert wird. In dieser
Struktur ist aber 'MS Sans Serif' eingetragen. Trotzdem enthält in folgendem
Codebeispiel die Variable "FontName" nach der Ausführung den String 'Tahoma':
var
FontName : string;
...
with TFont.Create do begin
FontName := Name;
Free
end;
Wo um alles in der Welt kommt das her? Der Quelltext der Methode TFont.GetName
liefert keinen Hinweis darauf. Wäre für etwas Aufklärung dankbar.
Gruß
Michael
ich schreibe gerade an einem Programm, bei dem ich möchte, dass der innerhalb
des Programms verwendete Font derselbe ist wie der, den Windows für
Titelzeilen, Menüs etc. verwendet. Ich möchte auch in jedem Fall
sicherstellen, dass sich das Programm in diesem Punkt nach den
Windows-Einstellungen richtet und dabei auch Änderungen an diesen
Einstellungen durch den Benutzer berücksichtigt.
Um zu ermitteln, welche Schriftarten eingestellt sind, verwende ich die
API-Funktion SystemParametersInfo () mit SPI_GETNONCLIENTMETRICS als
Parameter. Die Funktion füllt eine Struktur vom Typ TNonClientMetrics mit den
entsprechenden Daten.
Die Struktur TNonClientMetrics enthält u. a. die Felder lfMenuFont,
lfStatusFont und lfMessageFont. Alle drei sind vom Typ TLogFont. Dieser
wiederum enthält das Feld lfFaceName mit dem Namen des entsprechenden Fonts.
Ich habe nun festgestellt, dass nach Aufruf der Funktion bei allen drei Fonts
in lfFaceName 'Segoe UI' steht. Das ist aber leider nicht der Font, den
Windows für Menüs etc. verwendet. Vielmehr ist der dort verwendete Font
zumindest auf meinem System 'Tahoma'. Stelle ich diesen Font in meinem
Programm ein, sehen Texte im Programm genauso aus wie die Menüs oder die
Fenster-Titelzeile. Verwende ich dagegen den durch SystemParametersInfo
ermittelten Font 'Segoe UI', unterscheiden sich Texte im Programm minimal von
denen in Menüs und Titelzeile.
Auffällig ist auch, dass 'Tahoma' auch der Standardwert ist, mit dem neu
erstellte Font-Objekte vorbelegt sind. Irgendwoher muss Delphi diesen Font
haben. Aber woher? Sollte dieser Font bei jeder Erstellung eines Formulars von
Windows abgefragt werden, wäre es einfach: ich müsste dann nur einmalig ein
TFont-Objekt erstellen und dessen Namen für spätere Verwendung speichern. Ist
der Font dagegen in der VCL hart codiert [1], nutzt mir das nix, denn es wird
dann immer 'Tahoma' verwendet, auch wenn der Benutzer einen anderen Font
eingestellt hat.
[1] Ich habe durch Analyse der Unit VCL.Graphics festgestellt, dass TFont beim
Erstellen mit einer Struktur namens DefFontData initialisiert wird. In dieser
Struktur ist aber 'MS Sans Serif' eingetragen. Trotzdem enthält in folgendem
Codebeispiel die Variable "FontName" nach der Ausführung den String 'Tahoma':
var
FontName : string;
...
with TFont.Create do begin
FontName := Name;
Free
end;
Wo um alles in der Welt kommt das her? Der Quelltext der Methode TFont.GetName
liefert keinen Hinweis darauf. Wäre für etwas Aufklärung dankbar.
Gruß
Michael