C# webbrowser专题
2021-02-04 18:16
阅读:692
YPE HTML>
标签:inter list 流行 creat 告诉 互联网 dir _for dde
C# .Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 2
Study Case 4:高亮显示 上一个例子中我们学会了查找文本——究跟到底,对Web页面还是只读不写。那么,如果说要把所有的搜索结果高亮显示呢?我们很快会想到把所有匹配的文字颜色、背景改一下就可以了。首先想到的可能是直接修改HTML文本吧……但是,与SourceCode的高亮显示不同,我们需要并且只需要高亮页面中的文本部分。HTML标签、脚本代码等等是绝对不应该去改动的。因此我们不能把整个页面的Source Code读进来然后replace,那样有破坏HTML文件结构的可能;我们只能在能够分离出文本与其他内容(标签,脚本……)的前提下进行。 具体方法有很多,下面提供两个比较简单的方法。 方法一:使用TextRange(IHTMLTxtRange) 有了上一个Case的基础,相信大家立刻会想到使用TextRange。没错,TextRange除了提供查找方法之外,还提供了一个pasteHTML方法,以指定的HTML文本替换当前TextRange中的内容。代码片断如下: public partial class HilightDemo : Form { // 定义高亮显示效果的标签。 string tagBefore = ""; string tagAfter = ""; // …… private void btnHilight_Click(object sender, EventArgs e) { HtmlDocument htmlDoc = webBrowser.Document; string keyword = txtKeyword.Text.Trim(); if (keyword == "") return; object oTextRange = htmlDoc.Body.InvokeMember("createTextRange"); mshtml.IHTMLTxtRange txtrange = oTextRange as mshtml.IHTMLTxtRange; while (txtrange.findText(keyword, 1, 4)) { try { txtrange.pasteHTML(tagBefore + keyword + tagAfter); } catch { } txtrange.collapse(false); } } } ※这段代码里获取IHTMLTxtRange的方式和上面的例子稍稍不同,其实所谓条条大路通罗马,本质是一样的。 方法二:使用DOM(文档对象模型) 将HTML文档解析为DOM,然后遍历每个节点,在其中搜索关键字并进行相应替换处理即可。 public partial class HilightDemo : Form { //…… private void btnHilight_Click(object sender, EventArgs e) { HTMLDocument document = (HTMLDocument)webBrowser.Document.DomDocument; IHTMLDOMNode bodyNode = (IHTMLDOMNode)webBrowser.Document.Body.DomElement; string keyword = txtKeyword.Text.Trim(); if (keyword == "") return; HilightText(document, bodyNode, keyword); } private void HilightText(HTMLDocument document, IHTMLDOMNode node, string keyword) { // nodeType = 3:text节点 if (node.nodeType == 3) { string nodeText = node.nodeValue.ToString(); // 如果找到了关键字 if (nodeText.Contains(keyword)) { IHTMLDOMNode parentNode = node.parentNode; // 将关键字作为分隔符,将文本分离,并逐个添加到原text节点的父节点 string[] result = nodeText.Split(new string[] { keyword }, StringSplitOptions.None); for (int i = 0; i 1; i++) { if (result[i] != "") { IHTMLDOMNode txtNode = document.createTextNode(result[i]); parentNode.insertBefore(txtNode, node); } IHTMLDOMNode orgNode = document.createTextNode(keyword); IHTMLDOMNode hilightedNode = (IHTMLDOMNode)document.createElement("SPAN"); IHTMLStyle style = ((IHTMLElement)hilightedNode).style; style.color = "black"; style.backgroundColor = "yellow"; hilightedNode.appendChild(orgNode); parentNode.insertBefore(hilightedNode, node); } if (result[result.Length - 1] != "") { IHTMLDOMNode postNode = document.createTextNode(result[result.Length - 1]); parentNode.insertBefore(postNode, node); } parentNode.removeChild(node); } // End of nodeText.Contains(keyword) } else { // 如果不是text节点,则递归搜索其子节点 IHTMLDOMChildrenCollection childNodes = node.childNodes as IHTMLDOMChildrenCollection; foreach (IHTMLDOMNode n in childNodes) { HilightText(document, n, keyword); } } } } 上面的两段代码都是为了清晰易懂而精简得不能再简的,有很多地方很不完善。比如,没考虑到如何从高亮显示状态复原;也没有大小写匹配等等。当然,掌握了原理之后相信这些都不会太难。 这两种方法各有优缺点: 使用TextRange较轻量迅速,而且有一个特长,就是可以把跨标签(Tag)的关键字挑出来。例如,有这么一段HTML: Hello World! 先不管作者出于什么目的让Hel三个字母成为粗体,总之显示在页面上的是一句“Hello World!”。在我们希望高亮页面中的“Hello”这个关键字时,如果用DOM分析的话,会得出含有“Hel”的节点和文本节点“lo World!”两个节点,因此无法将其挑出来。而TextRange则能正确识别,将其设置为高亮。因此也可以说TextRange是只和文本有关,和HTML语法结构无关的对象。 但是,TextRange也有其致命缺点,加亮容易,反向的话就很难。换句话说,去除高亮显示的时候不能再用TextRange,而需要采用其他方法。 而DOM方法则正好相反, 由于DOM的树状结构特性,虽然不能(或者很难)跨越Tag搜索关键字,但是去除高亮显示并不繁琐。 Study Case 5:与脚本的互操作 在Case 1当中,我们已经看到,Web页面的HTML元素的事件,可以由Windows Form端来响应,可以在某种程度上看作是Web页面调用WinForm;那么反过来,WinForm除了可以直接访问Web页面的HTML元素之外,能否调用Web页面里的各种Script呢? 首先是调用Web页面的脚本中已经定义好的函数。假设HTML中有如下Javascript: function DoAdd(a, b) { return a + b; } 那么,我们要在WinForm调用它,只需如下代码即可: object oSum = webBrowser.Document.InvokeScript("DoAdd", new object[] { 1, 2 }); int sum = Convert.ToInt32(oSum); 其次,如果我们想执行一段Web页面中原本没有的脚本,该怎么做呢?这次.Net的类没有提供,看来还要依靠COM了。IHTMLWindow2可以将任意的字符串作为脚本代码来执行。 string scriptline01 = @"function ShowPageInfo() {"; string scriptline02 = @" var numLinks = document.links.length; "; string scriptline03 = @" var numForms = document.forms.length; "; string scriptline04 = @" var numImages = document.images.length; "; string scriptline05 = @" var numScripts = document.scripts.length; "; string scriptline06 = @" alert(‘网页的统计结果:\r\n链接数:‘ + numLinks + "; string scriptline07 = @" ‘\r\n表单数:‘ + numForms + "; string scriptline08 = @" ‘\r\n图像数:‘ + numImages + "; string scriptline09 = @" ‘\r\n脚本数:‘ + numScripts);}"; string scriptline10 = @"ShowPageInfo();"; string strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 + scriptline05 + scriptline06 + scriptline07 + scriptline08 + scriptline09 + scriptline10; IHTMLWindow2 win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow; win.execScript(strScript, "Javascript"); OK,今天就写到这里吧,再想起什么来再补充吧。欢迎大家多多指正,欢迎讨论。
C# WebBrowser制作的HTML文本编辑器
C# WebBrowser制作的HTML文本编辑器 · 下载源文件(http: //www.codeproject.com/cs/miscctrl/editor_in_windows_forms/editor2_src.zip) - 42.3 Kb · 下载演示项目(http: //www.codeproject.com/cs/miscctrl/editor_in_windows_forms/editor2_demo.zip) - 19.7 Kb · 原文:A Windows Forms based text editor with HTML output · 类似的控件:HTMLTextBox 简介 刚才,我在编写一个聊天应用程序,其中一个聊天客户端是基于 web 的并以 ASP.NET 2.0 编写,另一个聊天客户端是 C# 编写的基于 Windows 窗体的 .NET 应用。对于此Windows 窗体客户端,我需要一个可以输出 HTML 的富文本编辑器(a rich text editor) ,以便于 ASP.NET 的客户端可以显示 Windows 窗体客户端的聊天内容。这样,就排除了使用 RTF 文本框的可能。 我设计出的解决方案是在 Windows 窗体客户端,以编辑模式使用一个 WebBrowser 控件。对于 WebBrowser 控件中选定的文本,同时在 WebBrowser 控件的上方放置包含格式按钮的工具栏,以便设置文本格式。 本文说明了这个方案中,使用 WebBrowser 控件建立一个编辑器时的主要难点问题。因为源代码不难理解,我就不深入介绍了。 但是,我会介绍一些必要的实现技巧。 WebBrowser 控件设计模式设置 当使用此组件时,会自动应用设计模式,并为文档建立一个编辑模板。但是,作为参考,下面简单说明这是如何实现的。 应用设计模式需要使用 COM 接口,添加一个 MSHTML 的 "Microsoft HTML Object Library" 的引用,并添加一个对 ‘MSHTML‘ 的 ‘using‘。 在把改变写入到 DOM 文档之前,有必要添加一个 body 到控件。要这样做,你可以简单地设置一些文本到 WebBrowser 控件的 DocumentText 属性中。 webBrowser1.DocumentText = "" 下面的代码可以取得新的 DomDocument COM 接口的引用,并设置设计模式为 "On"。 IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2; doc.designMode = "On"; 最后,我把 WebBrowser 控件的上下文菜单替换掉,这样 IE 浏览器的默认上下文菜单就不会显示出来。 webBrowser1.Document.ContextMenuShowing += new HtmlElementEventHandler(Document_ContextMenuShowing); 浏览器现在处于设计模式中,使用一个自定义方法来显示指定的上下文菜单。 格式化文本 使用 browser.Document 中的 ExecCommand 方法,你可以把格式和编辑功能应用到设计模式下的浏览器控件。 下面是一些例子: public void Cut() { webBrowser1.Document.ExecCommand("Cut", false, null); } public void Paste() { webBrowser1.Document.ExecCommand("Paste", false, null); } public void Copy() { webBrowser1.Document.ExecCommand("Copy", false, null); } 某些命令用于绑定(显示)当前选区的格式。 public void Bold() { webBrowser1.Document.ExecCommand("Bold", false, null); } public void Italic() { webBrowser1.Document.ExecCommand("Italic", false, null); } 同步刷新选定文本的格式按钮 下面介绍一些比发出格式化命令到浏览器更有用的技巧。每 200 毫秒,我逐一查询浏览器编辑选区的状态,并据此设置工具栏格式按钮的状态。 private void timer_Tick(object sender, EventArgs e) { SetupKeyListener(); boldButton.Checked = IsBold(); italicButton.Checked = IsItalic(); underlineButton.Checked = IsUnderline(); orderedListButton.Checked = IsOrderedList(); unorderedListButton.Checked = IsUnorderedList(); linkButton.Enabled = SelectionType == SelectionType.Text; UpdateFontComboBox(); UpdateFontSizeComboBox(); if (Tick != null) Tick(); } 你可能已经注意到这儿使用了一个 Tick 计时器事件。外部的组件可以订阅此事件来更新 GUI 的状态。举例来说,它们将基于编辑器控件的状态,刷新“剪切/复制/粘贴/撤销/重复”(操作)的 Enabled 状态。 我通过使用从 WebBrowser 控件返回的 COM 文档接口,来完成此任务,先使用: IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2; 然后,使用 queryCommandState 方法来确定当前选区的状态: public bool IsBold() { return doc.queryCommandState("Bold"); } public bool IsItalic() { return doc.queryCommandState("Italic"); } public bool IsUnderline() { return doc.queryCommandState("Underline"); } 连接按钮和字体控件以一种简单的方式管理,但我将会保留以代码检测的方法。 取得焦点 让控件取得焦点不一定是简单的。 WebBrowser 控件本身不接受焦点。 WebBrowser 控件的文档也不接受焦点。但是,body 会取得焦点,可以假定有一个 body 元素在控件中。 private void SuperFocus() { if (webBrowser1.Document != null && webBrowser1.Document.Body != null) webBrowser1.Document.Body.Focus(); } 当然,你决不需要直接调用此方法。在控件上调用 Focus 方法,会把焦点放置到包含了 WebBrowser 控件的编辑器控件上。当接收到 GotFocus 事件时,编辑器控件会自动把焦点转到 WebBrowser 控件文档的 body 上。 取得文本或 HTML 分别使用 BodyHtml 和 BodyText 方法,可以返回 HTML 和文本。 连接到组件程序集 在 Visual Studio 2005 中,你可以连接到一个程序集 (添加一个引用),即使程序集是可执行的(文件)。此编辑器是作为内嵌在窗体的组件来编写的,因此你可以把这个组件添加到控件面板上,并把它拖放到你的应用程序中。此控件的名称为 Editor,在命名空间 Design 中。 结束语 .NET 2.0 中的 WebBrowser 控件可以作为一个有效的文本编辑器来使用。当你需要一个 HTML 编辑器控件时,它很有用。但是在某些范围内,不能完全直接地使用 WebBrowser 控件来实现。本文试图展示一些让它工作的必要技巧。
C# goto语句
goto语句直接跳转到代码行上,优点是:这是控制什么时候执行哪些代码的一种非常简单的方式.缺点是:过多的使用这个技巧将很难读懂代码. 下面面介绍如何使用这个技巧. goto语句的用法如下: goto; 标签用下述方式定义: ; 列如,下面的代码: int myInteger=5; goto myLabel; myInteger+=10; myLabel; Console.WriteLine("myInteger={0}",myInteger); 其执行过程如下: ...myinteger声明为int类型,并赋予值5. ...goto语句中断正常的执行过程,把控制转到标为mylabel:的代码行上. ...myinteger的值写到控制台上. 第3行代码并没有执行. 实际上,如果在应用程序中加入这段代码,就会发现编译代码时,任务列表会显示一个警告,即"Unreachable code detected"和一个行号.
C# webBrowser js 交互 调用
前面我也有转载过相关文章,当时没有测试,今天测试 ,结果不能用,以前都没注意。 今天整理了一下 。代码如下: using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Security.Permissions; namespace test10 { [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] [System.Runtime.InteropServices.ComVisibleAttribute(true)] public partial class MainForm : Form { public MainForm() { InitializeComponent(); webBrowser1.ObjectForScripting = this; } void MainFormLoad(object sender, EventArgs e) { string s=""; s+=""-//W3C//DTD HTML 4.0 Transitional//EN\">"; s+=""; s+=" "; s+="New Document "; s+=" "; s+=" "; s+=" "; s+=" "; s+=" "; s+=" function ShopXG(inf)"; s+=" {"; s+=" alert(inf);"; s+=" }"; s+=" var as = ‘as‘;"; s+=" "; s+=""; s+=""; s+=" "; s+=""; s+=" "; s+=" "; s+=" ";//调用 C# 的te 方法 s+=" "; s+=" "; s+=""; webBrowser1.DocumentText =s; } void Button1Click(object sender, EventArgs e) { HtmlElement el = webBrowser1.Document.GetElementById("btnId"); el.Click+= new HtmlElementEventHandler(BtnClick);//为 web 按钮添加事件 } void Button2Click(object sender, EventArgs e) { webBrowser1.Document.InvokeScript("ShopXG", new string[] {"我调用到了 js 方法"});//调用 web ShopXG方法 } void BtnClick(object sender, EventArgs e){ MessageBox.Show("C# 添加事件到 js"); } public void te(string s) { MessageBox.Show(s); } } }
C#通过webbrowser控件与javascript交互
C#通过webbrowser控件与javascript交互 1.C#里调用控件里面网页的js函数 // 调用JavaScript的messageBox方法,并传入参数 object[] objects = new object[1]; objects[0] = “C#访问JavaScript脚本”; this.webBrowser1.Document.InvokeScript(“messageBox”, objects); //object就是传入的参数,而messageBox则是网页中预定义好的js函数。 通过这种方式C#里面就可以执行Javascript函数,可以把上面的代码放到一个button的click事件里面。 2.C#windows窗体应用webbrowser控件里网页js调用C#窗体的函数 首先需要在代码里面加上 [System.Runtime.InteropServices.ComVisibleAttribute(true)] public partial class Form1 : Form { …..// } 这样使得C#的com对象是对网页里的javascript可见的。 然后在嵌入网页里面通过“window.external.MyMessageBox(‘javascript访问C#代码’)” ,即通过window.external捕获调用c#定义好的函数。 具体Form.cs代码如下(通过vs2008创建的c#window窗体应用,拖拽上一个webbrowser控件和button控件。): [System.Runtime.InteropServices.ComVisibleAttribute(true)] public partial class Form1 : Form { public Form1() { InitializeComponent(); System.IO.FileInfo file = new System.IO.FileInfo(“test.html”); // WebBrowser控件显示的网页路径 this.webBrowser1.Url = new Uri(file.FullName); // 将当前类设置为可由脚本访问 this.webBrowser1.ObjectForScripting =this; } private void button1_Click(object sender, EventArgs e) { } // 提供给JavaScript调用的方法 public void MyMessageBox(string message) { MessageBox.Show(message); } private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { } private void button1_Click_1(object sender, EventArgs e) { // 调用JavaScript的messageBox方法,并传入参数 object[] objects = new object[1]; objects[0] = “C#访问JavaScript脚本”; this.webBrowser1.Document.InvokeScript(“messageBox”, objects); } } test.html内容比较简单:
上一篇:窗体切换特效
下一篇:C#版简易RSS阅读器
评论
亲,登录后才可以留言!