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...
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

Posted: Sat Sep 08, 2007 5:22 pm
by Sparkie
Srod's turn

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

)
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
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.