禁用可编辑的WebBrowser控件的保存对话框C#

时间:2013-11-16 10:02:17

标签: c# html webbrowser-control

我希望你们能在这里帮助我。

我有一个用C#编写的应用程序,它使用WebBrowser控件编辑HTML文件(在屏幕截图上用2标记),这里是初始化它的代码:

    htmlEditor.DocumentText = "";
    doc = htmlEditor.Document.DomDocument as IHTMLDocument2;
    doc.designMode = "On";
    htmlEditor.Url = new Uri(Properties.Main.Default.tempDir + "\\section-1.html");

我还有一个listview控件,它显示了HTML文件列表(在屏幕截图中标记为1)。每次用户单击列表项时,都会触发一个事件,webbrowser控件会加载一个不同的HTML文件,这里是代码:

    private void sectionsTree_SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
    {
        Sections.fileCheck();

        if (sectionsTree.SelectedNode != null)
        {
            emDataSet.dtSectionsDataTable sectionsDT = new emDataSet.dtSectionsDataTable();
            sectionsDT.ReadXml(Properties.Main.Default.tempDir + "\\sections.xml");

            for (int i = 0; i < sectionsDT.Rows.Count; i++)
            {
                if (sectionsTree.SelectedNode.Text == sectionsDT.Rows[i][2].ToString())
                {
                    htmlEditor.Url = new Uri(Properties.Main.Default.tempDir + "\\" + sectionsDT.Rows[i][1].ToString());
                }
            }
        }
    }

现在我的问题出现了:因为webbrowser控件中加载的HTML页面是可编辑的,每次我在列表中选择一个新项目时(在加载新的HTML文件之前),都会出现一个Save对话框(标记为3 on截图)。我有自己的代码来保存由“更改”事件触发的已更改的HTML文件,如果有某种方法可以绕过,禁止,跳过或只是隐藏此“保存”对话框,那将是很好的,因此用户赢了每次他想要转到另一个文件时都需要点击它。这是变化的事件:

    private void sectionsTree_SelectedNodeChanging(object sender, RadTreeViewCancelEventArgs e)
    {
        Sections.fileCheck();

        if (sectionsTree.SelectedNode != null)
        {
            emDataSet.dtSectionsDataTable sectionsDT = new emDataSet.dtSectionsDataTable();
            sectionsDT.ReadXml(Properties.Main.Default.tempDir + "\\sections.xml");

            for (int i = 0; i < sectionsDT.Rows.Count; i++)
            {
                if (sectionsTree.SelectedNode.Text == sectionsDT.Rows[i][2].ToString())
                {
                    File.WriteAllText(Properties.Main.Default.tempDir + "\\" + sectionsDT.Rows[i][1].ToString(), htmlEditor.DocumentText);
                }
            }
        }
    }

我的观点是上面的代码没问题,与我的问题无关,因为我的理解是问题来自WebBrowser控件的内置功能,但是,也许,它可能是在检查文件是否已更改之前拦截WebBrowser控件的解决方案,并将其保存,因此在检查时它不会触发“保存”对话框,但我还没弄清楚如何执行此操作。 / p>

enter image description here

我期待着你的所有答案,随时可以提出任何问题。

谢谢, Aemeth

2 个答案:

答案 0 :(得分:0)

你可以使用这个

WebBrowser1.Document.ExecCommand(“Refresh”,False,“”)

在此http://www.spheregen.com/disable-save-dialog-in-webbrowser-editing/

处找到

希望为你工作

答案 1 :(得分:0)

我最近遇到过这种情况,并且从未使用所述的Document.ExecCommand("Refresh")成功。

对我有用的是使用Windows API调用将WM_CLOSE消息发送到对话框,允许我禁止对话但仍然在后台处理文件保存/重新加载。

回答:Setting up Hook on Windows messages有助于设置所有内容,但它的一般要点是获取对话框类(#32770),然后确保对话框的标题包含我的临时filename,然后获取该对话框的句柄并发送它WM_CLOSE

SetWinEventHook的委托函数正文如下,希望这有一些帮助。

GetClassName(hWnd, ClassName, ClassName.Capacity);
GetWindowText(hWnd, DialogTitle, DialogTitle.Capacity);
DialogHandle = FindWindow(DIALOG_CLASS, DialogTitle.ToString());

if (ClassName.ToString() == DIALOG_CLASS && DialogTitle.ToString().Contains(TempFilename))
{
     ReturnValue = SendMessage(DialogHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}

ClassNameDialogTitle属于StringBuilder类型,ReturnValueDialogHandle属于IntPtr类型。 TempFilename是一个包含由Path.GetTempFileName()

生成的临时文件名的字符串

您需要对SetWinEventHookUnhookWinEventGetClassNameGetWindowTextFindWindowSendMessage进行API调用 - PInvoke.net应该能够帮助那些。你还需要设置一些常量--PInvoke可以提供帮助。

这不是最优雅的解决方案,但它确实有效!

编辑添加 - 如果您想要实际与对话框进行交互,而不是随意关闭它,您可以使用PInvoke中的代码:http://www.pinvoke.net/default.aspx/user32.enumchildwindows然后在代码中传递DialogHandle上面的GetChildWindows()函数并遍历返回的IntPtr对象列表,在每个项目上调用GetWindowText(),直到找到与“&Yes”匹配的值(对于是按钮),“&No”(对于“否”按钮)或“Cancel”(对于取消按钮)。

获得按钮的句柄后,向其发送BM_CLICK消息(0x00F5),您可以取消对话而不会失去其功能。

由于您只是遍历目标对话框而不是每个窗口,这是一个非常快速的操作(测试时需要2ms),所以不应该导致任何减速。

代码更改为以下内容:

GetClassName(hWnd, ClassName, ClassName.Capacity);
GetWindowText(hWnd, DialogTitle, DialogTitle.Capacity);
DialogHandle = FindWindow(DIALOG_CLASS, DialogTitle.ToString());

if (ClassName.ToString() == DIALOG_CLASS && DialogTitle.ToString().Contains(TempFilename))
{
    foreach (IntPtr ChildWindow in GetChildWindows(hWnd))
    {
        StringBuilder ChildCaption = new StringBuilder(100);
        GetWindowText(ChildWindow, ChildCaption, ChildCaption.Capacity);
        if (ChildCaption.ToString() == @"&Yes")
        {
            SendMessage(ChildWindow, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
        }
    }
}