Jason Mills
Jason Mills

Reputation: 615

win32 - Using the default button font in a button

I'm creating a small WinAPI application in C++. I am trying to create a button on my form by using the code:

HWND hwndButton = CreateWindow(
    TEXT("BUTTON"),   
    TEXT("Click Here"),       
    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,  // Styles 
    10,         
    10,         
    100,        
    30,        
    hwnd,     
    NULL,       
    (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
    NULL);     

This code is based off of an MSDN sample. My issue is that it uses a bold font on the button like this:

enter image description here

When I want to use the standard font like this:

enter image description here

I already have the preprocessor directive at the top of my file to enable visual styles.

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

What steps should I take to use the standard system wide font?

Thanks

Upvotes: 4

Views: 5831

Answers (4)

Govind Parmar
Govind Parmar

Reputation: 21532

A convenient way of doing this without calling SendMessage on every single child window manually is to use the EnumChildWindows function with the following callback function -

  1. Create the callback function EnumChildProc:

     BOOL CALLBACK EnumChildProc(
         HWND hWnd,
         LPARAM lParam
     )
     {
         HFONT hfDefault = *(HFONT *) lParam;
         SendMessageW(hWnd, WM_SETFONT, (WPARAM) hfDefault, MAKELPARAM(TRUE, 0));
         return TRUE;
     }
    
  2. At the start of your (w)WinMain function, add the code:

     NONCLIENTMETRICSW ncm;
     HFONT hfDefault;
    
     ZeroMemory(&ncm, sizeof(NONCLIENTMETRICSW));
     ncm.cbSize = sizeof(NONCLIENTMETRICSW);
    
     SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, FALSE);
     hfDefault = CreateFontIndirectW(&ncm.lfMessageFont);
    

    Then, after the ShowWindow call, add these lines:

     EnumChildWindows(hWnd, EnumChildProc, (LPARAM)&hfDefault);
     DeleteObject(hfDefault);
    

Upvotes: 2

Mark Ingram
Mark Ingram

Reputation: 73605

GetStockObject isn't the recommended way of retrieving the GUI font (it doesn't take themes into account, and different fonts can be chosen for buttons, menus, etc). Instead you should use SystemParametersInfo (see Remarks section of GetStockObject).

It is not recommended that you employ this method to obtain the current font used by dialogs and windows. Instead, use the SystemParametersInfo function with the SPI_GETNONCLIENTMETRICS parameter to retrieve the current font. SystemParametersInfo will take into account the current theme and provides font information for captions, menus, and message dialogs.

NONCLIENTMETRICS metrics = {};
metrics.cbSize = sizeof(metrics);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);

HFONT guiFont = CreateFontIndirect(&metrics.lfCaptionFont);

// When you're done with the font, don't forget to call
DeleteObject(guiFont);

Upvotes: 8

Victor
Victor

Reputation: 14583

The default GUI font is stored in DEFAULT_GUI_FONT, and can be retrieved via

GetStockObject(DEFAULT_GUI_FONT);

To set the font of the button you can use:

HWND yourButton; // use CreateWindow or anything else to get this
SendMessage(yourButton, WM_SETFONT, (LPARAM)GetStockObject(DEFAULT_GUI_FONT), true);

Upvotes: 1

bunglehead
bunglehead

Reputation: 1179

There's no such thing as default system wide font for controls, initially you get a control created with "System" font, that's what you see on first picture. When button is created as part of a dialog, it uses a font from dialog template, so using something like "MS Shell Dlg" with appropriate size + WM_SETFONT on a button should give you the same result as on picture 2. Note that there's no physical MS Shell Dlg font on a system, it's mapped to particular font according to registry settings.

Common control manifest has nothing to do with this, behavior has not changed with comctl32 version 6.

Upvotes: 2

Related Questions