Correctly loading the Windows system font for use in Dialog

Just starting out? Need help? Post your questions and find answers here.
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Correctly loading the Windows system font for use in Dialog

Post by Andre »

I have an application, which should use different fonts and font sizes. That's why I need to do several calls to LoadFont() for loading the required fonts for later use.

This way I want to recognize the Windows system font (currently used by the user on his desktop) and use this setting as reference/base for loading the same font in different (larger/smaller) sizes.

For testing purposes I've combined a small code for receiving the Windows system font (giving on my Win8.1 "Segoe UI" in sizes 16, 12, 12 if I output all values of the WinAPI functions), thanksfully taken from the posting of 'rashad' here: http://www.purebasic.fr/english/viewtop ... nt#p339231, with the first example code in the PB manual at the OpenXMLDialog() function.

My problem is, that using the values of this WinAPI functions the received font heights are much higher, causing a much larger display of my created Dialog window, as it should be. To see the effect, just commend the 'SetGadgetFont(...)' line in the test code.

Anyone knows what I must exactly do, to get the correct Windows font sizes I need to use for my own Dialogs/GUI's?

Btw. according to the MSDN article about 'Fonts' (see: https://msdn.microsoft.com/en-us/library/dn742483.aspx) I should use a WinAPI function GetThemeFont(...) !? In the 'Guidelines' chapter there is described "Segoe UI, 9 pixel" as the setting for 'standard text'... => now the question is: how to get this data from the system (as the user can have set another font / size on his Windows)??

Beside this: Is there any (cross-platform, for Windows+MacOS) way to adjust the Menu and Requester fonts, so that they also use the system font settings? (see the WinAPI function or the MSDN article, there are several possible font sizes... which can also be received)

Code: Select all

; Code for receiving the Windows system font (posting by 'rashad') taken from:
;   http://www.purebasic.fr/english/viewtopic.php?f=13&t=44341&p=339231&hilit=systemfont#p339231
;
; More informations about the different Windows system fonts can be found in this MSDN article:
;   https://msdn.microsoft.com/en-us/library/dn742483.aspx

spinfo.NONCLIENTMETRICS
spinfo\cbSize = SizeOf(spinfo)
SystemParametersInfo_(#SPI_GETNONCLIENTMETRICS, 0, @spinfo, 0)

Font$ = PeekS(@spinfo\lfCaptionFont\lfFaceName[0])
;Debug PeekS(@spinfo\lfSMCaptionFont\lfFaceName[0])
;Debug PeekS(@spinfo\lfMenuFont\lfFaceName[0])
;Debug PeekS(@spinfo\lfMessageFont\lfFaceName[0])
;FontHeight = - PeekL(@spinfo\lfCaptionFont\lfHeight) - 3
;FontHeight = - PeekL(@spinfo\lfMenuFont\lfHeight) - 3
FontHeight = - PeekL(@spinfo\lfMessageFont\lfHeight) - 3
LoadFont(0, Font$, FontHeight)
SetGadgetFont(#PB_Default, FontID(0))    ; <====== comment this and you will see a much smaller font used in the following Dialog!

CompilerIf #PB_Compiler_Unicode
  #XmlEncoding = #PB_UTF8
CompilerElse 
  #XmlEncoding = #PB_Ascii
CompilerEndIf

#Dialog = 0
#Xml = 0

XML$ = "<window id='#PB_Any' name='test' text='test' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
       "  <panel>" +
       "    <tab text='First tab'>" +
       "      <vbox expand='item:2'>" +
       "        <hbox>" +
       "          <button text='button 1'/>" +
       "          <checkbox text='checkbox 1'/>" +
       "          <button text='button 2'/>" +
       "        </hbox>" +
       "        <editor text='content' height='150'/>" +
       "      </vbox>" +
       "    </tab>" +
       "    <tab text='Second tab'>" +
       "    </tab>" +
       "  </panel>" +
       "</window>"

If CatchXML(#Xml, @XML$, StringByteLength(XML$), 0, #XmlEncoding) And XMLStatus(#Xml) = #PB_XML_Success
  
  If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow 
    
  Else  
    Debug "Dialog error: " + DialogError(#Dialog)
  EndIf
Else
  Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
EndIf
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4951
Joined: Sun Apr 12, 2009 6:27 am

Re: Correctly loading the Windows system font for use in Dia

Post by RASHAD »

Hi Andre
Try

Code: Select all

; Code for receiving the Windows system font (posting by 'rashad') taken from:
;   http://www.purebasic.fr/english/viewtopic.php?f=13&t=44341&p=339231&hilit=systemfont#p339231
;
; More informations about the different Windows system fonts can be found in this MSDN article:
;   https://msdn.microsoft.com/en-us/library/dn742483.aspx

#TMT_CAPTIONFONT = 801
#TMT_SMALLCAPTIONFONT = 802
#TMT_MENUFONT = 803
#TMT_STATUSFONT = 804
#TMT_MSGBOXFONT = 805
#TMT_ICONTITLEFONT = 806

Import "Uxtheme.lib"
    OpenThemeData(Window.i, Body.p-unicode)
    GetThemeSysFont(hTheme,iConst,pStructure)
    CloseThemeData(hTheme) 
EndImport

hTheme = OpenThemeData(0, "Window")
GetThemeSysFont(hTheme,#TMT_MSGBOXFONT,lf.LOGFONT)
fntName$ =  PeekS(@lf\lfFaceName, 32, #PB_Unicode)
hDC = GetDC_(0)
fntHeight = Round(Abs(lf\lfheight) * 72 / GetDeviceCaps_(hDC, #LOGPIXELSY), #PB_Round_Nearest)
ReleaseDC_(0, hDC)
CloseThemeData(htheme)
LoadFont(0, fntName$, fntHeight)
SetGadgetFont(#PB_Default, FontID(0))    ; <====== comment this and you will see a much smaller font used in the following Dialog!
Egypt my love
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: Correctly loading the Windows system font for use in Dia

Post by Andre »

Thank you very much, RASHAD! :D

Your code example returns on my system (Win8.1, original settings with 125% DPI) the following font:
Segoe UI / 9
This should be the right (standard) font to use for creating my own GUI / Dialogs.

According to the MSDN article mentioned above, with it's included "table with sizes / styles" for different font uses (standard, headlines, menu, statusbar, etc.): Is there a way to get this font sizes too? Or do I need to do some simple size calculations, based on the standard font size? (e.g. a headline is always 5 pixel higher than standard font height, or similar...)
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2139
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: Correctly loading the Windows system font for use in Dia

Post by Andre »

Sorry, after reading the new example code a second and a third time I correctly recognized the included font constants and can answer my question myself.... :shock: :wink: :mrgreen:
Based on their use I created the following slightly modified code:

Code: Select all

; Code for receiving the Windows system font (posting by 'rashad') taken from:
;   http://www.purebasic.fr/english/viewtopic.php?f=13&t=64682
;
; More informations about the different Windows system fonts can be found in this MSDN article:
;   https://msdn.microsoft.com/en-us/library/dn742483.aspx

Enumeration 1
  #Font_CaptionFont
  #Font_SmallCaptionFont
  #Font_MenuFont
  #Font_StatusFont
  #Font_MsgBoxFont
  #Font_IconTitleFont
EndEnumeration

Structure fontdetails
  Name$
  Size.i
EndStructure
Dim Fonts.fontdetails(#Font_IconTitleFont)

#TMT_CAPTIONFONT = 801
#TMT_SMALLCAPTIONFONT = 802
#TMT_MENUFONT = 803
#TMT_STATUSFONT = 804
#TMT_MSGBOXFONT = 805
#TMT_ICONTITLEFONT = 806

Import "Uxtheme.lib"
    OpenThemeData(Window.i, Body.p-unicode)
    GetThemeSysFont(hTheme,iConst,pStructure)
    CloseThemeData(hTheme)
EndImport

hTheme = OpenThemeData(0, "Window")

For a = 1 To #Font_IconTitleFont
  GetThemeSysFont(hTheme, 800+a , lf.LOGFONT)     ; instead of the fixed font constants #TMT_MSGBOXFONT etc. we use an incrementing variable
  fntName$ =  PeekS(@lf\lfFaceName, 32, #PB_Unicode)
  hDC = GetDC_(0)
  fntHeight = Round(Abs(lf\lfheight) * 72 / GetDeviceCaps_(hDC, #LOGPIXELSY), #PB_Round_Nearest)
  ReleaseDC_(0, hDC)
  
  ; Debug output of the currently selected font:
  Debug fntName$ + " / " + fntHeight
  
  ; Storing the font information in the array for later use:
  Fonts(a)\Name$ = fntName$
  Fonts(a)\Size  = fntHeight
Next

CloseThemeData(htheme)


; And here the font we want to use:
LoadFont(0, Fonts(#Font_MsgBoxFont)\Name$, Fonts(#Font_MsgBoxFont)\Size)
SetGadgetFont(#PB_Default, FontID(0)) 
The output for the 6 different font types on my system is:
Segoe UI / 11
Segoe UI / 11
Segoe UI / 9
Segoe UI / 9
Segoe UI / 9
Segoe UI / 9
Any further debug outputs for comparing (e.g. of more differences regarding type/size of used Windows fonts) are welcome!

Can anyone say, which font sizes should be used for own programs and which ones can be ignored?

Thanks for any further help! :D
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
Post Reply