First of all: a simple and reliable way to do this is to create a dialog, and then send WM_SETFONT (or call SetFont() ) to the dialog and each control in it. I will show you how to do this below, but first, why the two strategies that you have already tried did not work (and cannot):
Change dialog template
First, you must call CDialog::CreateIndirect() if you want to use the dialog template that you have already loaded.
But don't worry. The dialog template contains only the name of the face and the size of the point - it does not allow you to specify other LOGFONT values, such as lfQuality . If that were the case, you could simply indicate this in your resource definition and not write code at all at run time!
Interception WM_SETFONT
In theory, you could do this job. But this is not practical. Your code has several problems: first you must intercept this message for each child control so that it can do something useful: the dialog itself probably does not display the text. But, even worse, you pass the original font to the base class (which passes it to the standard window procedure, which stores it internally for later use), and then immediately destroys it - this means that the dialog (and everything else using this font, including all child controls) will try to draw the text using a dummy font, and return to the default font as a result. Finally, you create a new font attached to a temporary object ( pFont ) created and destroyed by MFC, inside the CFont object you are working with, it will be separated from the font descriptor and destroyed, skipping the descriptor that uses nothing.
Leak of abstractions: note on HFONT and CFont
HFONT is the type of handle that Windows uses to represent a font object. Like most GDIs, there are special functions for creating fonts and the DeleteObject() function for destroying them.
CFont is a lightweight wrapper class for HFONT. A CFont instance can be attached and disconnected from an existing HFONT or used to create a new one. If the CFont instance is still bound to HFONT when its deconstructor executes, it calls DeleteObject() to destroy the underlying object. Internally, MFC uses temporary instances of CFont that are attached and disconnected from HFONT when various message handlers (such as OnSetFont) are called. It is worth remembering that inside Windows, Windows knows nothing about CFont, and one HFONT can belong to 0 or more instances of CFont at any given time.
Fonts and WM_SETFONT notes
When you create a new font - regardless of whether it is completed in a CFont object - you own this font, and it is your responsibility to destroy it as soon as you finish using it. Passing it to WM_SETFONT ( CWnd::SetFont() ) does not change the owner! This is actually very useful, as it allows you to transfer the same font to multiple windows without worrying about which one will destroy it - you still own it, and therefore you can (and should) destroy it yourself (if not) windows that still use it).
Finally - how to quickly create and install a font in a dialog box and all its children
So, now you should have enough background to understand the necessary steps:
- Create a dialogue
- Create the desired font
- Pass the font in the dialog box and its children (by sending WM_SETFONT messages or by calling CWnd :: SetFont ... which itself sends the WM_SETFONT message).
- When the dialogue is destroyed, also destroy your font.
Example
// define this as a class member - class destructor then handles step four! CFont m_nonCleartypeFont; BOOL CActivationChildDialogLicenseInfo::Create(UINT nIDTemplate, CWnd* pParentWnd) { // step one: create dialog normally BOOL nResult = CActivationChildDialog::Create(nIDTemplate, pParentWnd); // step two: create custom font // relying on destructor to destroy font once we're done with it // so be careful to only create it once! if ( NULL == m_nonCleartypeFont.m_hObject ) { CFont* pOriginalFont = GetFont(); // use template font as... template! // pull information from original font LOGFONT logfont; pOriginalFont->GetLogFont(&logfont); // make font adjustments: // specify italics logfont.lfItalic = true; // and non-cleartype antialiasing logfont.lfQuality = ANTIALIASED_QUALITY; // create our font based on adjusted information m_nonCleartypeFont.CreateFontIndirect(&logfont); } // step three: set our custom font on the dialog and all children SetFont (&m_nonCleartypeFont, FALSE); // Send message to quickly set this font for all children. // See documentation for SendMessageToDescendants() // - this is actually the example given! SendMessageToDescendants ( WM_SETFONT , (WPARAM)m_nonCleartypeFont.m_hObject, MAKELONG(FALSE, 0), FALSE); return nResult; }