2

My question arises from our program running on a Japanese OS. One of my co-workers had done something like embed a property sheet on a dialog and the property sheet has multiple pages. Everything works fine on other languages except Japanese.

On Japanese systems, some of the controls get cut off because there is not enough space. I determined that this was because on Japanese systems, the font used by the property sheet and hence the property pages was different than the font used by the parent dialog of the property sheet. For the record, the font used by the parent dialog and all the property pages was MS Shell Dlg, 8:

FONT 8, "MS Shell Dlg", 0, 0, 0x1

I wanted a simple fix to try and ameliorate the problem for Japanese and all potential system. I examined the fonts on Japanese Windows 7 property sheets/pages and they always SEEMED to be the Default GUI Font. So, when I was creating my first dialog, on the fly after loading the DIALOGTEMPLATE into memory with the MFC class CDialogTemplate, I would modify the font of the parent dialog to match the default GUI font, and everything would be fine on Japanese Windows--Window 7, that is.

A customer has now found that this is not a valid solution for Windows 8/8.1--it exhibits the original problem. After examining the fonts on a Windows 8.1 VM, I did determine that the property sheet on Windows 8.1 and the child property pages does not use the Default GUI Font.

That's lots of words to ask. is there a way to determine what the default font used by property sheets on a Windows system?

I figure my ugly workaround would be to create a property sheet with one property page, determine the font used by that property sheet and page, and then modify the dialog template of my parent dialog on the fly to use that font. Since property sheets have some quirks about activation (they get activated on creation even if invisible), I'd rather not, but it seems to be my only choice--besides re-engineering of my co-worker's dialogs.

Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29
  • If possible, create/edit your dialogs in resource editor to use "Segoe UI" size 9. This is the default font for Vista+. There is no issue if you are not worried about WinXP. – Barmak Shemirani May 31 '16 at 17:02
  • Fonts are [complicated](http://stackoverflow.com/a/6057761/5240004) If you have a test machine running 8/8.1 with the Japanese language pack installed, you can find the font with `GetDC` and the window handle (likely your property sheet's parent window), then `GetTextFace` to get the font name, and `GetTextMetrics` to get the size information. (Assuming that the font is actually selected into that DC) – theB May 31 '16 at 17:07
  • @BarmakShemirani The default font as created by Visual Studio and I assume by Windows is "MS Shell Dlg", 8 pt. In fact, on my US Windows 7 box, this is the font used to create property sheets. Of course, MS Shell Dlg is an alias font. In the past, I recall having problems with Japanese systems because they do not always have Segoe UI. – Joseph Willcoxson May 31 '16 at 17:14
  • @theB What I am doing is having to modify on the fly the parent dialog font because property sheets do not have font settings--and they ignore the fonts in the pages. Through trial and error I've found that I can put any crazy font size in a property page, and the property page will be uneffected. I can see the reasonableness of enforcing that behavior. Once a sheet has been created, it seems impossible to modify the font or the font of any of the pages. Once it is created, the fonts seem to be stuck. – Joseph Willcoxson May 31 '16 at 17:18

3 Answers3

3

Yes, apparently the font for Property Sheet and Wizard is different. There is a dialog template for each language. In WinAPI PropertySheet uses the font from that template.

To find this font use the following (I only tested this on Windows 10)

#define IDD_PROPSHEET   1006
#define IDD_WIZARD      1020

HMODULE hmod = LoadLibrary(L"comctl32.dll");
if (hmod)
{
    HRSRC hres = FindResource(hmod, MAKEINTRESOURCEW(IDD_PROPSHEET), (LPWSTR)RT_DIALOG);
    if (hres)
    {
        HGLOBAL hglob = LoadResource(hmod, hres);
        if (hglob)
        {
            CString fontname;
            WORD fontsize;
            CDialogTemplate::GetFont((DLGTEMPLATE*)hglob, fontname, fontsize);
            TRACE(L"%s %d\n", fontname, fontsize);
        }
    }
    FreeLibrary(hmod);
}

This might be somewhat outdated. The font obtained from SystemParametersInfo(SPI_GETNONCLIENTMETRICS...) must already be compatible because it's the main display font.

For some reason, MFC takes things further and applies that template font to property pages as well. MFC does other things which I can't understand, for example VS2015 has this code in "dlgprop.cpp"

LANGID langid = GetUserDefaultUILanguage();
if ((PRIMARYLANGID(langid) == LANG_JAPANESE) && IsFontInstalled(_T("MS UI Gothic")))
{
    WORD wLang = MAKELANGID(LANG_JAPANESE, 0x3f);
    if (wLang != 0)
    {
        hResource = ::FindResourceExW(hInst, (LPWSTR) RT_DIALOG,
                MAKEINTRESOURCEW(bWizard ? IDD_WIZARD : IDD_PROPSHEET), wLang);
    }
    ...
}

I don't know why it forces a sub-language if a certain font is present. Also as @PRinCEKtd points out, this font might be outdated (but the font could be still be installed) You can step through CPropertySheet to find all the font manipulations.

see also codeguru link, Custom Font in Property Sheets

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
0

try use

NONCLIENTMETRICS ncm = { GetNONCLIENTMETRICSWSize() };
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)){..}

usual all system controls (status bar, list view, tree view,menu, message box..) use fonts from this struct

where GetNONCLIENTMETRICSWSize() can be like this (on XP/2003 (major < 6) struct size is less on 4 byte compare vista+)

ULONG GetNONCLIENTMETRICSWSize()
{
    static ULONG m;
    if (!m)
    {
        RtlGetNtVersionNumbers(&m, 0, 0);
    }

    return m < 6 ? sizeof(NONCLIENTMETRICS) - 4 : sizeof(NONCLIENTMETRICS);
}
RbMm
  • 31,280
  • 3
  • 35
  • 56
  • Well, thanks for responding, but that is not the answer. None of the LOGFONTs returned match the font of the property sheet/page. The fonts I am looking for are actually in the client area and not the non-client area. Maybe some other SystemParametersInfo() call will be the answer... – Joseph Willcoxson May 31 '16 at 16:33
  • 1
    This should work. `ncm.lfMessageFont.lfFaceName` should return "Segoe UI" on Vista+. What font are you expecting? – Barmak Shemirani May 31 '16 at 17:03
  • It's not necessarily the name that is the problem, but the size. If I look at the fonts in my dialog, property sheet and pages, lf.lfHeight = -11, which at 96 DPI is 8 pt. All those structures on my US system return lf.lfHeight = -12, which is not the same and causes layout issues. Layout of controls on a dialog is a combination of font name and size. – Joseph Willcoxson May 31 '16 at 17:09
0

From Windows Vista onwards, the Meiryo font family was used as default in the Windows user interface to support Japanese. I think before vista, it was MS Gothic...

How about manually setting a default windows font directly? There are many fonts that support Japanese as well as a wide variety of languages. Some of them have been present from XP upto 10, though they might have some updates.

PRinCEKtd
  • 270
  • 3
  • 12