为啥我在尝试调用 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 事件?