Announcement

Collapse
No announcement yet.

Getting/Changing Font Properties?

Collapse
X
 
  • 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
    Code:
    GetTextMetrics
    
    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
    );
     
    Parameters
    
    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;
    } TEXTMETRIC;
    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.
    Fred
    "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

    Comment


    • #3
      Logfont

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

      Code:
      'Program For Using Brushes And Fonts
      #Compile Exe
      #Include "Win32api.inc"
      
      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)
      
        OnPaint=0
      End Function
      
      Function OnDestroy(wea As WndEventArgs) As Long
        Call PostQuitMessage(0)
        OnDestroy=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
            WndProc=OnPaint(wea)
            Exit Function
          Case %WM_DESTROY
            wea.hWnd=hWnd : wea.lParam=lParam : wea.wParam=wParam
            WndProc=OnDestroy(wea)
            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
      
        szAppName="Form21"
        winclass.cbSize=SizeOf(winclass)                       :winclass.style=%CS_HREDRAW 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
        winclass.lpszClassName=VarPtr(szAppName)
        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)
        Wend
      
        WinMain=msg.wParam
      End Function
      Fred
      "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

      Comment


      • #4
        Thanks Fred, for two quick responses.

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

        Comment


        • #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.
          Rod
          I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

          Comment


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

            Comment


            • #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.
              Code:
              #COMPILE EXE
              #DIM ALL
              
              %USEMACROS = 1
              #INCLUDE "WIN32API.INC"
              #INCLUDE "COMMCTRL.INC"
              
              %IDC_STATUS         = 1002
              %IDC_TEXTATTRIBUTES = 1001
              %IDD_FONTATTRIBUTES =  101
              
              CALLBACK FUNCTION ShowFONTATTRIBUTESProc()
              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 SEND CB.HNDL, %IDC_STATUS, CB.MSG, CB.WPARAM, CB.LPARAM
                          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_BORDER OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
                      %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_CLIPSIBLINGS OR _
                      %WS_CLIPCHILDREN OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                      %DS_SETFONT, %WS_EX_APPWINDOW OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                      %WS_EX_RIGHTSCROLLBAR, TO hDlg
                  CONTROL ADD LISTBOX, hDlg, %IDC_TEXTATTRIBUTES, , 0, 0, 80, 85, %WS_CHILD _
                      OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %LBS_SORT OR _
                      %LBS_NOTIFY, %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
                      %WS_EX_RIGHTSCROLLBAR
                  CONTROL ADD STATUSBAR, hDlg, %IDC_STATUS, "Status", 0, 109, _
                      201, 12, %WS_CHILD OR %WS_VISIBLE, %WS_EX_TRANSPARENT OR %WS_EX_LEFT _
                      OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
              
                  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.

              Comment


              • #8
                Code:
                LOCAL LF AS LOGFONT 
                
                CONTROL SEND CBHNDL, %ID_CONTROL_OF_INTEREST, %WM_GETFONT, %NULL, %NULL TO hFont 
                
                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]
                http://www.talsystems.com

                Comment


                • #9
                  :coffee: on me, didn't think about going after the logfont properties:
                  Code:
                  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:
                  Code:
                  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.

                  Comment


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

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

                    Comment


                    • #11
                      Michael/Colin/Rodney/Fred,

                      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!

                      Comment

                      Working...
                      X