对于我的应用程序,我需要创建一个不使用资源的对话框。 我正在尝试使用 DialogBoxInderect 功能。 代码令人难以置信的丑陋,但不知怎的,我成功地做到了。
问题在于,由于某些原因,对话框比我用更大的字体要求的要大得多。
如果我从资源加载它,对话框的样子如下:
当我调用 DialogBoxInderect 函数时,这是一个具有相同大小的对话框。
以下是在代码中定义它的方式:
HGLOBAL hGlobal;
LPDLGTEMPLATE wlsDialogTemplate;
LPDLGITEMTEMPLATE wlsDialogItemTemplate;
LPWORD nextItem;
LPWSTR itemString;
int32_t itemStringLength;
// Check for memory allocation errors
hGlobal = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hGlobal)
return -1;
wlsDialogTemplate = (LPDLGTEMPLATE)GlobalLock(hGlobal);
// Define a dialog box.
wlsDialogTemplate->style = WS_CAPTION;
wlsDialogTemplate->x = 0;
wlsDialogTemplate->y = 0;
wlsDialogTemplate->cx = 320;
wlsDialogTemplate->cy = 115;
GlobalUnlock(hGlobal);
retCode = DialogBoxIndirect(0, (LPDLGTEMPLATE)hGlobal, 0, ActivateWlsMsgDialog);
以下是它如何在RC文件中定义:
IDD_WLS_SMALL_MESSAGE_DLG DIALOGEX 0, 0, 320, 115
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",ID_CUSTOM_OK,175,95,120,15
PUSHBUTTON "Cancel",ID_CUSTOM_CANCEL,45,95,120,15
CTEXT "Static",IDC_HEADER_TEXT,120,10,170,70
CONTROL "",IDC_LOGO,"Static",SS_BITMAP,16,10,83,70
END
如您所见,第二个对话框比定义的大得多。我尝试使用各种风格标志但没有任何成功(这就是为什么在更大的对话框上有红叉)。
有任何帮助吗? 谢谢!
答案 0 :(得分:6)
较大的尺寸很容易解释。 Windows会根据字体自动调整对话框的大小,较大的对话框使用不同的字体。实际上,它使用的是默认的系统字体(在我的回答here中找到了关于Windows对话框字体这一令人困惑的问题的更多信息)。
所以要关注的真正问题是为什么它使用不同的字体,并修复它将解决尺寸问题。
在对话框资源文件中,将DS_SETFONT
flag指定为对话框样式之一。根据文档,这个标志
[i]指出对话框模板的标题(标准或扩展)包含指定客户区中文本和对话框控件所用字体的附加数据。如果可能,系统根据指定的字体数据选择字体。系统通过发送
WM_SETFONT
消息将字体句柄传递给对话框和每个控件。
这就解释了
下一个逻辑问题是动态创建的对话框模板有什么不同,用 一旦我们达成这种理解,解决方案应该是显而易见的:您需要告诉对话框您希望它使用哪种字体。有两种可能的方法可以让我想到: 后者可能就是你真正想要做的事情,因为它允许你使用实际的系统字体(令人困惑的是,它与我所称的不同)默认“系统字体),即Windows Vista及更高版本中的Segoe UI。请注意,即使在您的第一个屏幕截图中,它也使用了MS Sans Serif,因此在Aero界面中就像一个痛苦的拇指。再次,请参阅this answer以获取有关字体的更多信息,而不是您想知道的字体,并提供示例代码以使其工作。您需要确保为对话框本身设置和所有子控件的字体。DialogBoxIndirect
函数显示。罪魁祸首再次是DS_SETFONT
旗帜,但在这种情况下,旗帜不存在。这意味着该对话框不包含有关用于显示其控件的字体的任何信息,系统默认为默认系统字体(这是您在第二个屏幕截图中看到的丑陋的Windows 2.0时代字体)。
DS_SETFONT
标记,并在对话框模板的标题中提供字体信息,如上面链接的文档中所述。WM_INITDIALOG
消息。
答案 1 :(得分:0)
我玩过DialogBoxIndirect(实际上是DialogBoxIndirectParam),这里是设置字体的代码部分。观察DS_SHELLFONT选项。
LPWORD lpwAlign(LPWORD lpIn, int nAlignment)
{
return (LPWORD)(((ULONG_PTR)lpIn + nAlignment - 1) & -nAlignment);
}
LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner, LPMYMESSAGEPARAMS pParams)
{
WORD mem[1024]; // Buffer for dialog resource
LPDLGTEMPLATEW lpdt; // Pointer to heading resource structure
LPDLGITEMTEMPLATEW lpdit; // Pointer to current control
LPWORD lpw; // Cursor to resource buffer
LPWSTR lpwsz; // Cursor to resource buffer (of type WCHAR)
LPCWSTR lpwszCaption; // Aux pointer for text copying
LRESULT ret; // Function's return value
lpdt = (LPDLGTEMPLATEW)lpwAlign( mem, 4 );
//-----------------------
// Define a dialog box.
//-----------------------
lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION |
DS_MODALFRAME | DS_CENTER | DS_SHELLFONT;
lpdt->dwExtendedStyle = 0;
lpdt->cdit = 3; // number of controls
lpdt->x = 0; lpdt->y = 0;
lpdt->cx = 164; lpdt->cy = 49;
lpw = (LPWORD)(lpdt + 1);
// Dialog menu
*lpw++ = 0;
// Dialog class
*lpw++ = 0;
// Dialog title
for (lpwsz = (LPWSTR)lpw, lpwszCaption = L"Choose language";
*lpwsz++ = *lpwszCaption++;
);
lpw = (LPWORD)lpwsz;
// Dialog font
if ( lpdt->style & (DS_SETFONT | DS_SHELLFONT) )
{
// Size
*lpw++ = 8;
// Typeface name
for (lpwsz = (LPWSTR)lpw, lpwszCaption = L"MS Shell Dlg";
*lpwsz++ = *lpwszCaption++;
);
lpw = (LPWORD)lpwsz;
}
// Define the rest of the controls
...
ret = DialogBoxIndirectParamW( hinst, lpdt,
hwndOwner, MyMessageProc, (LPARAM)pParams );
return ret;
}
答案 2 :(得分:0)
这可以通过查找WM_INITDIALOG消息在对话框处理程序中解决,然后为对话框中的所有控件设置字体。
int CALLBACK SetChildFont(HWND child, LPARAM font) {
SendMessage(child, WM_SETFONT, font, TRUE);
return TRUE;
}
static int CALLBACK MyMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_INITDIALOG:
/* Set font for dialog and all child controls */
EnumChildWindows(hwnd, (WNDENUMPROC)SetChildFont, (LPARAM)GetStockObject(DEFAULT_GUI_FONT));
break;
}
return 0;
}