2

Possible Duplicates:
How to set default font for all the windows in a Win32 Application?
Which Font is the default for MFC Dialog Controls?

I hate default Windows Api Window Font (it is the default system font , i think). I know how to change the font of an individual child, say a button. But isn't there a way to change the font of the entire application so that I don't have to use SendMessage(...WM_SETFONT) on every single widget in my program?

Code examples are welcomed. (I am using C++)

Community
  • 1
  • 1
ApprenticeHacker
  • 21,351
  • 27
  • 103
  • 153
  • If you don't want to send WM_SETFONT to all your windows, then why don't you move to a higher level abstraction of the Win32 framework? – David Heffernan Jul 17 '11 at 14:35
  • 1
    @David Frankly because I am **making** a higher level abstraction of the Win32 framework. – ApprenticeHacker Jul 17 '11 at 14:37
  • 1
    @burning If you really are making a higher level abstraction of the Win32 framework then you'll have a common base class for all your windowed controls and you can set the font there. That's what all the Win32 GUI frameworks I've ever seen do. – David Heffernan Jul 17 '11 at 14:47
  • I know. I have the **WinControl** class for common widgets. But how do i change the font of say , menus? Or things made with Resources? – ApprenticeHacker Jul 17 '11 at 14:49
  • @burningprodigy: You **don't** change the font of menus. They use the default system font automatically. End of story. They're not customizable beyond owner-draw, and you definitely don't want to do that. At least not if you want a native-looking app, and if not, there's little point in writing to the Win32 API. And resource items don't have fonts. **Dialogs** have fonts, but you set those the same way as any other window. Put the code in the handler for the `WM_INITDIALOG` message. – Cody Gray - on strike Jul 17 '11 at 14:55
  • @Cody Yup I sure don't want to use owner-drawn, so I guess you are right, though I do wish windows menus could show images like Gtk ones... – ApprenticeHacker Jul 17 '11 at 14:57
  • Well, they can. There's a bit milder form of owner-drawing you can implement to get images on menus. It's still hell in Windows XP and earlier, but the Vista shell added some nice support for it. You'll notice even the desktop context menu has icons in Vista and 7. The same mechanism works nicely in your own apps. But it's still non-trivial to implement, and even more difficult to get right if you still want/need to support Windows XP. I maintain my own WinAPI wrapper library for fun. Honestly you probably have no business doing this for a production app. – Cody Gray - on strike Jul 17 '11 at 14:59
  • @Cody I'm doing this for fun too. Unfortunately the OS I am using right now is XP SP3 , so I guess image menus are out of reach... :( (I hate XP...) – ApprenticeHacker Jul 17 '11 at 15:33
  • 1
    use hbmpItem field of MENUITEMINFO to get images in menus. Don't try owner draw it's frightfully hard to get it right. – David Heffernan Jul 17 '11 at 15:33
  • Yeah, David's right. That's the easiest way to get menu icons in XP. The trick is that XP is expecting images that are 12 or 13 pixels (I forget which). The 16 pixel icons that you're probably used to seeing elsewhere (like in the Vista shell or in .NET WinForms) are too large and are going to get clipped. If you're doing it for fun, it can't hurt to play with. Didn't realize that. Try it out and if you get stuck, post a question about images in menus. – Cody Gray - on strike Jul 17 '11 at 15:35
  • Thanks! You just made my day. By the way, does anyone have a useful link to some documentation on this way of making image menus? – ApprenticeHacker Jul 17 '11 at 15:45
  • @burning @cody there is no documentation, you are just expected to know how to do it!!! If I come across as sounding bitter, then that would be a correct reading of my feelings towards this particular API. – David Heffernan Jul 17 '11 at 19:15

2 Answers2

7

One way would be to use EnumChildWindows:

BOOL CALLBACK SetChildFont(HWND hwndChild, LPARAM lParam)
{
    HFONT hFont = (HFONT)lParam;
    SendMessage(hwndChild, WM_SETFONT, (WPARAM)hFont, TRUE);
}

EnumChildWindows(hwndParent, SetChildFont, (LPARAM)hFont);
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
3

I explain all of this in quite a bit of depth here: Which Font is the default for MFC Dialog Controls? Definitely required reading for any Win32 developer who cares about getting the UI right.

There's no way to set the font for an entire application. The best thing you can do is set the font for a parent window and take advantage of the fact that most controls will inherit their font from their parent. To make extra sure that this works, you can write your own simple SendMessageToChildren function like MFC offers, which just walks down through the children of a particular parent recursively and sends each of them the WM_SETFONT message.

But WM_SETFONT is really your only option here. You can't set a font for an entire class like you can a background brush. Getting this right can be challenging, but I agree that it is a very important to try. The hallmark of an inconsistent UI and an unprofessional application is one that does not use the correct default GUI font. Windows Vista came along and complicated things even further by switching not only the face to Segoe UI, but the default size to 9 point.

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574