CWnd :: CreateDlgIndirect离开m_hWnd == NULL

时间:2009-11-03 12:04:14

标签: c++ winapi mfc

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

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

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

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

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

我出于某种原因无法进入该功能,所以我看到的是HWND为NULL。

有人能说出造成这种问题的原因是什么?我比较了两个对话框资源模板,它们的属性是相同的。

编辑:我在对话框上有一个自定义控件。当我删除它,它的工作原理。不知道为什么,这会有什么不同?

3 个答案:

答案 0 :(得分:9)

CreateDialogXXX失败的一个比较模糊的方法是让对话框上的子控件创建失败。通常是因为在尝试实现对话框创建之前,应用程序尚未初始化公共控件库。见InitCommonControlsEx

检查此方法的一种方法是在资源编辑器中打开对话框,转到对话框的属性,然后查找并打开DS_NOFAILCREATE标志。通常被称为“No Fail Create”之类的东西。或者将DS_NOFAILCREATE直接添加到内存中的对话框模板中。这将允许对话框显示,并且罪魁祸首应该因缺席而显而易见。

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

答案 1 :(得分:2)

我发现了问题。请参阅我对this question

的回答

答案 2 :(得分:0)

如果使用错误的HINSTANCE,则自定义CWnd派生的控件将失败。当使用卫星DLL作为语言资源时,这是我必须更改的内容:

// ----------------------------------------- //
// RegisterWndClass
// ----------------------------------------- //
/*static*/ BOOL MyCtrl::RegisterWndClass() {
    WNDCLASS windowclass = {0};
    // !! THIS IS THE IMPORTANT PART: !!
    HINSTANCE hInst = AfxGetResourceHandle(); // NOT AfxGetInstanceHandle();
    if(!(::GetClassInfo(hInst, MYCTRL_CLASSNAME, &windowclass))) {
        //If not then we have to register the new class
        windowclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        windowclass.lpfnWndProc = ::DefWindowProc;
        windowclass.cbClsExtra = windowclass.cbWndExtra = 0;
        windowclass.hInstance = hInst;
        windowclass.hIcon = NULL;
        windowclass.hCursor = AfxGetApp()->LoadStandardCursor(IDC_IBEAM);
        windowclass.hbrBackground = ::GetSysColorBrush(COLOR_WINDOW);
        windowclass.lpszMenuName = NULL;
        windowclass.lpszClassName = MYCTRL_CLASSNAME;

        if(!AfxRegisterClass(&windowclass)) {
            AfxThrowResourceException();
            return FALSE;
        }
    }
    return TRUE;
}