使用运行时创建的模板的对话框在 XP 32 位上不起作用
Dialog using runtime-created template doesn't work on XP 32 bit
我编写了一个运行时创建的对话框类,该类不使用任何基于此示例的资源文件: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部分才是罪魁祸首。
一些有趣但奇怪的事情:
- 同一程序中使用普通资源的对话框在Win7和WinXP中都能正常工作
- 当逐字节比较运行时创建的对话框模板时,我看不出与资源构建的对话框有什么不同
- 只要我不在对话框中添加任何控件,它就会在XP中显示,但如果我添加了一个静态控件,它就不会了
- 我已经监视了回调函数,当它启动时,它会发送WM_SETFONT、WM_DESTROY、WM_NCDESTROY,然后终止。就好像它在WM_SETFONT和WM_CREATE之间放弃了一样
我发现其他人也有类似的问题,但没有一个和我的问题完全一样: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);
}
哇,如果代码按制表符缩进,粘贴到这里会非常烦人:-/
代码看起来大致正确,但它没有显示生成的模板,该模板无法实例化。
我注意到一件奇怪的事:
m_data.Write<DWORD>(dwType); // control type (as DWORD)
这听起来不对,如果是,你需要0xFFFF
在前面
如果第一个元素是0xFFFF,则该数组具有一个附加元素其指定预定义系统类的序数值。这个序数可以是以下原子值之一。
在Win32下,我认为对话框模板结构需要字节对齐。
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- Qt C++在Win XP SP1上不起作用
- Visual C 2012 Express Compied Application在Windows XP上不起作用
- 注入dll在windows XP上不起作用
- 在Windows 7下编译的Dll在Windows XP中不起作用
- 使用运行时创建的模板的对话框在 XP 32 位上不起作用
- 我的代码在 Windows XP 上不起作用