为啥我在尝试调用 CDHtmlDialog::OnInitDialog() 时看到崩溃

Posted

技术标签:

【中文标题】为啥我在尝试调用 CDHtmlDialog::OnInitDialog() 时看到崩溃【英文标题】:Why am I seeing a crash when trying to call CDHtmlDialog::OnInitDialog()为什么我在尝试调用 CDHtmlDialog::OnInitDialog() 时看到崩溃 【发布时间】:2010-04-16 19:26:11 【问题描述】:

我在我的 mfc 应用程序中添加了一个 helpAbout 菜单项。我决定让 ddlg 从 CDhtmlDialog 派生。

我在派生类中重写了 OnInitDialog() 方法,我做的第一件事是调用父类的 OnInitDialog() 方法。

然后我输入设置标题的代码。

在某些机器上这工作正常,但在其他机器上它在调用时崩溃

CDHtmlDialog::OnInitDialog() - 试图读取一个空指针。

调用堆栈没有任何用处 - 它在 mfc90.dll 中

这是 mfc/win32 dll 不匹配的潜在问题吗?

它在我的 vista 机器上工作,但在 win2003 服务器上崩溃。

BOOL HTMLAboutDlg::OnInitDialog()

   // CRASHES on the following line
    CDHtmlDialog::OnInitDialog();
    CString title = "my title";  // example of setting title

     ...        other code

    SetWindowText(title);
    return TRUE;  // return TRUE  unless you set the focus to a control

这里是相关的头文件:

class HTMLAboutDlg : public CDHtmlDialog

    DECLARE_DYNCREATE(HTMLAboutDlg)

public:
    HTMLAboutDlg(CWnd* pParent = NULL);   // standard constructor
    virtual ~HTMLAboutDlg();
// Overrides
    HRESULT OnButtonOK(IHTMLElement *pElement);
    HRESULT OnButtonCancel(IHTMLElement *pElement);

// Dialog Data
    enum  IDD = IDD_DIALOG_ABOUT, IDH = IDR_HTML_HTMLABOUTDLG ;

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    virtual BOOL OnInitDialog();

    DECLARE_MESSAGE_MAP()
    DECLARE_DHTML_EVENT_MAP()
;

我不知道发生了什么——特别是为什么它在某些机器上工作而在其他机器上崩溃。

两者都安装了 VS2008

Visual Studio 为每台机器报告以下内容:

VISTA - 没有崩溃 9.0.30729.1 SP

2003 服务器:(崩溃) 9.0.21022.8 RTM

编辑 - html 代码

<HTML>
<BODY ID=HTMLAboutDlg BGCOLOR=WHITE>

<TABLE WIDTH=100%>
<TR WIDTH=100% HEIGHT=75>
<TD ALIGN=CENTER VALIGN=TOP>
<font color="#707880">by </font><a ID=LinkCP target=_blank href='http://www.mywebsite.com'><font color="#000000">my</font><font color="#2554C7">web</font><font color="#7093DB">site</font></a>
</TD>
</TR>
<TR>
<TD ALIGN=RIGHT ALIGN=BOTTOM>
<BUTTON STYLE="WIDTH:80" ID="ButtonOK">OK</BUTTON><BR>
</TD>
</TR>
</TABLE>

</BODY>
</HTML>

【问题讨论】:

两者的服务包版本相同吗? @Peter - 向问题添加了 VS 版本信息 如果去掉“...其他代码”和 SetWindowsText() 调用,它还会崩溃吗? @Mike - 其他代码永远不会被执行。崩溃是我在评论中指出的地方。它在 CDHtmlDialog::OnInitDialog(); 我进行了搜索,但没有发现任何有用的信息可以帮助您,因此我建议尝试通过使用最简单的 HTMLAboutDlg 类创建一个新项目来隔离问题,该类仅实现 OnInitDialog() 仅此而已。如果它在所有平台上都运行良好,请有选择地从您的真实类中添加代码,直到它再次开始崩溃。 【参考方案1】:

尝试引用 HTML 中的所有 ID 属性值,并仔细检查 ID 属性是否与 DHTML_EVENT_MAP 中的引用匹配。

我猜测 IE 版本之间在 ID 属性的区分大小写或丢失 HTML 元素的处理方面存在不同的行为。最终结果可能是基础 OnInitDialog() 类无法连接到安装了特定 Internet Explorer 版本的机器上的文档对象模型中的某些元素。

鉴于history of IE,这种行为很可能潜入一个版本,然后随后被删除。

这只是一个有根据的猜测:我无法访问所有早期版本的 IE 来确认这种行为...

【讨论】:

【参考方案2】:

我认为您需要在调用基类 OnInitDialog 'CDHtmlDialog::OnInitDialog()' 之前调用 SetHostFlags。

例如。 SetHostFlags(DOCHOSTUIFLAG_FLAT_SCROLLBAR); //根据需要设置主机 UI 标志。

一般信息:CDHtmlDialog 在“afxdhtml.h”中声明。 (我相信你会知道的)

由于 DHtmlDialog 内部处理 COM,请尝试使用

CoInitialize();//at the begining of application launch

CoUninitialize();//at the exit of app.

【讨论】:

谢谢,我会试试的。你能解释为什么它在一台机器上工作(原样)而不是另一台机器【参考方案3】:

这可能是由于试图引用一个不存在的 html 文件引起的。确保您传递给基类构造函数的 IDH 枚举有效并且实际上引用了现有的 HTML 页面。

HTMLAboutDlg::HTMLAboutDlg(Cwnd *pParent) 
    : CDHTMLDialog(HTMLAboutDlg::IDD, HTMLAboutDlg::IDH, pParent)

因此,请检查您的 IDR_HTML_HTMLABOUTDLG 值是否实际分配了正确的 HTML 页面。

如果您使用向导创建了对话框,我认为它会为您生成一个名称为“MyProjectName.htm”的页面,通常会为其分配 IDR_HTML_HTMLABOUTDLG 值。

你的资源 .rc 文件应该有点像:

IDR_HTML_MYPROJECT_DIALOG HTML                    "MyProjectName.htm"

您的 HTMLDialogs OnDocumentComplete 方法是否在 OnInitDialog 之前被调用?当我稍微琢磨一下时,这发生在我身上,由于我在其他地方进行了一些错误的错误检查,导致程序崩溃。

如果这没有帮助,您能否发布堆栈跟踪,或者可能是 cpp、h、html 和 .rc 文件。

【讨论】:

谢谢。 exe和资源完全相同。我将检查 ondoccomplete 调用。问题是它只能在一个平台上运行,而不能在另一个平台上运行。相同的源代码。【参考方案4】:

我有一个类似的问题,我通过添加 ::AfxOleInit(); 解决了这个问题。靠近 CMyApp::InitInstance() 函数的顶部。如果在创建窗口之前没有调用它,它将使整个应用程序崩溃。下面是我的 InitInstance 函数的开始部分现在的样子:

BOOL CMyApp::InitInstance()

    // InitCommonControls() is required on Windows XP if an application
    // manifest specifies use of ComCtl32.dll version 6 or later to enable
    // visual styles.  Otherwise, any window creation will fail.
    InitCommonControls();
    CWinApp::InitInstance();

    ::AfxOleInit();

...

【讨论】:

以上是关于为啥我在尝试调用 CDHtmlDialog::OnInitDialog() 时看到崩溃的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 Django 中使用此调用从 Paypal 收到“内部错误”?

为啥我在 swift 中调用 getIndex(cell: TableViewCell1) 函数时出错?

为什么对话框会在不刷新的情况下删除其内容

为啥当我在 grails 上删除一对多关系上的父级时,会在子级上调用 beforeInsert 事件?

为啥我在尝试设置 PayPal 付款时在生产中不断收到 INVALID_RESOURCE_ID 错误?

为啥在更新事务期间休眠调用删除?