【发布时间】:2018-07-17 07:33:48
【问题描述】:
我构建了一个名为EditableWebBrowser 的Winforms WebBrowser 类的非常简单的扩展,它运行良好,除非实例化从使用它的设计器代码中随机删除。启动应用程序时,我似乎也偶尔会出现一些挂起行为。除了两件事之外,没有什么特别的(自定义部分主要是字符串操作):
- 它使用 SHDocVw 引用来访问 IHTMLDocument2 对象。
- 它使用 MSHTML 高级接口来执行保存例程而不提示用户(使用 ExecWB 调用)。
但是,在构造函数中既没有使用 SHDocVw 也没有使用 MSHTML 接口,并且在发生冻结时不会调用它们。
控件如下所示:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
using SHDocVw;
using mshtml;
namespace WindowsFormsApp1.UserControls
{
public partial class EditableWebBrowser : System.Windows.Forms.WebBrowser
{
public string TempFile = "";
public string TempFileURL { get { return "file:///" + TempFile.Replace('\\', '/'); } }
// Private base constructor - we always want the parameterized public constructor
private EditableWebBrowser()
{
InitializeComponent();
}
public EditableWebBrowser(bool editableOnDocumentCompleted = true, string localFile = "tmpEditableWebBrowser.html") : this()
{
// Set temp file
this.TempFile = Path.GetTempPath() + localFile;
// Make the loaded document editable?
if(editableOnDocumentCompleted)
{
this.DocumentCompleted += WebBrowser1_DocumentCompleted;
}
}
// Handler for making the loaded document editable
private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
IHTMLDocument2 doc = (IHTMLDocument2)this.Document.DomDocument;
doc.designMode = "On";
}
// Some Regex objects and some custom methods here
private string _cleanupImportedHTML(string HTML)
{
...
}
public void Import(string HTML = null)
{
...
}
public void Clear()
{
...
}
public void SaveWithoutPrompt()
{
// Execute the browser's "Save" command without prompting
object inVal = "";
object outVal = "";
((IWebBrowser2)this.ActiveXInstance).ExecWB(SHDocVw.OLECMDID.OLECMDID_SAVE, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref inVal, ref outVal);
}
}
}
在使用它的表单的设计器(frmMain.Designer.cs)中,它很简单:
this.ewbContentEditor = new UserControls.EditableWebBrowser();
这条线偶尔会被删除,没有任何明显的模式。但是,引用它的其余设计器代码仍然保留,这显然破坏了引用它的其余设计器代码:
//
// ewbContentEditor
//
this.ewbContentEditor.Dock = System.Windows.Forms.DockStyle.Fill;
this.ewbContentEditor.Location = new System.Drawing.Point(3, 3);
this.ewbContentEditor.MinimumSize = new System.Drawing.Size(20, 20);
this.ewbContentEditor.Name = "ewbContentEditor";
this.ewbContentEditor.Size = new System.Drawing.Size(599, 375);
this.ewbContentEditor.TabIndex = 3;
我想知道这个问题是否与公共构造函数的默认参数订阅 DocumentCompleted 事件这一事实有关,但这是我目前唯一的想法,我不知道有什么方法可以肯定确认这个理论(没有明确的模式,我不想只是尝试一些东西,如果它不会很快崩溃就假设它是固定的)。
其他人有任何想法或看到问题吗?
此外,MSHTML 接口是使用本文中描述的方法实现的: https://www.codeproject.com/Articles/2491/Using-MSHTML-Advanced-Hosting-Interfaces
【问题讨论】: