[WinAPI] Muss man Dialogen Schriftarten mitgeben?
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
[WinAPI] Muss man Dialogen Schriftarten mitgeben?
Hi,
ich habe einem Dialog einen Button hinzugefügt. Nicht über den Ressource Editor, sondern über die minimale DLGITEMTEMPLATE-Datenstruktur. Und so sieht er aus:
Windows 95 ftw! Ist das normal so? Ich erreiche nach Google-Copy-Paste das beabsichtigte Verhalten, wenn ich dem Dialog eine Schriftart hinzufüge (DS_SHELLFONT mit 8 pt und MS Shell Dlg).
Nun bin ich aber stutzig, ob man das tatsächlich überall machen muss, oder ob ich was falsch gemacht habe und deshalb leide – und ob DS_SHELLFONT überhaupt eine Lösung ist und das nicht nur durch Zufall funktioniert …?
tl;dr: Wie kriege ich hin, dass mein Button aussieht wie alle anderen auch?
ich habe einem Dialog einen Button hinzugefügt. Nicht über den Ressource Editor, sondern über die minimale DLGITEMTEMPLATE-Datenstruktur. Und so sieht er aus:
Windows 95 ftw! Ist das normal so? Ich erreiche nach Google-Copy-Paste das beabsichtigte Verhalten, wenn ich dem Dialog eine Schriftart hinzufüge (DS_SHELLFONT mit 8 pt und MS Shell Dlg).
Nun bin ich aber stutzig, ob man das tatsächlich überall machen muss, oder ob ich was falsch gemacht habe und deshalb leide – und ob DS_SHELLFONT überhaupt eine Lösung ist und das nicht nur durch Zufall funktioniert …?
tl;dr: Wie kriege ich hin, dass mein Button aussieht wie alle anderen auch?
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Okay; in der MSDN steht:
Ich schreibe meinen Kram auf Extended Dialog Resources um und melde mich dann zurück.
Ja; sehen wir.http://msdn.microsoft.com/en-us/library/windows/desktop/ms644994(v=vs.85).aspx#fonts hat geschrieben:Dialog Box Fonts
The system uses the average character width of the dialog box font to calculate the position and dimensions of the dialog box. By default, the system draws all text in a dialog box using the SYSTEM_FONT font.
MhmmTo specify a font for a dialog box other than the default, […] set the DS_SETFONT or DS_SHELLFONT style and specify a point size and a typeface name. Even if a dialog box template specifies a font in this manner, the system always uses the system font for the dialog box title and dialog box menus.
Det hebick sou jemacht!The system font can vary between different versions of Windows. To have your application use the system font no matter which system it is running on, use DS_SHELLFONT with the typeface MS Shell Dlg,
Ups.and use the DIALOGEX Resource instead of the DIALOG Resource.
Ich schreibe meinen Kram auf Extended Dialog Resources um und melde mich dann zurück.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Ich habe WinAPI schon sehr lange nicht mehr angerührt, aber so hatte ich das früher in meinen Programmen gelöst:
Code: Alles auswählen
HFONT systemFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hWnd, WM_SETFONT, (WPARAM) systemFont, TRUE);
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Wiebitte? Lösungen, die ausführbaren Code erfordern? Mach dich nicht lächerlich ;)
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Habe grad in nem alten Code von mir geschaut wo ich einen Dialog dynamisch aufbaue. Ich benutze da zwar DS_SETFONT statt DS_SHELLFONT, aber setze den Font auch auf "MS Sans Serif". Warum weiß ich aber nicht... Ich würd das einfach so lassen bis das Projekt groß genug ist um in esoterische Sprachen übersetzt zu werden und dann einfach mal schauen obs Probleme mit dem Font gibt. Würde mich aber wundern, wenn Windows dann nicht automatisch nen anderen Font wählt.
Statt mit DLGITEMTEMPLATE rumzufummeln kann man übrigens auch einfach CreateWindow mit "BUTTON" als Klasse benutzen.
Statt mit DLGITEMTEMPLATE rumzufummeln kann man übrigens auch einfach CreateWindow mit "BUTTON" als Klasse benutzen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Nein danke. Ich arbeite auf meinem anderen PC mit großen Schriftarten und nachts auch mit anderen Desktop-Themas, und ich habe keine Lust, mein „groß genuges“ Projekt dann wegen so einem Detail halb neu zu schreiben.Helmut hat geschrieben:Habe grad in nem alten Code von mir geschaut wo ich einen Dialog dynamisch aufbaue. Ich benutze da zwar DS_SETFONT statt DS_SHELLFONT, aber setze den Font auch auf "MS Sans Serif". Warum weiß ich aber nicht... Ich würd das einfach so lassen bis das Projekt groß genug ist um in esoterische Sprachen übersetzt zu werden und dann einfach mal schauen obs Probleme mit dem Font gibt.
Tut es sogar mit MS Shell Dlg nicht; ich hab’s eben getestet :)Würde mich aber wundern, wenn Windows dann nicht automatisch nen anderen Font wählt.
Schon wieder ausführbarer Code, bah. Außerdem musst du dann noch Dialog Units in Pixel umrechnen usw usf. Ich bastle meine GUI lieber statisch zusammen und rufe zur Laufzeit nur CreateDialogIndirectParamW() auf.Statt mit DLGITEMTEMPLATE rumzufummeln kann man übrigens auch einfach CreateWindow mit "BUTTON" als Klasse benutzen.
Zuletzt geändert von Krishty am 07.06.2013, 22:07, insgesamt 1-mal geändert.
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Okay, eine Suche nach WM_SETFONT hat gerade ergeben, dass ich das auch so wie CodingCat gemacht habe.
Kann übrigens jedem nur raten das dynamische Erstellen von Dialogen zu vermeiden. Das ist einfach nur ne Quälerei.
Kann übrigens jedem nur raten das dynamische Erstellen von Dialogen zu vermeiden. Das ist einfach nur ne Quälerei.
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Soweit ich weiß ersetzt Windows die Schriftart auch nur, wenn man die entsprechende Windowsversion benutzt. Also zB mit einem Font mit arabischen und den üblichen lateinischen Zeichen, wenn man die arabische Sprache in Windows aktiviert hat. Anders geht es nicht, weil kein Font alle Unicodezeichen enthalten kann.Krishty hat geschrieben:Tut es sogar mit MS Shell Dlg nicht; ich hab’s eben getestet :)Würde mich aber wundern, wenn Windows dann nicht automatisch nen anderen Font wählt.
Wenn du deine GUI statisch basteln willst sparst du dir mit dem Resourceneditor viel Nerven.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Ja; du hast recht. Eine Erklärung dafür habe ich auch von jemand Bekanntem auf StackOverflow gefunden:Helmut hat geschrieben:Soweit ich weiß ersetzt Windows die Schriftart auch nur, wenn man die entsprechende Windowsversion benutzt. Also zB mit einem Font mit arabischen und den üblichen lateinischen Zeichen, wenn man die arabische Sprache in Windows aktiviert hat. Anders geht es nicht, weil kein Font alle Unicodezeichen enthalten kann.Krishty hat geschrieben:Tut es sogar mit MS Shell Dlg nicht; ich hab’s eben getestet :)Würde mich aber wundern, wenn Windows dann nicht automatisch nen anderen Font wählt.
Ich suche mal weiter, wie ich die Dinger von der Schriftart unabhängig kriege.http://stackoverflow.com/questions/7219213/system-default-dialog-font hat geschrieben:How do you know that your dialog is compatible with the metrics of an unknown font? What if the users font has metrics that result in your template generating a dialog with truncated text? – Raymond Chen Aug 28 '11 at 15:38
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Cat, deine Lösung setzt wohl auch den Standard-Windows-GUI-Font und nicht den, den der Benutzer eingestellt hat. Außerdem wird dringend davon abgeraten (The Old New Thing – What are SYSTEM_FONT and DEFAULT_GUI_FONT?). Die bessere Lösung ist wohl
NONCLIENTMETRICS metrix; metrix.cbSize = sizeof metrix;
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrix, 0);
hFont = CreateFontIndirectW(&metrix.lfMessageFont);
NONCLIENTMETRICS metrix; metrix.cbSize = sizeof metrix;
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrix, 0);
hFont = CreateFontIndirectW(&metrix.lfMessageFont);
Zuletzt geändert von Krishty am 14.05.2014, 11:15, insgesamt 1-mal geändert.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Okayokay. Um ein Bisschen Ordnung ins Wirrwarr zu bringen:
Windows 7 selber ist inkohärent in benutzerdefinierten Schriftarten. Manchmal werden sie benutzt, manchmal nicht:
Falls man an die benutzerdefinierte Schriftart unbedingt rankommen will:
NONCLIENTMETRICS metrix; metrix.cbSize = sizeof metrix;
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrix, 0);
hFont = CreateFontIndirectW(&metrix.lfMessageFont);
Aber Windows macht es, wie gesagt, meist selber nicht. Es wird davon abgeraten weil man nicht im Voraus alle Dialoge mit allen benutzerdefinierten Schriftarten testen kann.*Heutzutage geht es wohl so, dass man alles mit der symbolischen Schriftart Microsoft Sans Serif füllt. Die wird über Windows’ internes Font Mapping zu Tahoma aufgelöst. So macht es auch Visual Studios Resource Editor, wie Helmut schon erwähnte. Nachtrag: Quatsch; ich habe meine Quelle missverstanden. Siehe weiter unten.
MS Shell Dlg 2 ist für Programme da, die für Windows 2000 bis XP ausgelegt sind**: Im Augenblick und auf westlichen Systemen wird es immer zu Tahoma. Auf Systemen exotischer Sprache wird die nächstbeste Schriftart gewählt (z.B. MS UI Gothic auf japanischen Systemen, weil Tahoma nicht alle Zeichen darstellen kann). Weil die letzten Informationen, die ich dazu finden konnte, von 2006 sind, denke ich, dass es auch heute noch die erste Wahl sein sollte.
MS Shell Dlg war für Programme da, die sowohl unter Windows 95, 98, als auch NT und 2000 liefen**: Unter Windows 95, 98, und NT wird sie zu MS Sans Serif aufgelöst; auf Windows 2000 hingegen zu Tahoma (weil das damals die neue Windows-Standardschriftart wurde). Programme, die das benutzen, sehen also sowohl unter Windows 95 und 98, als auch unter 2000 „aktuell“ aus. Von der Benutzung wird abgeraten, falls das Programm auf Windows 95 und 98 verzichtet.
GetStockObject(DEFAULT_GUI_FONT) war bereits beim Erscheinen von Windows 95 deprecated***.
* How do you know that your dialog is compatible with the metrics of an unknown font? What if the users font has metrics that result in your template generating a dialog with truncated text? – Raymond Chen Aug 28 '11 at 15:38 (http://stackoverflow.com/questions/7219 ... ialog-font)
** Overview of MS Shell DLG and FontSubsitutes (http://support.microsoft.com/kb/282187/en-us)
*** Raymond Chen: What are SYSTEM_FONT and DEFAULT_GUI_FONT? (http://blogs.msdn.com/b/oldnewthing/arc ... 36435.aspx)
Windows 7 selber ist inkohärent in benutzerdefinierten Schriftarten. Manchmal werden sie benutzt, manchmal nicht:
Falls man an die benutzerdefinierte Schriftart unbedingt rankommen will:
NONCLIENTMETRICS metrix; metrix.cbSize = sizeof metrix;
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrix, 0);
hFont = CreateFontIndirectW(&metrix.lfMessageFont);
Aber Windows macht es, wie gesagt, meist selber nicht. Es wird davon abgeraten weil man nicht im Voraus alle Dialoge mit allen benutzerdefinierten Schriftarten testen kann.*
MS Shell Dlg 2 ist für Programme da, die für Windows 2000 bis XP ausgelegt sind**: Im Augenblick und auf westlichen Systemen wird es immer zu Tahoma. Auf Systemen exotischer Sprache wird die nächstbeste Schriftart gewählt (z.B. MS UI Gothic auf japanischen Systemen, weil Tahoma nicht alle Zeichen darstellen kann). Weil die letzten Informationen, die ich dazu finden konnte, von 2006 sind, denke ich, dass es auch heute noch die erste Wahl sein sollte.
MS Shell Dlg war für Programme da, die sowohl unter Windows 95, 98, als auch NT und 2000 liefen**: Unter Windows 95, 98, und NT wird sie zu MS Sans Serif aufgelöst; auf Windows 2000 hingegen zu Tahoma (weil das damals die neue Windows-Standardschriftart wurde). Programme, die das benutzen, sehen also sowohl unter Windows 95 und 98, als auch unter 2000 „aktuell“ aus. Von der Benutzung wird abgeraten, falls das Programm auf Windows 95 und 98 verzichtet.
GetStockObject(DEFAULT_GUI_FONT) war bereits beim Erscheinen von Windows 95 deprecated***.
* How do you know that your dialog is compatible with the metrics of an unknown font? What if the users font has metrics that result in your template generating a dialog with truncated text? – Raymond Chen Aug 28 '11 at 15:38 (http://stackoverflow.com/questions/7219 ... ialog-font)
** Overview of MS Shell DLG and FontSubsitutes (http://support.microsoft.com/kb/282187/en-us)
*** Raymond Chen: What are SYSTEM_FONT and DEFAULT_GUI_FONT? (http://blogs.msdn.com/b/oldnewthing/arc ... 36435.aspx)
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Sooo; noch mehr zum Thema findet sich bei Michael Kaplan. Leider hat er alles kreuz und quer durcheinandergepostet, aber ich hoffe, dass ich alle wichtigen Dinge gefunden habe:
Es ist unmöglich, einen Dialog zu definieren, der sich von Windows 95 bis Windows 8 jeweils dem visuellen Stil anpasst. Man muss entweder für jede Shell-Generation eine eigene Version anlegen, oder ein auf dem kleinsten gemeinsamen Nenner basierendes, völlig eigenständiges Aussehen nutzen (wie z.B. Office).
Man kann mit den logischen Fonts die Symptome aber zumindest lindern (wenn man Benutzereinstellungen ignoriert):
Die Schriftarten pro Windows-Version sind:
Windows 3.1 System
Windows 95 MS Sans Serif
Windows NT 4 MS Sans Serif
Windows 98 MS Sans Serif
Windows ME MS Sans Serif
Windows 2000 Tahoma
Windows XP Tahoma
Windows Vista Segoe UI
Windows 7 Segoe UI
Windows 8 Segoe UI 2
- Is this the Über-font post? No, but it is the teaser for it! (Einleitung)
- Why the Windows Shell can't provide the ultimate font solution for everyone (or even anyone!) (unter anderem mit dem Hinweis, dass MS Shell Dlg 2 in Windows Vista / 7 / 8 nicht auf Aeros Segoe UI mappt, sondern bei XPs Tahoma bleibt; und warum man kein MS Shell Dlg 3 eingeführt hat)
- More problems with the Shell's 'ultimate font' solutions (warum die lateinischen Buchstaben in japanischen Schriften absichtlich unästhetisch aussehen)
- Neither GDI nor Uniscribe solve the ultimate font problem completely, either (darüber, dass es zumindest möglich ist, Text aller Sprachen im selben Control anzuzeigen, obwohl die geforderte Schriftart vielleicht nicht alle Zeichen anbietet)
Es ist unmöglich, einen Dialog zu definieren, der sich von Windows 95 bis Windows 8 jeweils dem visuellen Stil anpasst. Man muss entweder für jede Shell-Generation eine eigene Version anlegen, oder ein auf dem kleinsten gemeinsamen Nenner basierendes, völlig eigenständiges Aussehen nutzen (wie z.B. Office).
Man kann mit den logischen Fonts die Symptome aber zumindest lindern (wenn man Benutzereinstellungen ignoriert):
- DS_SHELLFONT mit MS Shell Dlg wählt auf Windows 95, 98, NT 4.0, ME, und 2000 jeweils die „richtige“ Schriftart.
- DS_SHELLFONT mit MS Shell Dlg 2 wählt auf Windows 2000 und XP jeweils die „richtige“ Schriftart.
- Die beiden Flags sorgen außerdem dafür, dass auf asiatischen Systemen eine Schriftart gewählt wird, die mit dem Rest der Shell konsistent ist. Ab Vista könnte das durch die verbesserte Unicode-Unterstützung bedeutungslos sein, aber das mutmaße ich jetzt bloß.
Die Schriftarten pro Windows-Version sind:
Windows 3.1 System
Windows 95 MS Sans Serif
Windows NT 4 MS Sans Serif
Windows 98 MS Sans Serif
Windows ME MS Sans Serif
Windows 2000 Tahoma
Windows XP Tahoma
Windows Vista Segoe UI
Windows 7 Segoe UI
Windows 8 Segoe UI 2
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Ich bin euch meine endgültige Lösung schuldig geblieben, darum trage ich hier nach:
Wo ich noch nicht ganz hinter gekommen bin, das ist die Übergabe von ANSI_CHARSET an den Dialog. Ob das so richtig ist, und welche Auswirkungen es auf verschiedenen Windows-Systemen auf die Schriftart hat, kann ich nicht sagen. Auf Windows 7 funktioniert aber z.B. Chinesisch trotzdem ausgezeichnet. Ich benutze ausschließlich die W- (also UTF-16-)Version der WinAPI; vielleicht hat der Zeichensatz ja darauf keine Auswirkung.
- MS Shell Dlg 2 als Dialogschriftart setzen
- DS_SHELLFONT immer setzen
- ???
- PROFIT!!!
Wo ich noch nicht ganz hinter gekommen bin, das ist die Übergabe von ANSI_CHARSET an den Dialog. Ob das so richtig ist, und welche Auswirkungen es auf verschiedenen Windows-Systemen auf die Schriftart hat, kann ich nicht sagen. Auf Windows 7 funktioniert aber z.B. Chinesisch trotzdem ausgezeichnet. Ich benutze ausschließlich die W- (also UTF-16-)Version der WinAPI; vielleicht hat der Zeichensatz ja darauf keine Auswirkung.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [WinAPI] Muss man Dialogen Schriftarten mitgeben?
Falls noch jemand zwischen Pixeln und Dialogeinheiten hin- und herkonvertieren muss und sich dabei in einem Fenster befindet, das kein Dialog ist:
- GetDialogBaseUnits() war für Windows 3.1 entworfen und liefert dementsprechend die Maße des uralt-System-Fonts
- MapDialogRect() funktioniert nur mit Dialogen
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS) ist nutzlos, weil die Textbreite Null ist
- GetTextMetrics() ist die Funktion der Wahl, aber nur für die Höhe – die Breite ist falsch
- KB 145994 erklärt, wie’s richtig geht (und man will sich lieber in den Kopf schießen, als das wirklich zu tippen) – via GetTextExtentPoint32()