Menu

#32 Make Tk use the default Windows font

closed-duplicate
5
2014-08-20
2001-09-14
Anonymous
No

Hello,

Donal K. Fellows asked me to submit the following patch I posted to comp.lang.tcl. Its purpose is
to make Tk use the standard Windows dialog font by default. In the current version, the default
font for Tk buttons, labels, entries etc. is "MS Sans Serif" 8 pt regardless of what font the user
configured in Windows; this makes Tk programs look slightly (but noticably) different from native
Windows dialog applications. With my patch, Tk uses the Windows standard dialog font by default.
Here's the news article I wrote on September 13, 2001.

--- 8< ---

To make Tk use the standard Windows dialog font, the Tk
source code has to be patched in two places. I did this
for Tk 8.3.3. Perhaps someone has the time to put this
on a Wiki page, include in a FAQ, or even integrate it
in the official Tk for Windows source codes.

First, a few lines have to be added to function TkpGetNativeFont
in tk/win/tkWinFont.c. These lines add a new font name,
"windefault", which can be used throughout Tk. The windefault
font is always the Windows standard dialog font. Note that
this font is different from all the other system fonts,
like "system" or "ansi". It has to be implemented differently
from the other system fonts since it can't be retrieved
through GetStockObject. Here's the new version of TkpGetNativeFont:

TkFont *
TkpGetNativeFont(
Tk_Window tkwin, /* For display where font will
be used. */
CONST char *name) /* Platform-specific font name. */
{
int object;
WinFont *fontPtr;

/* New code starts here */
if (strcmp(name,"windefault")==0)
{
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS),
&ncm, 0);

tkwin = (Tk_Window) ((TkWindow *)
tkwin)->mainPtr->winPtr;
fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
InitFont(tkwin,
CreateFontIndirect(&ncm.lfMessageFont),
0, fontPtr);

return (TkFont *) fontPtr;
}
/* New code ends here - rest of function unchanged */

object = TkFindStateNum(NULL, NULL, systemMap, name);
if (object < 0) {
return NULL;
}

tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
InitFont(tkwin, GetStockObject(object), 0, fontPtr);

return (TkFont *) fontPtr;
}

With this modification it's possible to use the new font with any
Tk widget, like this:

button .b -text "Whatever" -font windefault

The second modification sets the windefault font as the default for
all Tk widgets. This is done by replacing the CTL_FONT define in
tk/win/tkWinDefault.h with "windefault", like this:

#define CTL_FONT "windefault"

In the original version, CTL_FONT is hardcoded to 8 pt MS Sans Serif.

After these changes, recompile the Tk library and rebuild wish or
whatever application you're linking Tk into.
--- 8< ---

Sorry for not being able to submit CVS diffs, but I think the above should be obvious and not too
hard to integrate.

If you have any questions about this, contact me at wr@grp.de.

Thanks
Wolfram Rösler

Discussion

  • Christopher Nelson

    Logged In: YES
    user_id=107514

    I applied this patch (with some adaptation) to Tk 8.4a3. Before the patch,
    my default button text appeared to be a squosh too large (maybe a point).
    After the patch, default button text is HUGE.

    % font metrics "{MS Sans Serif} 8"
    -ascent 11 -descent 2 -linespace 13 -fixed 0
    % font metrics windefault
    -ascent 13 -descent 3 -linespace 16 -fixed 0

    I'm on an Citrix NT server. The desktop properties dialog tells me that my text
    is MS San Serif 10.

    % font metrics "{MS Sans Serif} 10"
    -ascent 13 -descent 3 -linespace 16 -fixed 0

    (I'd attach my patch but there's nothing on this page to let me do that. <shrug>)

     
  • Christopher Nelson

    Logged In: YES
    user_id=107514

    The patch seems to do the right thing on W98 (SE 4.10.2222 A) where the desktop
    properties sheet tells me I have "MS Sans Serif 8" text.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902

    Strange; the file upload machinery is available on the page
    when I view it (even if SF makes it as hard-to-use as
    possible - you have to check a box, select a file *and* give
    a description for the file for it to work.)

     
  • Nobody/Anonymous

    Logged In: NO

    The behaviour described by Chris Nelson on his Citrix server seems to be ok. His Windows font is set to MS
    Sans Serif 10 pt, and "font metrics" for this font prints exactly the same as it prints for the "windefault" font.
    Which font does Windows use for standard dialogs in other applications? Perhaps a screenshot would be
    helpful.

    Regards,
    W. Rsler (wr@grp.de)

     
  • Christopher Nelson

    Logged In: YES
    user_id=107514

    I've looked into this some more. It appears that windefault _is_ the same as the font
    specified in the desktop property sheet. What I don't understand is why no other
    button (in 'Windows applications) uses that default font!

    I have a screen shot I'd love to upload but I don't seem to have the ability to do that.<shrug>
    I've done it before, I know what I'm looking for but there's not checkbox, no browse button on
    this or any other page Iv'e checked this morning.

     
  • Christopher Nelson

    Logged In: YES
    user_id=107514

    I become increasingly dissatisfied with this patch.

    The Desktop Properties sheet lets you set distinct fonts for:

    - Title bars
    - Icons
    - Menus
    - Message box text
    - Palette titles
    - Selected items
    - Tool tips

    The non-client metrics stucture has fields for:

    - Caption font (is this a title bar?)
    - Menu font
    - Status font
    - Message font

    But NOT for application window or button text.

    I started with:

    NONCLIENTMETRICS ncm;
    ncm.cbSize = sizeof(NONCLIENTMETRICS);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
    sizeof(NONCLIENTMETRICS),
    &ncm, 0);

    tkwin = (Tk_Window) ((TkWindow *)
    tkwin)->mainPtr->winPtr;
    fontPtr = (WinFont *) ckalloc(sizeof(WinFont));

    if (strcmp(name,"Caption")==0) {
    InitFont(tkwin,
    CreateFontIndirect(&ncm.lfCaptionFont),
    0, fontPtr);
    } else if (strcmp(name,"Menu")==0) {
    InitFont(tkwin,
    CreateFontIndirect(&ncm.lfMenuFont),
    0, fontPtr);
    } else if (strcmp(name,"Status")==0) {
    InitFont(tkwin,
    CreateFontIndirect(&ncm.lfStatusFont),
    0, fontPtr);
    } else if (strcmp(name,"Message")==0) {
    InitFont(tkwin,
    CreateFontIndirect(&ncm.lfMessageFont),
    0, fontPtr);
    } else {

    but got stumped on what should be "windefault" and what to use for labels and buttons.
    There must be a way to ask 'Windows what font is used for buttons but I can't figure it out.

     
  • Christopher Nelson

    Logged In: YES
    user_id=107514

    I have what I now consider a decent patch. The problem -- as I see it -- was
    that the list of fonts in systemMap was missing DEFAULT_GUI_FONT. I've added it.
    While I was at it, I put in access to the fonts configured in the Desktop Properties.
    You may not like the names; I'm open to feedback.

    As I go forward with this, I'd like Tk to respond to WM_SETTINGCHANGE and update
    widgets that use the Desktop fonts as it does when you recreate a Tk font. I'll
    look into that when this is firmer. (BTW, should predefined fonts (like "system" on
    'Windows, "application" for Macs) be listed by [font names]? By [font families]?)

    I still can't find a way to post a file on this page. Here comes my patch in-line:

    Index: tkWinFont.c

    RCS file: /pti/prod/mrd/CvsRepository/tcl/tk/win/tkWinFont.c,v
    retrieving revision 1.1
    diff -u -w -r1.1 tkWinFont.c
    --- tkWinFont.c 2001/09/04 23:51:53 1.1
    +++ tkWinFont.c 2001/09/26 18:40:22
    @@ -11,7 +11,7 @@
    * See the file "license.terms" for information on usage and redistribution
    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    *
    - * RCS: @(#) $Id: tkWinFont.c,v 1.1 2001/09/04 23:51:53 murray Exp $
    + * RCS: @(#) $Id: tkWinFont.c,v 1.2 2001/09/20 15:43:42 nelson Exp $
    */

    #include "tkWinInt.h"
    @@ -160,6 +160,7 @@
    {ANSI_FIXED_FONT, "ansifixed"},
    {ANSI_VAR_FONT, "ansi"},
    {DEVICE_DEFAULT_FONT, "device"},
    + {DEFAULT_GUI_FONT, "defaultgui"},
    {OEM_FIXED_FONT, "oemfixed"},
    {SYSTEM_FIXED_FONT, "systemfixed"},
    {SYSTEM_FONT, "system"},
    @@ -285,15 +286,59 @@
    *
    *---------------------------------------------------------------------------
    */
    -
    TkFont *
    TkpGetNativeFont(
    - Tk_Window tkwin, /* For display where font will be used. */
    + Tk_Window tkwin, /* For display where font will
    + be used. */
    CONST char *name) /* Platform-specific font name. */
    {
    int object;
    WinFont *fontPtr;

    + LOGFONT lf;
    + /*
    + * This is needed for all but one of the desktop fonts so let's
    + * just get it once.
    + */
    + NONCLIENTMETRICS ncm;
    + ncm.cbSize = sizeof(NONCLIENTMETRICS);
    + SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
    + sizeof(NONCLIENTMETRICS),
    + &ncm, 0);
    + tkwin = (Tk_Window) ((TkWindow *)
    + tkwin)->mainPtr->winPtr;
    + fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
    +
    + if ((strcmp(name,"Caption")==0)
    + || (strcmp(name,"Title")==0)) {
    + InitFont(tkwin,
    + CreateFontIndirect(&ncm.lfCaptionFont),
    + 0, fontPtr);
    + } else if ((strcmp(name,"SmallCaption")==0)
    + || (strcmp(name,"PaletteTitle")==0)) {
    + InitFont(tkwin,
    + CreateFontIndirect(&ncm.lfSmCaptionFont),
    + 0, fontPtr);
    + } else if (strcmp(name,"Menu")==0) {
    + InitFont(tkwin,
    + CreateFontIndirect(&ncm.lfMenuFont),
    + 0, fontPtr);
    + } else if ((strcmp(name,"Status")==0)
    + || (strcmp(name,"Tooltip")==0)) {
    + InitFont(tkwin,
    + CreateFontIndirect(&ncm.lfStatusFont),
    + 0, fontPtr);
    + } else if (strcmp(name,"Message")==0) {
    + InitFont(tkwin,
    + CreateFontIndirect(&ncm.lfMessageFont),
    + 0, fontPtr);
    + } else if (strcmp(name,"Icon")==0) {
    + SystemParametersInfo(SPI_GETICONTITLELOGFONT,
    + sizeof(LOGFONT), &lf, 0);
    + InitFont(tkwin,
    + CreateFontIndirect(&lf),
    + 0, fontPtr);
    + } else {
    object = TkFindStateNum(NULL, NULL, systemMap, name);
    if (object < 0) {
    return NULL;
    @@ -302,6 +347,7 @@
    tkwin = (Tk_Window) ((TkWindow *) tkwin)->mainPtr->winPtr;
    fontPtr = (WinFont *) ckalloc(sizeof(WinFont));
    InitFont(tkwin, GetStockObject(object), 0, fontPtr);
    + }

    return (TkFont *) fontPtr;
    }
    Index: tkWinDefault.h
    ===================================================================
    RCS file: /pti/prod/mrd/CvsRepository/tcl/tk/win/tkWinDefault.h,v
    retrieving revision 1.1
    diff -u -w -r1.1 tkWinDefault.h
    --- tkWinDefault.h 2001/09/04 23:51:52 1.1
    +++ tkWinDefault.h 2001/09/26 18:04:31
    @@ -9,7 +9,7 @@
    * See the file "license.terms" for information on usage and redistribution
    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    *
    - * RCS: @(#) $Id: tkWinDefault.h,v 1.1 2001/09/04 23:51:52 murray Exp $
    + * RCS: @(#) $Id: tkWinDefault.h,v 1.2 2001/09/20 15:43:41 nelson Exp $
    */

    #ifndef _TKWINDEFAULT
    @@ -28,7 +28,8 @@
    #define BLACK "Black"
    #define WHITE "White"

    -#define CTL_FONT "{MS Sans Serif} 8"
    +#define CTL_FONT "defaultgui"
    +
    #define NORMAL_BG "SystemButtonFace"
    #define NORMAL_FG "SystemButtonText"
    #define ACTIVE_BG NORMAL_BG
    @@ -269,7 +270,7 @@
    #define DEF_MENU_CURSOR "arrow"
    #define DEF_MENU_DISABLED_FG_COLOR DISABLED
    #define DEF_MENU_DISABLED_FG_MONO ""
    -#define DEF_MENU_FONT CTL_FONT
    +#define DEF_MENU_FONT "Menu"
    #define DEF_MENU_FG MENU_FG
    #define DEF_MENU_POST_COMMAND ""
    #define DEF_MENU_RELIEF "flat"
    @@ -298,7 +299,7 @@
    #define DEF_MENUBUTTON_DIRECTION "below"
    #define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED
    #define DEF_MENUBUTTON_DISABLED_FG_MONO ""
    -#define DEF_MENUBUTTON_FONT CTL_FONT
    +#define DEF_MENUBUTTON_FONT "Menu"
    #define DEF_MENUBUTTON_FG NORMAL_FG
    #define DEF_MENUBUTTON_HEIGHT "0"
    #define DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR DEF_MENUBUTTON_BG_COLOR
    @@ -331,7 +332,7 @@
    #define DEF_MESSAGE_BORDER_WIDTH "2"
    #define DEF_MESSAGE_CURSOR ""
    #define DEF_MESSAGE_FG NORMAL_FG
    -#define DEF_MESSAGE_FONT CTL_FONT
    +#define DEF_MESSAGE_FONT "Message"
    #define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG
    #define DEF_MESSAGE_HIGHLIGHT HIGHLIGHT
    #define DEF_MESSAGE_HIGHLIGHT_WIDTH "0"

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2001-10-15

    Logged In: YES
    user_id=72656

    Attached version of patch received on 2001-10-08 from Chris.

     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2001-10-15
     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2001-11-17
    • status: open --> closed-duplicate
     
  • Jeffrey Hobbs

    Jeffrey Hobbs - 2001-11-17

    Logged In: YES
    user_id=72656

    I've dup'ed this out against 471727 (TIP #64 patch).