f



Matching Custom Control's Font to Dialog Box's.

Hi Experts:

    I'm using the resource editor to create a dialog box with
some custom controls.

    The dialog box has a nice font by default, the resource
editor identifies this as "MS Sans Serif".

    It looks much nicer than the "System" font that is the
default in my custom control.

    So in my dialogproc's WM_INITDIALOG trap I run the
following:

           hdc = GetDC(hdlg);
           font_name_char_count = GetTextFace(hdc, 100, NULL);
           font_name = new TCHAR[font_name_char_count];
           GetTextFace(hdc, font_name_char_count , font_name);
           ReleaseDC(hdlg, hdc);

    Stepping through this with the debugger, font_name_char_count
is set to 0.  MSDN's GetTextFace documentation states:

       lpFaceName
          [out] Pointer to the buffer that receives the typeface
          name. If this parameter is NULL, the function returns
          the number of characters in the name, including the
          terminating null character.

    I'm running this under WIN 98, the GetLastError() function
returns 87, "The parameter is incorrect"

    So... Why doesn't GetTextFace(hdc, 100, NULL) return some
value greater than zero that is the size of the font's name.

    Next, I try the following code:

           TCHAR font_name_buffer[1000];
           font_name_char_count = GetTextFace(hdc, 1000 ,
                                              font_name_buffer);

Here the font name char count is 6, and the font name is
"System".  Now I know what the "System" font looks like,
it's what comes up by default in my custom controls.  It's
not the nice looking font that is used by default in the
dialog boxes.

    I am at a breakpoint in dialogproc, and hdc is the handle
to the device config for this for the dialog box's handle,
hdlg.

    So, why aren't I seeing the name of the dialog box's
font in the name buffer?

                                                    Thanks
                                                    Larry

0
Larry
12/27/2003 8:43:14 AM
comp.os.programmer.win32 14523 articles. 0 followers. Post Follow

7 Replies
443 Views

Similar Articles

[PageSpeed] 6

Larry Lindstrom wrote:
> Hi Experts:
> 
>    I'm using the resource editor to create a dialog box with
> some custom controls.
> 
>    The dialog box has a nice font by default, the resource
> editor identifies this as "MS Sans Serif".
> 
>    It looks much nicer than the "System" font that is the
> default in my custom control.
> 
>    So in my dialogproc's WM_INITDIALOG trap I run the
> following:
> 
>           hdc = GetDC(hdlg);
>           font_name_char_count = GetTextFace(hdc, 100, NULL);
>           font_name = new TCHAR[font_name_char_count];
>           GetTextFace(hdc, font_name_char_count , font_name);
>           ReleaseDC(hdlg, hdc);
> 
>    Stepping through this with the debugger, font_name_char_count
> is set to 0.  MSDN's GetTextFace documentation states:
> 
>       lpFaceName
>          [out] Pointer to the buffer that receives the typeface
>          name. If this parameter is NULL, the function returns
>          the number of characters in the name, including the
>          terminating null character.
> 
>    I'm running this under WIN 98, the GetLastError() function
> returns 87, "The parameter is incorrect"
> 
>    So... Why doesn't GetTextFace(hdc, 100, NULL) return some
> value greater than zero that is the size of the font's name.
> 
>    Next, I try the following code:
> 
>           TCHAR font_name_buffer[1000];
>           font_name_char_count = GetTextFace(hdc, 1000 ,
>                                              font_name_buffer);
> 
> Here the font name char count is 6, and the font name is
> "System".  Now I know what the "System" font looks like,
> it's what comes up by default in my custom controls.  It's
> not the nice looking font that is used by default in the
> dialog boxes.
> 
>    I am at a breakpoint in dialogproc, and hdc is the handle
> to the device config for this for the dialog box's handle,
> hdlg.
> 
>    So, why aren't I seeing the name of the dialog box's
> font in the name buffer?
> 
>                                                    Thanks
>                                                    Larry
> 
I don't know why your call to GetTextFace() does not work but the good 
news is that that is the wrong approach to the problem and you don't 
need to make it work.

The font for the dialog (or any window) is not stored in the DC. It must 
be selected into the DC each time you plan to use it and the original 
font selected back in when you're finished.

Because of this, GetDC() followed by GetTextFace() is always going to 
give you "System" and that is not what you want.

Here's the right way to solve your problem:

When a dialog is created, it creates a font as specified in the dialog 
template: MS Sans Serif, 8 pt, or whatever. It saves the handle to this 
font in its private window data. Every time it calls GetDC it selects 
this handle into the DC and, of course, selects the original handle back 
before calling ReleaseDC().

It also passes this handle on to each control as the control is created, 
using the WM_SETFONT message. All standard and common control supplied 
by Microsoft save the font handle and select it for use just like the 
dialog does.

It's up to you to make this work in your own custom control.
1) Handle the WM_SETFONT message and save the font handle somewhere. 
(Saving it in your window private data is a good idea if you plan to 
have more than one instance of the control open at a time.)
2) After any call to GetDC() in your control you must get the font 
handle and SelectObject() to make the DC use it.
3) Before calling ReleaseDC() you should call SelectObject() to put the 
original font handle back.

Norm

0
Norman
12/27/2003 3:41:16 PM
>     Next, I try the following code:
> 
>            TCHAR font_name_buffer[1000];
>            font_name_char_count = GetTextFace(hdc, 1000 ,
>                                               font_name_buffer);
I don't know why GetTextFace(hdc, 100, NULL) does not work.

>     So, why aren't I seeing the name of the dialog box's
> font in the name buffer?


You're probably getting "System" instead of the "MS Sans Serif" that
you expect because the dialog box font *is* System. "MS Sans Serif" is
the font used by the dialog box *controls*.
0
johnbrown105
12/27/2003 4:42:27 PM
Norman Bullen wrote:
> Larry Lindstrom wrote:
> 
>> Hi Experts:
>>
>>    I'm using the resource editor to create a dialog box with
>> some custom controls.
>>
>>    The dialog box has a nice font by default, the resource
>> editor identifies this as "MS Sans Serif".
>>
>>    It looks much nicer than the "System" font that is the
>> default in my custom control.
>>
>>    So in my dialogproc's WM_INITDIALOG trap I run the
>> following:
>>
>>           hdc = GetDC(hdlg);
>>           font_name_char_count = GetTextFace(hdc, 100, NULL);
>>           font_name = new TCHAR[font_name_char_count];
>>           GetTextFace(hdc, font_name_char_count , font_name);
>>           ReleaseDC(hdlg, hdc);
>>
>>    Stepping through this with the debugger, font_name_char_count
>> is set to 0.  MSDN's GetTextFace documentation states:
>>
>>       lpFaceName
>>          [out] Pointer to the buffer that receives the typeface
>>          name. If this parameter is NULL, the function returns
>>          the number of characters in the name, including the
>>          terminating null character.
>>
>>    I'm running this under WIN 98, the GetLastError() function
>> returns 87, "The parameter is incorrect"
>>
>>    So... Why doesn't GetTextFace(hdc, 100, NULL) return some
>> value greater than zero that is the size of the font's name.
>>
>>    Next, I try the following code:
>>
>>           TCHAR font_name_buffer[1000];
>>           font_name_char_count = GetTextFace(hdc, 1000 ,
>>                                              font_name_buffer);
>>
>> Here the font name char count is 6, and the font name is
>> "System".  Now I know what the "System" font looks like,
>> it's what comes up by default in my custom controls.  It's
>> not the nice looking font that is used by default in the
>> dialog boxes.
>>
>>    I am at a breakpoint in dialogproc, and hdc is the handle
>> to the device config for this for the dialog box's handle,
>> hdlg.
>>
>>    So, why aren't I seeing the name of the dialog box's
>> font in the name buffer?
>>
>>                                                    Thanks
>>                                                    Larry
>>
> I don't know why your call to GetTextFace() does not work but the good 
> news is that that is the wrong approach to the problem and you don't 
> need to make it work.
> 
> The font for the dialog (or any window) is not stored in the DC. It must 
> be selected into the DC each time you plan to use it and the original 
> font selected back in when you're finished.
> 
> Because of this, GetDC() followed by GetTextFace() is always going to 
> give you "System" and that is not what you want.
> 
> Here's the right way to solve your problem:
> 
> When a dialog is created, it creates a font as specified in the dialog 
> template: MS Sans Serif, 8 pt, or whatever. It saves the handle to this 
> font in its private window data. Every time it calls GetDC it selects 
> this handle into the DC and, of course, selects the original handle back 
> before calling ReleaseDC().
> 
> It also passes this handle on to each control as the control is created, 
> using the WM_SETFONT message. All standard and common control supplied 
> by Microsoft save the font handle and select it for use just like the 
> dialog does.
> 
> It's up to you to make this work in your own custom control.
> 1) Handle the WM_SETFONT message and save the font handle somewhere. 
> (Saving it in your window private data is a good idea if you plan to 
> have more than one instance of the control open at a time.)
> 2) After any call to GetDC() in your control you must get the font 
> handle and SelectObject() to make the DC use it.
> 3) Before calling ReleaseDC() you should call SelectObject() to put the 
> original font handle back.
> 
> Norm
> 
Thanks Norm:

    That works.

    Please let me know if this is the whole proper method.  I
don't want to have a resource leak.

    I'll only have one instance of this control, so I'll
squirrel the value away in a static variable in the control's
winproc.

      case WM_SETFONT:
           new_font_handle = (HFONT)wParam;
           return 0;

      case WM_PAINT:

           hdc = BeginPaint(hwnd, &ps);
           old_font_handle = (HFONT)SelectObject(hdc,
                                           new_font_handle);

                         .
                         .
                         .

           DeleteObject(SelectObject(hdc, old_font_handle));
           EndPaint(hwnd, &ps);

           return 0;

    Anything else I need to do?

                                                    Thanks
                                                    Larry

0
Larry
12/27/2003 9:18:41 PM
John Brown wrote:

>>    Next, I try the following code:
>>
>>           TCHAR font_name_buffer[1000];
>>           font_name_char_count = GetTextFace(hdc, 1000 ,
>>                                              font_name_buffer);
> 
> I don't know why GetTextFace(hdc, 100, NULL) does not work.
> 
> 
>>    So, why aren't I seeing the name of the dialog box's
>>font in the name buffer?
> 
> 
> 
> You're probably getting "System" instead of the "MS Sans Serif" that
> you expect because the dialog box font *is* System. "MS Sans Serif" is
> the font used by the dialog box *controls*.

Thanks John:

    I don't think so.

    When I look at the dialogbox's properties in the
resource editor, I'm seeing "MS Sans Serif" as it's
font.  And the text that was displayed in the control
I created was the "System" font that you get in a
window when no font is specified.

    I appreciate your advice.

                                              Thanks
                                              Larry

0
Larry
12/27/2003 9:25:30 PM
Larry Lindstrom wrote:
>    That works.
> 
>    Please let me know if this is the whole proper method.  I
> don't want to have a resource leak.
> 
>    I'll only have one instance of this control, so I'll
> squirrel the value away in a static variable in the control's
> winproc.
> 
>      case WM_SETFONT:
>           new_font_handle = (HFONT)wParam;
>           return 0;
> 
>      case WM_PAINT:
> 
>           hdc = BeginPaint(hwnd, &ps);
>           old_font_handle = (HFONT)SelectObject(hdc,
>                                           new_font_handle);
> 
>                         .
>                         .
>                         .
> 
>           DeleteObject(SelectObject(hdc, old_font_handle));
>           EndPaint(hwnd, &ps);
> 
>           return 0;
> 
>    Anything else I need to do?
> 
>                                                    Thanks
>                                                    Larry
> 

Actually, you don't want to delete the font after selecting the original 
font back into the DC. The font belongs to the dialog box and it will 
delete the font when it closes.

Just call
    SelectObject(hDC, old_font_handle);
and ignore the return value.

Norm

0
Norman
12/27/2003 11:21:45 PM
John Brown wrote:

>>    Next, I try the following code:
>>
>>           TCHAR font_name_buffer[1000];
>>           font_name_char_count = GetTextFace(hdc, 1000 ,
>>                                              font_name_buffer);
> 
> I don't know why GetTextFace(hdc, 100, NULL) does not work.
> 
> 
>>    So, why aren't I seeing the name of the dialog box's
>>font in the name buffer?
> 
> 
> 
> You're probably getting "System" instead of the "MS Sans Serif" that
> you expect because the dialog box font *is* System. "MS Sans Serif" is
> the font used by the dialog box *controls*.

"System" is the font that is selected into ANY DC when you call GetDC(). 
(An exception is "owned" DCs that retain selected objects between uses.)

The font used by a dialog is saved (as a handle) in the dialog's private 
window area and passed to controls for them to use as appropriate.

Norm

0
Norman
12/27/2003 11:25:21 PM
> 
> "System" is the font that is selected into ANY DC when you call GetDC(). 
> (An exception is "owned" DCs that retain selected objects between uses.)
> 

Thanks for the correction, and the information in your previous posts.
0
johnbrown105
12/28/2003 1:01:45 PM
Reply: