No announcement yet.

Getting/Changing Font Properties?

  • Filter
  • Time
  • Show
Clear All
new posts

  • Getting/Changing Font Properties?

    I have two basic font questions.

    How can I get the properties of a control's current font?
    How can I change those properties?

    Do I have to use Font New to create a new font, then use it by applying Control Set Font?

    I know I can use WM_GetFont to get a handle on the current font. Can I use that to to simply change one or more properties of the current font?

    I'd like to be able to display the properties of a control's current font.

    I searched through the forums, expecting multiple examples but didn't find an answer. Lots of font discussions, but never quite the one I was looking for. When I don't find something I expect to see discussed frequently, it makes me wonder how other programmers solve the problem - apparently differently than I might have expected.

    I read at MSDN that a LOGFONT structure is used to hold the font properties, but I'm not familiar with accessing/changing its member values.

  • #2
    The GetTextMetrics function fills the specified buffer with the metrics for the 
    currently selected font. 
    BOOL GetTextMetrics
      HDC hdc,            // handle to device context
      LPTEXTMETRIC lptm   // pointer to text metrics structure
    hdc    Handle to the device context. 
    lptm   Pointer to the TEXTMETRIC structure that is to receive the metrics. 
    typedef struct tagTEXTMETRIC 
    {  /* tm */
        int  tmHeight;
        int  tmAscent;
        int  tmDescent;
        int  tmInternalLeading;
        int  tmExternalLeading;
        int  tmAveCharWidth;
        int  tmMaxCharWidth;
        int  tmWeight;
        BYTE tmItalic;
        BYTE tmUnderlined;
        BYTE tmStruckOut;
        BYTE tmFirstChar;
        BYTE tmLastChar;
        BYTE tmDefaultChar;
        BYTE tmBreakChar;
        BYTE tmPitchAndFamily;
        BYTE tmCharSet;
        int  tmOverhang;
        int  tmDigitizedAspectX;
        int  tmDigitizedAspectY;
    You can get a handle to a device context with the GetDC(hWnd_Control) function. Also check out the %WM_SETFONT message.
    Last edited by Fred Harris; 27 Mar 2009, 12:44 PM.


    • #3

      LOGFONT is used with CreateFontIndirect(). A related function is just simply CreateFont() which just takes piles of parameters instead of a LOGFONT type. Here is a program that uses CreateFont()...

      'Program For Using Brushes And Fonts
      #Compile Exe
      #Include ""
      Type WndEventArgs
        hIns    As Dword
        hWnd    As Dword
        lParam  As Dword
        wParam  As Dword
      End Type
      Function OnPaint(wea As WndEventArgs) As Long
        Local hDC,hBrush,hTmp,hFont As Dword
        Local lpPaint As PAINTSTRUCT
        Local strText As String
        Local rc As RECT
        hDC = BeginPaint(wea.hWnd, lpPaint)
        hBrush=CreateSolidBrush(&h000000FF)         'red brush
        hTmp=SelectObject(hDC,hBrush)               'hTmp holds original brush, red brush >>hDC
        Call GetClientRect(wea.hWnd,rc)             'get size of screen
        Call FillRect(hDC,rc,hBrush)                'fill rect (screen) with red
        Call DeleteObject(SelectObject(hdc,hTmp))   'Select(hTmp) back in hDC -- Delete return from Select(red brush) tricky!
        Call SetTextColor(hDC,&H00FFFFFF)           'Set Text Color To White
        hFont=CreateFont(80,0,0,0,%FW_BOLD,0,0,0,0,0,0,2,0,"SYSTEM_FIXED_FONT")  'Create a font
        hTmp=SelectObject(hDC,hFont)                'Select new font into DC
        Call SetBkMode(hDC,%TRANSPARENT)
        strText = "Hello, World!"
        Call TextOut(hDC,32,110,ByVal StrPtr(strText),Len(strText))
        Call DeleteObject(SelectObject(hdc,hTmp))
        Call EndPaint(wea.hWnd,lpPaint)
      End Function
      Function OnDestroy(wea As WndEventArgs) As Long
        Call PostQuitMessage(0)
      End Function
      Function WndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
        Static wea As WndEventArgs
        Select Case wMsg
          Case %WM_PAINT
            wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
            Exit Function
          Case %WM_DESTROY
            wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
            Exit Function
        End Select
        WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
      End Function
      Function WinMain(ByVal hIns As Long,ByVal hPrevIns As Long,ByVal lpCmdLn As Asciiz Ptr,ByVal iShow As Long) As Long
        Local hMainWnd As Dword
        Local winclass As WndClassEx
        Local szAppName As Asciiz*8
        Local Msg As tagMsg
        winclass.cbSize=SizeOf(winclass)              Or %CS_VREDRAW
        winclass.lpfnWndProc=CodePtr(WndProc)                  :winclass.cbClsExtra=0
        winclass.cbWndExtra=0                                  :winclass.hInstance=hIns
        winclass.hIcon=LoadIcon(%NULL,ByVal %IDI_APPLICATION)  :winclass.hCursor=LoadCursor(%NULL,ByVal %IDC_ARROW)
        winclass.hbrBackground=GetStockObject(%LTGRAY_BRUSH)   :winclass.lpszMenuName=%NULL
        Call RegisterClassEx(winclass)
        hMainWnd=CreateWindow(szAppName,"Form21",%WS_OVERLAPPEDWINDOW,210,100,500,450,0,0,hIns,ByVal 0)
        Call ShowWindow(hMainWnd,iShow)
        Call UpdateWindow(hMainWnd)
        While GetMessage(Msg,%NULL,0,0)
          Call TranslateMessage(Msg)
          Call DispatchMessage(Msg)
      End Function


      • #4
        Thanks Fred, for two quick responses.

        I'll digest what you posted and I'm sure I'll have a followup question.


        • #5
          From help on FONT NEW:
          This is the preferred method of creating and specifying fonts in PowerBASIC. Using FONT NEW, you can create a group of fonts, in advance, and switch between them easily using CONTROL SET FONT, GRAPHIC SET FONT, and XPRINT SET FONT.

          If the requested font is not available on the computer, Windows will search for a substitute font, which is similar to the attributes specified (CharSet, Font Family, etc.).
          my bold
          Until you set a different font, the control is going to have the default font as specified in the help. I would create whatever number of fonts with whatever variations that I expect to use and apply when necessary, rather than checking the control to see if the font attribute is set the way you want.

          What PB has given us here is rather luxurious in my opinion.
          I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.


          • #6
            Hi Rodney,

            Yep the tools are fine.

            The desire I had was to programmatically check one of the font properties to see what values have been assigned.

            I could, of course, store the current values (which I assign) in variables.

            But that wouldn't help with finding the default values assigned by PowerBASIC. I can't check those (other than what Help tells me).


            • #7
              You're probably going to have to assume that the control is using a system default font, ...

              According to this program, you're not going to get attributes about the font back after you set them.
              #COMPILE EXE
              #DIM ALL
              %USEMACROS = 1
              #INCLUDE "WIN32API.INC"
              #INCLUDE "COMMCTRL.INC"
              %IDC_STATUS         = 1002
              %IDC_TEXTATTRIBUTES = 1001
              %IDD_FONTATTRIBUTES =  101
              LOCAL FormX, FormY, StatusY AS LONG
              LOCAL cHandle, hDC          AS DWORD
              LOCAL tx                    AS TEXTMETRIC
              LOCAL FaceName              AS ASCIIZ * 128
                  SELECT CASE AS LONG CBMSG
                      CASE %WM_INITDIALOG
                          ' Initialization handler
                      ' use one or the other, don't matter which control you get
                          CONTROL HANDLE CB.HNDL, %IDC_TEXTATTRIBUTES TO cHandle
                          CONTROL HANDLE CB.HNDL, %IDC_STATUS TO cHandle
                          hDC = GetDC(cHandle)
                          STATUSBAR SET TEXT CB.HNDL, %IDC_STATUS, 1, 0, "hDC="& HEX$(hDC, 8)
                          GetTextMetrics hDC, tx
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmHeight = "& FORMAT$(tx.tmHeight)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmAscent = "& FORMAT$(tx.tmAscent)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmDescent = "& FORMAT$(tx.tmDescent)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmInternalLeading = "& FORMAT$(tx.tmInternalLeading)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmExternalLeading = "& FORMAT$(tx.tmExternalLeading)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmAveCharWidth = "& FORMAT$(tx.tmAveCharWidth)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmMaxCharWidth = "& FORMAT$(tx.tmMaxCharWidth)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmWeight = "& FORMAT$(tx.tmWeight)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmOverhang = "& FORMAT$(tx.tmOverhang)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmDigitizedAspectX = "& FORMAT$(tx.tmDigitizedAspectX)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmDigitizedAspectY = "& FORMAT$(tx.tmDigitizedAspectY)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmFirstChar = "& FORMAT$(tx.tmFirstChar)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmLastChar = "& FORMAT$(tx.tmLastChar)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmDefaultChar = "& FORMAT$(tx.tmDefaultChar)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmBreakChar = "& FORMAT$(tx.tmBreakChar)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmItalic = "& FORMAT$(tx.tmItalic)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmUnderlined = "& FORMAT$(tx.tmUnderlined)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmStruckOut = "& FORMAT$(tx.tmStruckOut)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmPitchAndFamily = "& FORMAT$(tx.tmPitchAndFamily)
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmCharSet = "& FORMAT$(tx.tmCharSet)
                          GetTextFace hDC, 127, FaceName
                          LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "tmFaceName = "& FaceName
                          ReleaseDC cHandle, hDC
                      CASE %WM_SIZE
                          ' Dialog has been resized
                          CONTROL GET SIZE CB.HNDL, %IDC_STATUS TO FormX, StatusY
                          DIALOG GET CLIENT CB.HNDL TO FormX, FormY
                          FormY = FormY - StatusY
                          CONTROL SET LOC CB.HNDL, %IDC_TEXTATTRIBUTES, 0, 0
                          CONTROL SET SIZE CB.HNDL, %IDC_TEXTATTRIBUTES, FormX, FormY
                  END SELECT
              END FUNCTION
              FUNCTION PBMAIN()
                  LOCAL lRslt AS LONG
                  LOCAL hDlg  AS DWORD
                  DIALOG NEW PIXELS, %HWND_DESKTOP, "Font Attributes", 261, 190, 300, 250, %WS_POPUP OR _
                      %WS_EX_RIGHTSCROLLBAR, TO hDlg
                  CONTROL ADD LISTBOX, hDlg, %IDC_TEXTATTRIBUTES, , 0, 0, 80, 85, %WS_CHILD _
                      %LBS_NOTIFY, %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                  CONTROL ADD STATUSBAR, hDlg, %IDC_STATUS, "Status", 0, 109, _
                      201, 12, %WS_CHILD OR %WS_VISIBLE, %WS_EX_TRANSPARENT OR %WS_EX_LEFT _
                  LOCAL hFont AS DWORD
                  FONT NEW "Modern", 22, 2, 0, 0, 0 TO hFont
                  CONTROL SET FONT hDlg, %IDC_TEXTATTRIBUTES, hFont
                  CONTROL SET FONT hDlg, %IDC_STATUS, hFont
                  DIALOG SHOW MODAL hDlg, CALL ShowFONTATTRIBUTESProc TO lRslt
                  FONT END hFont
                  FUNCTION = lRslt
              END FUNCTION
              Furcadia, an interesting online MMORPG in which you can create and program your own content.


              • #8
                LOCAL LF AS LOGFONT 
                GetObject hFont,  SIZEOF(LF), BYVAL VARPTR(LF)
                Read members of LF. Rejoice. Be Happy.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]


                • #9
                  :coffee: on me, didn't think about going after the logfont properties:
                  LOCAL lf                    AS LOGFONT
                  LOCAL hFont                 AS DWORD
                      SELECT CASE AS LONG CBMSG
                          CASE %WM_INITDIALOG
                              ' Initialization handler
                              CONTROL SEND CB.HNDL, %IDC_TEXTATTRIBUTES, %WM_GETFONT, 0, 0 TO hFont
                              STATUSBAR SET TEXT CB.HNDL, %IDC_STATUS, 1, 0, "hFont="& HEX$(hFont, 8)
                              GetObject hFont, SIZEOF(lf), lf
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfHeight = "& FORMAT$(lf.lfHeight)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfWidth = "& FORMAT$(lf.lfWidth)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfEscapement = "& FORMAT$(lf.lfEscapement)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfOrientation = "& FORMAT$(lf.lfOrientation)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfWeight = "& FORMAT$(lf.lfWeight)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfItalic = "& FORMAT$(lf.lfItalic)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfUnderline = "& FORMAT$(lf.lfUnderline)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfStrikeOut = "& FORMAT$(lf.lfStrikeOut)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfCharSet = "& FORMAT$(lf.lfCharSet)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfOutPrecision = "& FORMAT$(lf.lfOutPrecision)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfClipPrecision = "& FORMAT$(lf.lfClipPrecision)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfQuality = "& FORMAT$(lf.lfQuality)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfPitchAndFamily = "& FORMAT$(lf.lfPitchAndFamily)
                              LISTBOX ADD CB.HNDL, %IDC_TEXTATTRIBUTES, "lfFaceName = "& lf.lfFaceName
                          CASE %WM_SIZE
                  Replace in appropriate place in above.

                  For the interested:
                  lfHeight = -11
                  lfWidth = 0
                  lfEscapement = 0
                  lfOrientation = 0
                  lfWeight = 400
                  lfItalic = 0
                  lfUnderline = 0
                  lfStrikeOut = 0
                  lfCharSet = 0
                  lfOutPrecision = 0
                  lfClipPrecision = 0
                  lfQuality = 0
                  lfPitchAndFamily = 0
                  lfFaceName = MS Sans Serif
                  Set as default on my system.
                  Last edited by colin glenn; 27 Mar 2009, 04:56 PM.
                  Furcadia, an interesting online MMORPG in which you can create and program your own content.


                  • #10
                    >Set as default on my system

                    Be careful with the word 'default' here... if you change the font of a dialog as a whole, it changes the font of controls added thereto.

                    Not to mention, there is more than one "default" font...

                    If you want to check various types of defaults, use the GetStockObject() function to retrieve handles to...
                    • ANSI_FIXED_FONT Windows fixed-pitch (monospace) system font.
                    • ANSI_VAR_FONT Windows variable-pitch (proportional space) system font.
                    • DEVICE_DEFAULT_FONT Windows NT/2000/XP: Device-dependent font.
                    • DEFAULT_GUI_FONT Default font for user interface objects such as menus and dialog boxes. This is MS Sans Serif. Compare this with SYSTEM_FONT.
                    • OEM_FIXED_FONT Original equipment manufacturer (OEM) dependent fixed-pitch (monospace) font.
                    • SYSTEM_FONT System font. By default, the system uses the system font to draw menus, dialog box controls, and text.
                      Windows 95/98 and Windows NT: The system font is MS Sans Serif.
                      Windows 2000/XP: The system font is Tahoma
                    • SYSTEM_FIXED_FONT Fixed-pitch (monospace) system font. This stock object is provided only for compatibility with 16-bit Windows versions earlier than 3.0.

                    ... and call GetObject() as above to get the characteristics of ALL the 'default' fonts.

                    Last edited by Michael Mattias; 27 Mar 2009, 06:53 PM.
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]


                    • #11

                      Cool beans!

                      The last sentence in my post asked about the use of LOGFONT but I didn't know how to access it.

                      Now I know, and it's an easy to implement solution. Great!

                      Drinking at these forum fountains is, as they say, like drinking from a fire hose. You come in for a sip, and you go away with a belly-full of information.

                      Thanks guys!