我在这里玩原始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);
}
答案 0 :(得分:1)
对话框不响应WM_SETFONT
。对话框具有在其模板中定义的字体,如果设置了DS_SETFONT
样式,则会在创建时将其传播给其所有子控件。您从WM_GETFONT
返回的字体是最初根据模板创建的字体。
如果要在创建对话框后更改控制字体,则需要单独发送WM_SETFONT
条消息。
关于为什么会出现这种情况的理论:对话框布局基于字体大小(“对话框单位”是字体高度和平均字体宽度的一小部分)。因此,对话框需要在创建时知道其字体,以便调整控件的大小和布局。从对话框的角度来看,之后更改字体可能需要调整大小/重新布局,这不是对话管理器中实现的功能。