我编写了一个运行时创建的对话框类,它不使用基于此示例的任何资源文件:http://blogs.msdn.com/b/oldnewthing/archive/2005/04/29/412577.aspx
它是在Windows 7 x64计算机上编译的,但是作为x86应用程序。该对话框是较大程序的一部分,在其他地方使用与资源文件(MFC)的普通对话框。
对话框由DialogBoxIndirectParam启动,如下所示:
DialogBoxIndirectParam(NULL, m_template.GetTemplate(), NULL, DlgProc, reinterpret_cast<LPARAM>(this));
对话框在我尝试的所有Windows 7 x64计算机上都显示正常,但它在Windows XP x86计算机上不起作用。我不知道它是Windows版本还是CPU位部分是罪魁祸首。
一些有趣但奇怪的事情:
我发现其他人有类似的问题,但没有一个与我的完全一样:http://social.msdn.microsoft.com/Forums/zh/vcgeneral/thread/45989a10-2785-486d-94ae-4f1f3e1ca651,http://cboard.cprogramming.com/windows-programming/39218-createdialog-failure.html
我必须说我对此有所了解,我在win32编程方面还不够好,无法弄清楚这里究竟出现了什么问题。
这是模板代码的样子:
DialogTemplate::DialogTemplate(const std::wstring& title, WORD width, WORD height) :
m_numControls(0)
{
AddHeader(title, width, height);
AddFont();
}
DialogTemplate::~DialogTemplate(void)
{
}
void DialogTemplate::AddHeader(const std::wstring& title, WORD width, WORD height)
{
// Write out the extended dialog template header
m_data.Write<WORD>(1); // dialog version
m_data.Write<WORD>(0xFFFF); // extended dialog template
m_data.Write<DWORD>(0); // help ID
m_data.Write<DWORD>(0); // extended style
m_data.Write<DWORD>(WS_CAPTION | WS_SYSMENU | DS_SETFONT | DS_MODALFRAME);
m_data.Write<WORD>(0); // number of controls (placeholder)
m_data.Write<WORD>(32); // X
m_data.Write<WORD>(32); // Y
m_data.Write<WORD>(width); // width
m_data.Write<WORD>(height); // height
m_data.WriteString(L""); // no menu
m_data.WriteString(L""); // default dialog class
m_data.WriteString(title.c_str()); // title
}
bool DialogTemplate::AddFont()
{
// Write out font
HDC hdc = GetDC(NULL);
if (!hdc)
return false;
NONCLIENTMETRICSW ncm = { sizeof(ncm) };
if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0))
return false;
if (ncm.lfMessageFont.lfHeight < 0)
ncm.lfMessageFont.lfHeight = -MulDiv(ncm.lfMessageFont.lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
m_data.Write<WORD>((WORD)ncm.lfMessageFont.lfHeight); // point
m_data.Write<WORD>((WORD)ncm.lfMessageFont.lfWeight); // weight
m_data.Write<BYTE>(ncm.lfMessageFont.lfItalic); // Italic
m_data.Write<BYTE>(ncm.lfMessageFont.lfCharSet); // CharSet
m_data.WriteString(ncm.lfMessageFont.lfFaceName);
return true;
}
void DialogTemplate::AddControl(LPCWSTR pszType, WORD x, WORD y, WORD width, WORD height, const std::wstring& text, DWORD controlId, DWORD style)
{
m_data.AlignToDword();
m_data.Write<DWORD>(0); // help id
m_data.Write<DWORD>(0); // window extended style
m_data.Write<DWORD>(WS_CHILD | style); // style
m_data.Write<WORD>(x); // x
m_data.Write<WORD>(y); // y
m_data.Write<WORD>(width); // width
m_data.Write<WORD>(height); // height
m_data.Write<DWORD>(controlId); // control ID
m_data.WriteString(pszType); // control type (as string)
m_data.WriteString(text.c_str()); // text
m_data.Write<WORD>(0); // no extra data
++m_numControls;
m_data.Overwrite<WORD>(m_numControls, NUM_CTRL_OFFS);
}
void DialogTemplate::AddControl(DWORD dwType, WORD x, WORD y, WORD width, WORD height, const std::wstring& text, DWORD controlId, DWORD style)
{
m_data.AlignToDword();
m_data.Write<DWORD>(0); // help id
m_data.Write<DWORD>(0); // window extended style
m_data.Write<DWORD>(WS_CHILD | style); // style
m_data.Write<WORD>(x); // x
m_data.Write<WORD>(y); // y
m_data.Write<WORD>(width); // width
m_data.Write<WORD>(height); // height
m_data.Write<DWORD>(controlId); // control ID
m_data.Write<DWORD>(dwType); // control type (as DWORD)
m_data.WriteString(text.c_str()); // text
m_data.Write<WORD>(0); // no extra data
++m_numControls;
m_data.Overwrite<WORD>(m_numControls, NUM_CTRL_OFFS);
}
哇,如果它被标签缩进,那么粘贴代码会非常烦人: - /
答案 0 :(得分:0)
代码看起来是正确的,但它没有显示生成的模板,它无法实例化。
我发现奇怪的一件事是:
m_data.Write<DWORD>(dwType); // control type (as DWORD)
这听起来不对,you need 0xFFFF
in front if it:
如果第一个元素是0xFFFF,则该数组有一个额外的元素 指定预定义系统类的序数值。该 序数可以是以下原子值之一。
答案 1 :(得分:0)
在Win32下,我认为对话框模板结构需要字节对齐。