我在这里玩原始的 Windows API。我试图在 WM_INITDIALOG 消息期间将字体传递给对话框,然后在该对话框中创建新的子窗口时继续使用该字体。但我不想继续传递我创建的 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);
}