CWnd::CreateDlgIndirect 离开 m_hWnd==NULL

2022-01-12 00:00:00 winapi c++ mfc

我正在处理的对话框没有显示,使用:

A dialog I'm working on isn't displaying, using:

CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate,CWnd* pParentWnd, HINSTANCE hInst)

对 CreateDlgIndirect 的调用在一个 lon-used 基类中,它有效地获取资源文件中对话框模板的 IDD - 它适用于许多其他对话框,但我看不出我的对话框有什么不同.当以更正常的方式创建对话框时,我的对话框可以正常工作,但我必须使用基类,因为它内置了许多其他功能.

The call to CreateDlgIndirect is in a lon-used base-class, which effectively takes the IDD of the dialog template in the resource file - it works fine for many other dialogs but I can't see what's different in my dialog. My dialog works fine when created in a more normal way, but I have to use the base class as it has loads of other functionality built in.

当我在 dlgcore.cpp 中浏览 CWnd::CreateDlgIndirect 时发现,普通的 Win32 API 调用失败了:

What I find when trawling through CWnd::CreateDlgIndirect in dlgcore.cpp, is that the plain Win32 API call is failing:

hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,pParentWnd->GetSafeHwnd(), AfxDlgProc);

由于某种原因,我无法进入该函数,所以我看到的只是 HWND 为 NULL.

I can't step into that function for some reason, so all I see is the HWND is NULL.

任何人都可以提出可能导致这种情况的问题吗?我对比了两个对话框资源模板,属性是一样的.

Can anyone suggest what kind of problems might be causing this? I compared the two dialog resource templates and their properties are the same.

我在对话框上有一个自定义控件.当我删除它时,它可以工作.不知道为什么,这会有什么不同?

edit: I have one custom control on the dialog. When I remove this, it works. No idea why, what difference might this make?

推荐答案

CreateDialogXXX 失败的一种比较隐晦的方式是对话框上的子控件创建失败.通常是因为应用程序在尝试创建对话框之前尚未初始化公共控件库.请参阅 InitCommonControlsEx

One of the more obscure ways for CreateDialogXXX to fail is for a child control on the dialog to fail creation. Usually because the application has not initialized the common controls library before attempting to effect the dialog creation. See InitCommonControlsEx

检查这一点的一种方法是在资源编辑器中打开对话框,转到对话框的属性,然后找到并打开 DS_NOFAILCREATE 标志.通常称为No Fail Create"之类的晦涩难懂的东西.或者将 DS_NOFAILCREATE 直接添加到内存中的对话框模板中.这将允许显示对话框,而罪魁祸首应该是没有出现的.

One way to check this is to open the dialog in the resource editor, go to the dialog's properties, and find and turn on the DS_NOFAILCREATE flag. Usually called something obscure like "No Fail Create". Or add the DS_NOFAILCREATE directly to your dialog template in memory. This will allow the dialog to show, and the culprit should be evident by its absence.

如果子控件是实际的自定义控件 - 自定义窗口类要么未正确注册,要么根本没有注册.检查注册中使用的 HINSTANCE - 除非指定 CS_GLOBAL 标志,否则窗口类由 (hInstance, ClassName) 标识 - 这可以防止在不同 dll 中使用相同名称的窗口类发生冲突.

In the case that the child control is an actual custom control - well the custom window class is either not registered correctly, or at all. Check the HINSTANCE used in registration - unless the CS_GLOBAL flag is specified, window classes are identified by (hInstance, ClassName) - this prevents window classes using the same name in different dlls conflicting.

相关文章