views:

1452

answers:

3

I'm creating window using pure Win32 API (RegisterClass and CreateWindow functions). How can I specify a font for the window instead of system defined one?

+2  A: 

In case you superclass a standard common control that already has its own font handle, use this approach: Just create a font using CreateFont oder CreateFontIndirect and set it using WM_SETFONT message (in MFC and ATL there would be a corresponding SetFont function). When the font is no longer needed, destroy the font using DeleteObject. Be sure to not destroy the window's previously set font.

In case you're writing a custom control that draws itself, just create a new font object using CreateFont or CreateFontIndirect and store it in your class somewhere. If you want to support third-party users, handle WM_SETFONT and WM_GETFONT to let the user set another font. When painting, use the current font object stored in your class.

vividos
The window default font cannot be ::DeleteObject-ed. If, however, a child window gets it font set by its parent and that font is shared among windows, then it's of course the parent's responsibility to clean it up.
Johann Gerell
WM_SETFONT is only handled by standard/common controls. If Andrei is creating a brand new class (he did mention RegisterClass), he has to follow Matthew Xavier's guidelines.
efotinis
Thanks, I updated the answer accordingly. Thanks Matthew Xavier, your answer is right, too.
vividos
A: 

As vividos said just use CreateFont()/CreateFontIndirect:

HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, 
   OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, 
   DEFAULT_PITCH | FF_DONTCARE, TEXT("Tahoma"));

And then set this font for your window/control with the WM_SETFONT message:

SendMessage(window, WM_SETFONT, hFont, TRUE);
Bob Jones
+2  A: 

When you create your own window class, you are responsible for managing the font yourself. This task will have four parts:

  1. When the window is created (i.e. when you handle WM_CREATE), use CreateFont() or CreateFontIndirect() to obtain an HFONT for the font you want to use in the window. You will need to store this HFONT along with the other data you keep for each instance of the window class. You may choose to have your window class handle WM_GETFONT and WM_SETFONT as well, but it is generally not required for top-level windows (if you are creating a control window class, you will want to handle WM_SETFONT, since the dialog manager sends that message).
  2. If your window has any child windows that contain text, send each of them a WM_SETFONT message whenever your window's font changes. All of the common Windows controls handle WM_SETFONT.
  3. When you draw the contents of your window (typically in response to a WM_PAINT message), select your HFONT into the device context with the SelectObject() function before drawing text (or using text functions such as or GetTextMetrics()).
  4. When the window is destroyed (i.e. when you handle WM_DESTROY), use DeleteObject() to release the font you created in step 1. Note that if you choose to handle WM_SETFONT in your window, do not delete a font object you receive in your WM_SETFONT handler, as the code that sent the message expects to retain ownership of that handle.
Matthew Xavier
Nice. I couldn't have written it better :)
efotinis