Jump to content

Read font settings of a GUI Control


TimRude
 Share

Recommended Posts

I want to see if I can read the font settings of a GUI control, so I tried this:

#include <APIConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIDiag.au3>
#include <StructureConstants.au3>

$hGUI = GUICreate("Sample GUI", 400, 300, 1200)
GUISetFont(18, 400, 0, "Tahoma")
Local $idLabel = GUICtrlCreateLabel("Sample Text", 10, 10)
Local $hLabel = GUICtrlGetHandle($idLabel)
GUISetState(@SW_SHOW, $hGUI)
WinWaitActive($hGUI)

Local $hDC = _WinAPI_GetDC($hLabel)
Local $tTEXTMETRIC = _WinAPI_GetTextMetrics($hDC)
Local $iLPY = _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSY) ; get number of pixels per logical inch
Local $iSize = Abs(((1 * DllStructGetData($tTEXTMETRIC, "tmHeight")) * 72 / $iLPY)) ; calculate point size
Local $sFontName = _WinAPI_GetTextFace($hDC)
ConsoleWrite("_WinAPI_GetTextFace returns: " & $sFontName &@TAB & "Point Size: " & $iSize & @CRLF)
_WinAPI_DisplayStruct($tTEXTMETRIC, $tagTEXTMETRIC)
_WinAPI_ReleaseDC($hLabel, $hDC)

Essentially, it creates a label control on a GUI with a specific font name and size. Then it tries to examine the DC of the label to figure out what that font name and size is.

But no matter what I set the label's font to (by using GUISetFont and letting the label inherit the setting from the GUI), it always returns System 12pt. The values in the TEXTMETRIC structure never change, and the returned font name from the _WinAPI_GetTextFace function never changes.

What am I missing or not understanding here?

image.thumb.png.8544196532ca4b192ea82758e5302e85.png

Link to comment
Share on other sites

I did some searching and found this, and looks like that it works: 

 

 

#include <APIConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIDiag.au3>
#include <StructureConstants.au3>

$hGUI = GUICreate("Sample GUI", 400, 300, 1200)
GUISetFont(48, 400, 0, "Tahoma")
Local $idLabel = GUICtrlCreateLabel("Sample Text", 10, 10)
Local $hLabel = GUICtrlGetHandle($idLabel)
GUISetState(@SW_SHOW, $hGUI)
WinWaitActive($hGUI)

$aFont = GUICtrlGetFont($idLabel)
_ArrayDisplay($aFont)

#cs

[0] - Size
[1] - Weight
[2] - Attribute
[3] - Name
[4] - Quality

#ce

Func GUICtrlGetFont($CtrlID)
    Local $hWnd = GUICtrlGetHandle($CtrlID)

    If Not $hWnd Then
        Return 0
    EndIf

    Local $Ret, $hDC, $hFont, $tFont
    Local $aFont = 0

    $hDC = _WinAPI_GetDC($hWnd)
    $hFont = _SendMessage($hWnd, $WM_GETFONT)
    $tFont = DllStructCreate($tagLOGFONT)
    $Ret = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFont, 'int', DllStructGetSize($tFont), 'ptr', DllStructGetPtr($tFont))
    If (Not @error) And ($Ret[0]) Then
        Dim $aFont[5] = [0]
        $aFont[0] = -Round(DllStructGetData($tFont, 'Height') / _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSY) * 72, 1)
        $aFont[1] = DllStructGetData($tFont, 'Weight')
        $aFont[2] = BitOR(2 * (DllStructGetData($tFont, 'Italic') <> 0), 4 * (DllStructGetData($tFont, 'Underline') <> 0), 8 * (DllStructGetData($tFont, 'Strikeout') <> 0))
        $aFont[3] = DllStructGetData($tFont, 'FaceName')
        $aFont[4] = DllStructGetData($tFont, 'Quality')
    EndIf
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return $aFont
EndFunc   ;==>GUICtrlGetFont

 

I haven't really looked into why it works and yours doesn't (for me), but it did return the font and size correctly when I tested it with your GUI code. Try it out, see if that works for you, and what Yashied has done differently.

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

Thanks @mistersquirrle, that was the pointer I needed. This works nicely.

#include <APIConstants.au3>
#include <WinAPIGdiDC.au3>
#include <SendMessage.au3>
#include <Array.au3> ; only needed for demo

$hGUI = GUICreate("Sample GUI", 400, 300)
GUISetFont(48, 400, 0, "Tahoma")
GUICtrlCreateLabel("Sample Text", 10, 10)

; it works even before the GUI is visible, and with -1 as control ID

Local $aFont = _GUICtrlGetFont(-1)
_ArrayDisplay($aFont, "Font Info")

GUISetState(@SW_SHOW, $hGUI)

While GUIGetMsg() <> $GUI_EVENT_CLOSE
WEnd

Func _GUICtrlGetFont($id_or_hWnd) ; accepts either Control ID or hWnd

    ; If successful, returns 1D array consisting of:
    ;
    ;   [0] - Size
    ;   [1] - Weight
    ;   [2] - Attribute
    ;   [3] - Name
    ;   [4] - Quality
    ;
    ; If unsuccessful, returns 0 with @error set to non-zero

    If IsHWnd($id_or_hWnd) Then
        Local $hWnd = $id_or_hWnd
    Else
        Local $hWnd = GUICtrlGetHandle($id_or_hWnd)
    EndIf
    If $hWnd = 0 Then Return SetError(1, 1, 0)
    Local $hDC = _WinAPI_GetDC($hWnd)
    Local $iLPY = _WinAPI_GetDeviceCaps($hDC, $LOGPIXELSY)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Local $tFont = DllStructCreate($tagLOGFONT)
    Local $hFont = _SendMessage($hWnd, $WM_GETFONT)
    If @error Then Return SetError(@error, 2, 0)
    Local $iRet = _WinAPI_GetObject($hFont, DllStructGetSize($tFont), $tFont)
    If $iRet <> 0 Then
        Local $aFont[5]
        $aFont[0] = Abs(Round(DllStructGetData($tFont, 'Height') / $iLPY * 72, 1))
        $aFont[1] = DllStructGetData($tFont, 'Weight')
        $aFont[2] = BitOR( _
                ((DllStructGetData($tFont, "Italic")) ? $GUI_FONTITALIC : 0), _
                ((DllStructGetData($tFont, "Underline")) ? $GUI_FONTUNDER : 0), _
                ((DllStructGetData($tFont, "Strikeout")) ? $GUI_FONTSTRIKE : 0))
        $aFont[3] = DllStructGetData($tFont, 'FaceName')
        $aFont[4] = DllStructGetData($tFont, 'Quality')
        Return $aFont
    Else
        Return SetError(1, 3, 0)
    EndIf

EndFunc   ;==>_GUICtrlGetFont

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...