Page 1 of 2

Getting default messagebox font

Posted: Fri Sep 07, 2007 8:16 pm
by Seymour Clufley
Does anyone know how to do this? Extensive searching on this forum has yielded nothing. I can get the default system font, but not the messagebox font.

(I'm trying to create custom dialogue boxes, so I need to know the user's font.)

Thanks for any help,
Seymour.

Posted: Fri Sep 07, 2007 9:48 pm
by Fluid Byte

Posted: Sat Sep 08, 2007 11:08 am
by Seymour Clufley
Thanks for the link, but I already know that stuff. I have been fiddling around with this code for two days and I still can't get it to work.

Here it is:

Code: Select all

fnt.l=GetStockObject_(#DEFAULT_GUI_FONT)
If fnt
    finfo.LOGFONT
    GetObject_(fnt,SizeOf(LOGFONT),@finfo)
    fontsize=finfo\lfHeight
    fontname$=PeekS(@finfo\lfFaceName[0])
Else
    fontname$="System"
    fontsize=12
EndIf

b$="FONTNAME: "+fontname$+"    FONTSIZE: "+Str(fontsize)
MessageRequester("FONT INFO",b$,0)
a=LoadFont(#PB_Any,fontname$,fontsize)
What I'm trying to get is the font set for use in dialogue boxes. If you go to Display>Appearance>Advanced and choose MessageBox, it allows you to choose a font for dialogue boxes. According to the MSDN page you linked to, DEFAULT_GUI_FONT is the one for getting this.

The code includes a messagerequester for displaying the results of the Default_GUI_Font call and they're never correct. I get "MS Shell Dlg" for the fontname!

Posted: Sat Sep 08, 2007 1:55 pm
by netmaestro

Code: Select all

;===============================================================================
; Include/Tailbite Library Command: GetMessageBoxFont
; Author:                           netmaestro
; Date:                             September 8, 2007
; Target OS:                        Microsoft Windows All
; Target Compiler:                  PureBasic 4.xx and later
; License:                          Free, unrestricted, credit appreciated
;                                   but not required
;===============================================================================

Global hook, *fi.LOGFONT 

Procedure CbtProc(nCode, wParam, lParam) 

  Select nCode 
    
    Case #HCBT_CREATEWND 
        
      hWnd = wParam 
      *pcbt.CBT_CREATEWND = lParam 
      *pcs.CREATESTRUCT = *pcbt\lpcs 
      If *pcs\lpszClass = 32770    
        *pcs\x = -2 * *pcs\cx ; if it's a dialog box, move it off the screen
      EndIf 
          
    Case #HCBT_ACTIVATE 
        
      hwnd = wParam 
      control = GetDlgItem_(hwnd, $FFFF) 
      font = SendMessage_(control, #WM_GETFONT, 0,0) 
      GetObject_(font,SizeOf(LOGFONT),*fi)
      SendMessage_(hwnd, #WM_CLOSE,0, 0) ; we examined it, now let's kill it

  EndSelect 

  ProcedureReturn CallNextHookEx_(hook, nCode, wParam, lParam) 

 EndProcedure 

ProcedureDLL GetMessageBoxFont(*finfo.LOGFONT)
  *fi = *finfo
  hook = SetWindowsHookEx_(#WH_CBT, @CbtProc(), #Null, GetCurrentThreadId_()) 
  MessageRequester("Title","Message",$C0) ; this won't make a sound and you won't see it 
  UnhookWindowsHookEx_(hook) 
EndProcedure
Usage: GetMessageBoxFont(MyVar.LOGFONT) and the variable MyVar may be examined.

Posted: Sat Sep 08, 2007 4:49 pm
by netmaestro
Here is another solution, which reads the LOGFONT structure for the MessageBox font from the registry:

Code: Select all

ProcedureDLL ReadBinaryKey(OpenKey.l, SubKey$, Valuename$) 
  *regdata = AllocateMemory(1024) 
  hKey = 0 
  Datasize = 1024 
  KeyType = #REG_BINARY 
  Result=0 
  If RegOpenKeyEx_(OpenKey, SubKey$, 0, #KEY_READ, @hKey) = 0 
    If RegQueryValueEx_(hkey, valuename$, 0, @keytype,  *regdata, @Datasize)  = 0 
      ReAllocateMemory(*regdata, Datasize) 
      Result = 1 
    EndIf 
    RegCloseKey_(hKey) 
  EndIf 
  If Result 
    ProcedureReturn *regdata 
  Else 
    FreeMemory(*regdata) 
    ProcedureReturn 0 
  EndIf 
EndProcedure 

*fi.LOGFONT = ReadBinaryKey(#HKEY_CURRENT_USER, "Control Panel\Desktop\WindowMetrics", "MessageFont") 

If *fi 
  hdc = GetWindowDC_(#Null)
  logPixSY = GetDeviceCaps_(hdc, #LOGPIXELSY) 
  ReleaseDC_(#Null, hdc)
  FontSize.f = -(*fi\lfHeight * 72) / logPixSY 
  fontname.s = Space(16) 
  
  CompilerIf #PB_Compiler_Unicode 
    fontname = PeekS(@*fi\lfFacename) 
  CompilerElse 
    namelength = MemorySize(*fi)-OffsetOf(LOGFONT\lfFacename) 
    WideCharToMultiByte_(#CP_ACP, 0, @*fi\lfFacename, namelength, @fontname, namelength/2, 0, 0); 
  CompilerEndIf 
  
  Debug fontname 
  Debug Str(fontsize)
EndIf 
I don't think I can come up with a third way as I don't believe any stock objects or SystemParametersInfo calls will do it. Hopefully one of these will suit your needs, personally I prefer the first one because it's actually creating a message box and looking at the font, which should be safer than reading registry keys which could vary by system.

Posted: Sat Sep 08, 2007 5:16 pm
by Sparkie
Netmaestro wrote:I don't think I can come up with a third way.
Sure you can... :wink:

Code: Select all

ncm.NONCLIENTMETRICS\cbSize = SizeOf(NONCLIENTMETRICS)
SystemParametersInfo_(#SPI_GETNONCLIENTMETRICS, SizeOf(ncm), @ncm, 0) 
msgFont$ = PeekS(@ncm\lfMessageFont\lfFaceName)
hdc = CreateDC_(@"DISPLAY", 0, 0, 0)
logPixSY = GetDeviceCaps_(hdc, #LOGPIXELSY) 
DeleteDC_(hdc)
msgFontSize.f = -(ncm\lfMessageFont\lfHeight * 72) / logPixSY
MessageRequester("Message Box Font Info:", "FontName: " + msgFont$ + #crlf$ + "FontSize: " + Str(msgFontSize))
**Edited font size calculation

Posted: Sat Sep 08, 2007 5:19 pm
by netmaestro
Hehe, I'd satisfied myself that nothing in SystemParametersInfo would do. Very good!

Now come up with a fourth way :twisted: :twisted: :twisted:

Posted: Sat Sep 08, 2007 5:22 pm
by Sparkie
netmaestro wrote:Now come up with a fourth way :twisted: :twisted: :twisted:
Srod's turn :P

Posted: Sat Sep 08, 2007 5:26 pm
by Sparkie
By the way, good find on solution#2 Netmeastro. My search of the registry turned up zilch...squat...nada. :(

Posted: Sat Sep 08, 2007 5:41 pm
by netmaestro
Thx, of the three solutions if I were writing software needing this I'd choose the Sparkie version as it's the best one. I looked at SystemParametersInfo first and when I didn't find anything that looked suitable I went hacking. (To be truthful I don't need much excuse to go hacking :D )

Posted: Sat Sep 08, 2007 6:20 pm
by Derek
I get Tahoma with both pieces of code but with Sparkies I get 9 point and with Netmaestro's second piece of code I get 11 point. Something wrong somewhere.

Setting my messageboxfont to 20 I get 21 from Sparkie and 27 from Netmaestro.

Posted: Sat Sep 08, 2007 6:35 pm
by Sparkie
Try my code once more Derek. I made a slight change in the font size calculation.

Posted: Sat Sep 08, 2007 6:37 pm
by Derek
It's spot on now. :)

Posted: Sat Sep 08, 2007 6:42 pm
by Sparkie
8)

Posted: Sat Sep 08, 2007 6:54 pm
by netmaestro
I adjusted mine to reflect the point size also so it should return the same as Sparkie's.