【问题标题】:Disable editable WebBrowser control's save dialog C#禁用可编辑的 WebBrowser 控件的保存对话框 C#
【发布时间】:2016-12-23 18:22:36
【问题描述】:

希望大家能帮帮我。

我有一个用 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 文件之前)都会出现一个保存对话框(标记为 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 控件并保存它的解决方案,因此当它被检查时它不会触发“保存”对话框,但我还没有弄清楚如何做到这一点。

我期待您的所有答案,请随时提出任何问题。

谢谢, 艾美特

【问题讨论】:

    标签: c# html webbrowser-control


    【解决方案1】:

    你可以用这个

    WebBrowser1.Document.ExecCommand(“刷新”, False, “”)

    在这个http://www.spheregen.com/disable-save-dialog-in-webbrowser-editing/找到

    希望为你工作

    【讨论】:

      【解决方案2】:

      我最近遇到了这个问题,但从未像描述的那样使用 Document.ExecCommand("Refresh") 成功。

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

      所以回答:Setting up Hook on Windows messages 有助于设置一切,但它的一般要点是获取对话框类 (#32770),然后确保对话框的标题包含我的临时文件名,然后获取该对话框的句柄并将其发送到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 传递给 @ 987654344@ 函数并遍历返回的IntPtr 对象列表,在每个项目上调用GetWindowText(),直到找到与“&amp;Yes”(对于“是”按钮)、“&amp;No”(对于无按钮)或“Cancel”(用于取消按钮)。

      获得按钮句柄后,向其发送BM_CLICK 消息 (0x00F5),您可以在不丢失功能的情况下抑制对话框。

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

      代码更改如下:

      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);
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-06
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        • 2012-11-10
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多