2013-08-09 6 views
0

여기에서 원시 Windows API를 사용하고 있습니다. WM_INITDIALOG 메시지 중에 대화 상자에 글꼴을 전달하고 대화 상자 안에 새 자식 창이 만들어 질 때마다 해당 글꼴을 계속 사용하려고합니다. 하지만 내가 만든 HFONT를 계속 전달하고 싶지는 않습니다. 필요할 때마다 대화 상자 창에서 검색하고 싶습니다.HFONT 대화 상자에서 보낸 메시지가 아닙니다.

그래서 내 WM_INITDIALOG 처리기를 입력 할 때 글꼴을 만든 다음 SendMessage (WM_SETFONT)를 사용하여 대화 상자로 보냅니다. 그런 다음 새 자식 창을 만들 때마다 SendMessage (WM_GETFONT)를 사용하여 대화 글꼴을 검색하는 것이 필요하다고 생각했습니다. 하지만 대화 상자에서받은 핸들은 내가 만든 핸들이 아니므로 새로운 컨트롤 글꼴을 설정하기 위해 새 핸들을 사용하면 잘못된 글꼴이 표시된다는 것은 놀라운 일이 아닙니다.

응용 프로그램이 종료 될 때 글꼴 핸들 만 파괴합니다. 하지만 잘못된 핸들이 그렇지 않으면 문제가되지 않을 것입니다. 아래 예제에서는 명시 적으로 글꼴 핸들을 전달하는 컨트롤이 올바른 글꼴을 표시하지 않습니다.

아이디어가 있으십니까?

#include <Windows.h> 
#include <CommCtrl.h> 

static INT_PTR CALLBACK DialogProc(
    _In_ HWND hwndDlg, 
    _In_ UINT uMsg, 
    _In_ WPARAM wParam, 
    _In_ LPARAM lParam) 
{ 
    static HFONT hFont = NULL; 

    switch(uMsg) 
    { 
     case WM_CLOSE: 
      ::EndDialog(hwndDlg, 0); 
      ::DeleteObject(hFont); 
      return TRUE; 

     case WM_INITDIALOG: 
     { 
      // create our font 
      hFont = ::CreateFontW(
       36, 
       0, 
       0, 
       0, 
       FW_NORMAL, 
       0, 
       0, 
       0, 
       DEFAULT_CHARSET, 
       OUT_DEFAULT_PRECIS, 
       CLIP_DEFAULT_PRECIS, 
       CLEARTYPE_QUALITY, 
       VARIABLE_PITCH, 
       L"Tahoma"); 

      // set that font as the dialog font 
      ::SendMessageW(hwndDlg, WM_SETFONT, (WPARAM)hFont, TRUE); 

      // retrieve the dialog font 
      HFONT hFontDialog = (HFONT)::SendMessageW(hwndDlg, WM_GETFONT, 0, 0); 

      // create two child windows 
      HWND hwndStatic1 = ::CreateWindowExW(0, WC_STATIC, L"hFont",  WS_VISIBLE | WS_CHILD, 0, 0, 100, 30, hwndDlg, NULL, 0, 0); 
      HWND hwndStatic2 = ::CreateWindowExW(0, WC_STATIC, L"hFontDialog", WS_VISIBLE | WS_CHILD, 0, 50, 100, 20, hwndDlg, NULL, 0, 0); 

      // set their fonts, using the one we created for the first one and 
      // the one from the dialog for the second one 
      ::SendMessageW(hwndStatic1, WM_SETFONT, (WPARAM)hFont,  TRUE); 
      ::SendMessageW(hwndStatic2, WM_SETFONT, (WPARAM)hFontDialog, TRUE);    

      return FALSE; 
     } 
    } 

    return FALSE; 
}  


#include <PshPack2.h> 
struct DialogTemplate 
{    
    DLGTEMPLATE Base; 
    WORD Menu; 
    WORD Class;   
    WCHAR Title[1]; 
}; 
#include <PopPack.h> 


int WINAPI wWinMain(
    __in HINSTANCE  hInstance, 
    __in_opt HINSTANCE hPrevInstance, 
    __in LPWSTR  lpCmdLine, 
    __in int   nShowCmd) 
{ 
    DialogTemplate dt = {0}; 
    dt.Base.style = DS_CENTER | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU; 
    dt.Base.cx = 200; 
    dt.Base.cy = 200;  

    return ::DialogBoxIndirectParamW(
     ::GetModuleHandle(NULL), 
     (DLGTEMPLATE*)&dt, // holy hack, Batman! I hope this is OK... 
     NULL, 
     DialogProc, 
     (LPARAM)0); 
} 

답변

1

대화 상자가 WM_SETFONT에 응답하지 않습니다. 대화 상자에는 템플리트에 정의 된 글꼴이 있으며 DS_SETFONT 스타일이 설정된 경우 작성시 해당 하위 컨트롤에 적용됩니다. WM_GETFONT에서 가져온 글꼴은 처음에 템플릿을 기반으로 작성된 글꼴입니다.

대화 상자를 만든 후에 제어 글꼴을 변경하려면 WM_SETFONT 개의 메시지를 개별적으로 보내야합니다.

내 이유에 대한 나의 이론 : 대화 상자 레이아웃은 글꼴 크기 ("대화 단위"는 글꼴 높이와 평균 글꼴 너비의 일부)를 기반으로합니다. 따라서 대화 상자는 컨트롤을 크기를 조정하고 레이아웃하기 위해 글꼴을 만들 때 글꼴을 알아야합니다. 나중에 대화 상자의 관점에서 글꼴을 변경하면 크기 조정/다시 레이아웃이 필요할 수 있으며 대화 관리자에서 구현 된 기능이 아닙니다.

+0

이론이 맞는지는 모르지만 그 글꼴을 변경할 수 없다는 확인을 해 주셔서 감사합니다. MSDN의 WM_SETFONT 문서에서이 점에 대해 분명히 알고 싶습니다. (현재) 그들은 당신이 폰트를 바꿀 수 있다고 말하지 않지만, 당신이 할 수 없다고 말하는 것은 아닙니다. – user1593842