使用运行时创建的模板的对话框在XP 32位上不起作用

时间:2012-02-08 09:11:06

标签: c++ winapi dialog

我编写了一个运行时创建的对话框类,它不使用基于此示例的任何资源文件: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位部分是罪魁祸首。

一些有趣但奇怪的事情:

  • 使用普通资源在同一程序中的对话框在Win 7和Win XP中都能正常工作。
  • 当逐字节比较运行时创建的对话框模板时,我发现与资源构造的对话框没有区别。
  • 只要我没有在对话框中添加任何控件,它就会显示在XP中,但如果我添加的内容与单个静态不同,那么它就不会。
  • 我监视了回调函数,当它启动时,它发送WM_SETFONT,WM_DESTROY,WM_NCDESTROY然后死掉。就像它放弃了WM_SETFONT和WM_CREATE之间的某个地方。

我发现其他人有类似的问题,但没有一个与我的完全一样:http://social.msdn.microsoft.com/Forums/zh/vcgeneral/thread/45989a10-2785-486d-94ae-4f1f3e1ca651http://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);
}

哇,如果它被标签缩进,那么粘贴代码会非常烦人: - /

2 个答案:

答案 0 :(得分:0)

代码看起来是正确的,但它没有显示生成的模板,它无法实例化。

我发现奇怪的一件事是:

m_data.Write<DWORD>(dwType);    // control type (as DWORD)

这听起来不对,you need 0xFFFF in front if it

  

如果第一个元素是0xFFFF,则该数组有一个额外的元素   指定预定义系统类的序数值。该   序数可以是以下原子值之一。

答案 1 :(得分:0)

在Win32下,我认为对话框模板结构需要字节对齐。