VC++ 创建 Cdialog 类断言错误

Posted

技术标签:

【中文标题】VC++ 创建 Cdialog 类断言错误【英文标题】:VC++ create Cdialog Class Assertion error 【发布时间】:2015-08-19 16:01:59 【问题描述】:

我完全是 Visual Studio 的菜鸟,这可能是一个愚蠢的错误。

我只是想实例化一个 Cdialog 类,我正在制作一个 dll,最终需要在 Window 中有一些 activeX 命令。

我尝试了几种实例化方法,但总是遇到断言错误。

所以在我的 calldllclass.h 中我有:

#pragma once
__declspec(dllexport) long init();

在我的扩展 Cdialog 的类中:

//AFX_INCLUDES()
//AFX_INCLUDES

class CMyclass: public CDialog

#include "resource.h"

public:
    CMyclass(CWnd* pParent = NULL)
    : CDialog(100, pParent)
        //AFX_DATA_INIT(CMyclass)
        //AFX_DATA_INIT   
    ;  // standard constructor
    virtual ~CMyclass();
    long calc();
// Dialog Data
    //AFX_DATA(CMyclass)
    //AFX_DATA

    // ClassWizard generated virtual function overrides
    //AFX_VIRTUAL(CMyclass)
    protected:
    //AFX_VIRTUAL

protected:
    // Generated message map functions
    //AFX_MSG(CMyclass)
    //AFX_MSG
    DECLARE_MESSAGE_MAP()   

;
//AFX_INSERT_LOCATION

我创建了一个资源类:

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE MOVEABLE PURE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE MOVEABLE PURE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE MOVEABLE PURE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "#ifdef _WIN32\r\n"
    "LANGUAGE 9, 1\r\n"
    "#pragma code_page(1252)\r\n"
    "#endif //_WIN32\r\n"
    "#include ""res\\SimpleVC6SampleEvent.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
    "#include ""afxres.rc""         // Standard components\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED




/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOG DISCARDABLE  0, 0, 0, 0
STYLE DS_MODALFRAME
FONT 8, "MS Sans Serif"
BEGIN
END




#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////

最后在我的 cpp 中我有:

// SIMPLEDIALOGDLL.cpp : Defines the exported functions for the DLL application.
//
#pragma once
#include "stdafx.h"
#include "myclass.h"
#include "resource.h"
#include "dll2export.h"


BEGIN_MESSAGE_MAP(CMyclass, CDialog)
    //AFX_MSG_MAP(CMyclass)
    //AFX_MSG
END_MESSAGE_MAP()


long init()  

    AfxEnableControlContainer();
    CoInitializeEx(NULL,COINIT_MULTITHREADED);
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    CMyclass * obj = new CMyclass();

    //obj->ShowWindow(SW_HIDE);
    obj->ShowWindow(SW_SHOW);

    long res = obj->calc();
    return (long) obj;


long CMyclass::calc()
    return 1+1;

当 obj->ShowWindow(SW_SHOW);被称为我得到一个 调试断言失败! winocc.cpp 第 329 行

BOOL CWnd::ShowWindow(int nCmdShow)

    ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

    if (m_pCtrlSite == NULL)
        return ::ShowWindow(m_hWnd, nCmdShow);
    else
        return m_pCtrlSite->ShowWindow(nCmdShow);

我在 showWindow 之后做了一点更新,它返回 1400

   DWORD dw = GetLastError();

添加答案建议 我有这个来初始化方法

AfxEnableControlContainer();
CoInitializeEx(NULL,COINIT_MULTITHREADED);
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

CMyclass *obj = new CMyclass();

if(obj->Create(100))
    obj->ShowWindow(SW_HIDE);
    DWORD dw = GetLastError();
else
    DWORD dw = GetLastError();

现在我在 obj->Create(100)); objcore.cpp 行:40

【问题讨论】:

我在任何地方都没有看到对CDialog::Create 的呼叫。您需要先创建一个对话框,然后才能显示它。 这还不够吗? CMyclass(CWnd* pParent = NULL) : CDialog(100, pParent) @RoyBean 创建 CDialog 对象但不创建窗口。您必须调用 Create 来创建无模式对话窗口。 @ScottMcP-MVP 我添加了 CMyclass(CWnd* pParent = NULL) : CDialog(100,pParent) //AFX_DATA_INIT(CMyclass) //AFX_DATA_INIT CDialog::Create(100,父);导致断言也失败 这可能是因为对话框模板“100”不存在。我建议你阅读一些关于 MFC 的“入门”教程。 【参考方案1】:

@ScottMcP-MVP 是对的,无模式对话框需要调用Create method。

另外,根据MSDN docs on the constructor,

要构造一个无模式对话框,使用受保护的形式 CDialog 构造函数。构造函数受到保护,因为您必须 派生您自己的对话框类来实现无模式对话框。 构建无模式对话框是一个两步过程。第一的 调用构造函数;然后调用 Create 成员函数创建一个 基于资源的对话框...

所以像CMyclass() : CDialog() ...这样声明你的类并使用下面的代码来显示它:

CMyclass * obj = new CMyclass();
if (obj->Create(100))
    obj->ShowWindow(SW_SHOW);
else
 << error >>

P.S.:别忘了在程序结束时删除变量!

【讨论】:

我有这个来初始化方法 AfxEnableControlContainer(); CoInitializeEx(NULL,COINIT_MULTITHREADED); AFX_MANAGE_STATE(AfxGetStaticModuleState()); CMyclass *obj = new CMyclass(); if(obj->Create(100)) obj->ShowWindow(SW_HIDE); DWORD dw = GetLastError(); else DWORD dw = GetLastError();现在我在 obj->Create(100)); objcore.cpp 行:40 你能检查obj是否为NULL吗?如果记录 ID #100 不在您的资源文件中,则可能会发生这种情况——我注意到您已将对话框声明为 IDD_ABOUTBOX,该符号 #defined 是否为 100?最好添加对obj == NULL 的检查并将下一行更改为if (obj-&gt;Create(IDD_ABOUTBOX))【参考方案2】:

我的代码是对的,

很多小时后,我去更改 Visual Studio 的编译器选项,并在调试信息格式中放入 Program Database (/Zi)

帮我解决这个问题

【讨论】:

不要将其称为解决方案,除非您知道为什么会这样。 大声笑,这对我有用,如果任何 Visual Studio VC++ 专家知道解释,我会喜欢听的,我提出问题并解决了我的问题,如果你不接受,不是我的问题。 您的代码错误。你有一个错误。您未能诊断出断言失败的原因,并且只是尝试了随机的事情,直到其中一个使应用程序看起来可以工作。纯属巧合。我将此答案标记为 “不是答案” 随心所欲,所以现在更改程序设置不是一个有效的解决方案,哈哈! 不分析错误绝对不是一个有效的解决方案。断言失败,因为m_hWnd 不是有效的窗口句柄,或者m_pCtrlSitenullptr。为什么?随机更改编译器设置只会掩盖错误。掩盖错误不被视为任何给定编程问题的有效解决方案。

以上是关于VC++ 创建 Cdialog 类断言错误的主要内容,如果未能解决你的问题,请参考以下文章

编译时间错误C4407

★VC-MFC◆CToolbarCtrl && CDialog 下拉菜单 ★

Visual C++ 6.0 - 派生的 CDialog 类中的 OnInitDialog 不起作用

拦截 CDialog 创建

CDialog 类的父子实现

当 CDialog.DoModal() 函数无法创建对话框时?