2

In the code that follows, the Miriam font is created in WM_CREATE and its family name is obtained in a static OUTLINETEXTMETRIC struct, pointed by s_potm. Then I exhibit the member otmpFamilyName of this structure in WM_PAINT, and I get the string Arial printed on the window client area, instead of Miriam. But there is no reason for this font substitution, as the font file mriam.ttf exists in Windows 7. Any explanation ?

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
    WNDCLASSEX  wndclassx;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = CS_HREDRAW | CS_VREDRAW;
    wndclassx.lpfnWndProc   = WndProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = 0;
    wndclassx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndclassx.lpszMenuName  = 0;
    wndclassx.lpszClassName = L"WndProc";
    wndclassx.hIconSm       = 0;

    if( !RegisterClassEx(&wndclassx) ) return 0;

    HWND hWnd = CreateWindow(L"WndProc", 0, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                             0, 0, hInstance, 0);

    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    MSG msg;

    while( GetMessage(&msg, NULL, 0, 0) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    //  Retorna msg.wParam

    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    static OUTLINETEXTMETRIC* s_potm;

    switch ( message )
    {
        case WM_CREATE:
        {
            HDC hDC;
            if( !(hDC = CreateIC(L"Display", nullptr, nullptr, nullptr)) ) return -1;

            LOGFONT lf;
            memset(&lf, 0, sizeof(LOGFONT));
            lf.lfHeight = 20;
            lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
            wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Miriam");

            HFONT hFont;
            if( !(hFont = CreateFontIndirect(&lf)) )
            {
                DeleteDC(hDC);
                return -1;
            }

             hFont = (HFONT)SelectObject(hDC, hFont);

             int ix = GetOutlineTextMetrics(hDC, 0, nullptr);

             s_potm = (OUTLINETEXTMETRIC*)new char[ix];

             GetOutlineTextMetrics(hDC, ix, s_potm); 

             DeleteObject(SelectObject(hDC, hFont));
             DeleteDC(hDC);
        }
        break;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &ps);
            wchar_t* p = (wchar_t*)((BYTE*)s_potm + (int)s_potm->otmpFamilyName);
            TextOut(ps.hdc, 10, 20, p, wcslen(p)); 
            EndPaint(hwnd, &ps);
        }
        break;

        case WM_DESTROY:

        PostQuitMessage(0);
        break;

        default:

        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

Edit : the same thing happens with the font MT Extra

4

1 に答える 1

4

Windowsにフォントを要求すると、LOGFONT構造にリストされているすべての基準に一致するように最善を尽くします。一部のフィールドは他のフィールドよりも優先されます。ほとんどの値をゼロのままにしました。

この場合、あなたを失望させているのはlfCharSetフィールドだと思います。ゼロはに相当しANSI_CHARSETますが、ミリアムはANSIフォントのようには見えません。

MSDNのドキュメントには次のように書かれていlfCharSetます。

このパラメータは、フォントマッピングプロセスで重要です。一貫した結果を保証するには、特定の文字セットを指定します。lfFaceNameメンバーで書体名を指定する場合は、lfCharSet値がlfFaceNameで指定された書体の文字セットと一致することを確認してください。

于 2012-06-22T22:04:11.417 に答える