简体   繁体   English

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

[英]Disable editable WebBrowser control's save dialog C#

I hope you guys can help me out here. 我希望你们能在这里帮助我。

I have an application written in C#, that uses a WebBrowser control to edit HTML files (marked with 2 on the screenshot), and here's the code that initializes it: 我有一个用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");

I also have a listview control, that shows the list of HTML files(marked with 1 on the screenshot). 我还有一个listview控件,它显示HTML文件列表(在屏幕截图上标记为1)。 Each time the user clicks on a list item, an event is triggered and the webbrowser control loads a different HTML file, and here's the code for that: 每次用户单击列表项时,都会触发一个事件,并且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());
                }
            }
        }
    }

Now here comes my problem: because the HTML page loaded in the webbrowser control is editable, each time I select a new item on the list (and before a new HTML file is loaded) a Save dialog appears (marked with 3 on the screenshot). 现在出现了我的问题:因为在webbrowser控件中加载的HTML页面是可编辑的,所以每次我在列表中选择一个新项目时(并且在加载新的HTML文件之前),都会出现一个“保存”对话框(在屏幕快照中标记为3) 。 I have my own code to save the changed HTML file, triggered by the "changing" event and it would be great if there would be somehow a solution to bypass, suppress, skip, or just simply hide this Save dialog, so the user won't need to click it every time he wants to go to another file. 我有自己的代码来保存由“ changing”事件触发的更改的HTML文件,如果能够以某种方式绕过,抑制,跳过或仅隐藏此“保存”对话框的解决方案,那将是非常不错的,因此用户赢得了每次他想转到另一个文件时都不需要单击它。 Here's the changing event: 这是不断变化的事件:

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

My opinion is that the above codes are okay, and have nothing to do with my problem, because, my understanding is that the problem comes from a built-in feature of the WebBrowser control, however, just maybe, it could be a solution to intercept the WebBrowser control just before it checks if the file has been changed or not, and save it, so when it's checked it won't trigger the Save dialog, but I haven't figured out how to do that. 我的意见是上述代码尚可,并且与我的问题无关,因为我的理解是问题来自WebBrowser控件的内置功能,但是,也许它可以解决在检查文件是否已更改之前就拦截WebBrowser控件并保存它,因此当选中它时,它不会触发“保存”对话框,但是我还没有弄清楚该怎么做。

在此处输入图片说明

I'm looking forward to all your answers, and feel free to ask anything. 我期待您的所有答复,并随时提出任何问题。

Thanks, Aemeth 谢谢爱美

you may use this 你可以用这个

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

found at this http://www.spheregen.com/disable-save-dialog-in-webbrowser-editing/ 在此http://www.spheregen.com/disable-save-dialog-in-webbrowser-editing/中找到

Hope to work for you 希望为你工作

I've run into this recently and never had success using the Document.ExecCommand("Refresh") as described. 我最近遇到过这种情况,但从未如所描述的那样使用Document.ExecCommand("Refresh")成功。

What has worked for me is to use Windows API calls to send the WM_CLOSE message to the dialog, allowing me to suppress the dialog but still handle the file saving/reloading in the background. 对我有用的是使用Windows API调用将WM_CLOSE消息发送到对话框,允许我WM_CLOSE对话框,但仍在后台处理文件保存/重新加载。

SO answer: Setting up Hook on Windows messages was helpful in setting everything up, but the general gist of it was to obtain the dialog class ( #32770 ), then make sure that the title of the dialog contained my temporary filename, then obtain the handle to that dialog and send it WM_CLOSE . 这样的答案: 在Windows消息上设置Hook有助于设置所有内容,但其主要内容是获取对话框类( #32770 ),然后确保对话框的标题包含我的临时文件名,然后获取处理该对话框并将其发送WM_CLOSE

The body of my delegate function for SetWinEventHook is as follows, hopefully this is of some help. 我的SetWinEventHook委托函数的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);
}

ClassName and DialogTitle are of StringBuilder type, ReturnValue and DialogHandle are of IntPtr type. ClassNameDialogTitleStringBuilder类型, ReturnValueDialogHandleIntPtr类型。 TempFilename is a string containing a tempfile name generated by Path.GetTempFileName() TempFilename是一个字符串,其中包含由Path.GetTempFileName()生成的临时文件名

You'll need API calls to SetWinEventHook , UnhookWinEvent , GetClassName , GetWindowText , FindWindow , and SendMessage - PInvoke.net should be able to help with those. 您需要对SetWinEventHookUnhookWinEventGetClassNameGetWindowTextFindWindowSendMessage API调用-PInvoke.net应该可以帮助您解决这些问题。 You'll also need a few constants setting up, again - PInvoke can help. 同样,您还需要设置一些常量-PInvoke可以提供帮助。

It's not the most elegant solution, but it works! 这不是最优雅的解决方案,但可以!

Edited to add - if you want to actually interact with the dialog, rather than just arbitrarily close it, you can use the code found at PInvoke here: http://www.pinvoke.net/default.aspx/user32.enumchildwindows then, pass DialogHandle in the code above to the GetChildWindows() function and iterate through the list of returned IntPtr objects, calling GetWindowText() on each item until you find a value that matches either " &Yes " (for the Yes button), " &No " (for the No button) or " Cancel " (for the cancel button). 编辑后添加-如果您想与对话框进行实际交互,而不仅仅是随意关闭对话框,则可以使用在PInvoke处找到的代码: http ://www.pinvoke.net/default.aspx/user32.enumchildwindows,将上面代码中的DialogHandle传递给GetChildWindows()函数,并遍历返回的IntPtr对象的列表,对每个项目调用GetWindowText() ,直到找到与“ &Yes ”(对于“ &Yes ”按钮),“ &No ”相匹配的值(对于否按钮)或“ Cancel ”(对于取消按钮)。

Once you have the handle of the button, send it the BM_CLICK message (0x00F5) and you can suppress the dialog without losing the functionality of it. 掌握了按钮的句柄后,将其发送给BM_CLICK消息(0x00F5),您可以取消显示对话框而不会失去其功能。

As you're only iterating through the targeted dialog rather than every window, this is a pretty fast operation (took 2ms when tested) so shouldn't cause any slowdowns. 因为您只遍历目标对话框而不是每个窗口,所以这是一个相当快的操作(测试时占用2ms),因此不会造成任何变慢。

The code changes to the following: 代码更改为以下内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM