收藏 分享(赏)

Form+HTML 界面.doc

上传人:ysd1539 文档编号:6732592 上传时间:2019-04-21 格式:DOC 页数:11 大小:48.08KB
下载 相关 举报
Form+HTML 界面.doc_第1页
第1页 / 共11页
Form+HTML 界面.doc_第2页
第2页 / 共11页
Form+HTML 界面.doc_第3页
第3页 / 共11页
Form+HTML 界面.doc_第4页
第4页 / 共11页
Form+HTML 界面.doc_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、窗口与 WebBrowser 控件相结合开发程序界面by skyfrog 2011/5/8 补C# Windows 应用程序与 JavaScript 交互使用 Winform WebBrowser 控件对访问页面执行、改写、添加 Javascript 代码,可以解决许多问题,实现你想要的效果。1. 在 Form 上添加 Webbrowser 控件,然后再 Form 类上添加 COM 可访问属性:/设置如下属性让 COM 可访问(网页文件需要)System.Runtime.InteropServices.ComVisibleAttribute(true)2. 初始化 WebBrowser 的 U

2、rl 与 ObjectForScripting 两个属性。private void InitializeWebBrowser()/设置 URLstring path = Application.StartupPath + “TOC.html“;if (File.Exists(path)webBrowser1.Url = new Uri(path);m_Ready = true;elsewebBrowser1.Url = new Uri(“about:blank“); /如果 TOC 文件不存在/设置脚本调用对象webBrowser1.ObjectForScripting = this;Url

3、属性:WebBrowser 控件显示的网页路径ObjectForScripting 属性:该对象可由显示在 WebBrowser 控件中的网页所包含的脚本代码访问。3. 在 C#中调用 Javascript 方法通过 WebBrowser 类的 Document 属性中的 InvokeScript 方法调用当前网页的 Javascript方法。代码示例如下:webBrowser1.Document.InvokeScript(“AppendLayer“, new object1 layerNameStr );其中,“AppendLayer“是网页中的 javascript 方法名称,object

4、 数组是其参数。4. 在 Javascript 中调用 C#方法JavaScript 通过 window.external 调用 C#公开的方法。即由 ObjectForScripting 属性设置的类的实例中所包含的公共方法。代码示例如下:window.external.RemoveLayer(index);实现 Form 与页面的交互HtmlDocument htmlDoc = webBrowser1.Document;/得到 webBrowser1 控件中页面的所有文档HtmlElement btnElement = htmlDoc.All“btnClose“;/在文档中找到需要和 fo

5、rm 交互的元素if (btnElement != null)btnElement.Click += new HtmlElementEventHandler(HtmlBtnClose_Click);/给这个元素 Click 事件(元素为 Button)加上 EventHandler(委托方法名) WebBrowser 控件说明使用 WebBrowser 控件还可以显示在应用程序中创建的内容或从数据库或资源文件检索的内容。使用 DocumentText 或 DocumentStream 属性,以字符串或数据流的形式获取或设置当前文档的内容。 还可以通过 Document 属性操作网页的内容,该属

6、性包含一个 HtmlDocument 对象,向当前页提供对 HTML 文档对象模型 (DOM) 的托管访问。 该属性与 ObjectForScripting 属性组合使用时,对在应用程序代码与网页中的动态 HTML (DHTML) 代码之间实现双向通信十分有用,使用它可以在单个用户界面中组合基于 Web 的控件和 Windows 窗体控件。 在应用程序中可以使用 Document 属性调用脚本代码方法。 脚本代码可以通过 window.external 对象访问应用程序,该对象是用于主机访问的内置 DOM 对象,它映射到为 ObjectForScripting 属性指定的对象。 The Web

7、Browser control is a managed wrapper for the ActiveX WebBrowser control, and uses whichever version of the control is installed on the users computer. 注意:WebBrowser 控件会占用大量资源。使用完该控件后一定要调用 Dispose 方法,以便确保及时释放所有资源。必须在附加事件的同一线程上调用 Dispose 方法,该线程应始终是消息或用户界面 (UI) 线程。注意:WebBrowser 类只能在设置为单线程单元 (STA) 模式的线程

8、中使用。 若要使用此类,请确保您的 Main 方法已用 STAThreadAttribute 特性标记它。WebBrowser 控件使用详解方法 说明GoBack 相当于 IE 的“ 后退”按钮,使你在当前历史列表中后退一项 GoForward 相当于 IE 的“ 前进”按钮,使你在当前历史列表中前进一项 GoHome 相当于 IE 的“ 主页”按钮,连接用户默认的主页 GoSearch 相当于 IE 的“ 搜索”按钮,连接用户默认的搜索页面 Navigate 连接到指定的 URL Refresh 刷新当前页面Refresh2 同上,只是可以指定刷新级别,所指定的刷新级别的值来自 Refres

9、hConstants 枚举表, 该表定义在 ExDisp.h 中,可以指定的不同值如下: REFRESH_NORMAL 执行简单的刷新,不将 HTTP pragma: no-cache 头发送给服务器 REFRESH_IFEXPIRED 只有在网页过期后才进行简单的刷新 REFRESH_CONTINUE 仅作内部使用。在 MSDN 里写着 DO NOT USE! 请勿使用 REFRESH_COMPLETELY 将包含 pragma: no-cache 头的请求发送到服务器 Stop 相当于 IE 的“ 停止”按钮,停止当前页面及其内容的载入 属性 说明Application 如果该对象有效,则

10、返回掌管 WebBrowser 控件的应用程序实现的自动化对象(IDispatch)。如果在宿主对象中自动化对象无效,这个程序将返回 WebBrowser 控件的自动化对象 Parent 返回 WebBrowser 控件的父自动化对象,通常是一个容器,例如是宿主或 IE 窗口 Container 返回 WebBrowser 控件容器的自动化对象。通常该值与 Parent 属性返回的值相同 Document 为活动的文档返回自动化对象。如果 HTML 当前正被显示在 WebBrowser 中,则 Document 属性提供对 DHTML Object Model 的访问途径 TopLevelCo

11、ntainer 返回一个 Boolean 值,表明 IE 是否是 WebBrowser 控件顶层容器,是就返回 true Type 返回已被 WebBrowser 控件加载的对象的类型。例如:如果加载.doc 文件,就会返 回 Microsoft Word Document Left 返回或设置 WebBrowser 控件窗口的内部左边与容器窗口左边的距离 Top 返回或设置 WebBrowser 控件窗口的内部左边与容器窗口顶边的距离 Width 返回或设置 WebBrowser 窗口的宽度,以像素为单位 Height 返回或设置 WebBrowser 窗口的高度,以像素为单位 Locati

12、onName 返回一个字符串,该字符串包含着 WebBrowser 当前显示的资源的名称,如果资源 是网页就是网页的标题;如果是文件或文件夹,就是文件或文件夹的名称 LocationURL 返回 WebBrowser 当前正在显示的资源的 URL Busy 返回一个 Boolean 值,说明 WebBrowser 当前是否正在加载 URL,如果返回 true 就可以使用 stop 方法来撤销正在执行的访问操作 WebBrowser 的事件 Private Events Description BeforeNavigate2 导航发生前激发,刷新时不激发CommandStateChange 当命

13、令的激活状态改变时激发。它表明何时激活或关闭 Back 和 Forward 菜单项或按钮 DocumentComplete 当整个文档完成是激发,刷新页面不激发DownloadBegin 当某项下载操作已经开始后激发,刷新也可激发此事件DownloadComplete 当某项下载操作已经完成后激发,刷新也可激发此事件NavigateComplete2 导航完成后激发,刷新时不激发NewWindow2 在创建新窗口以前激发OnFullScreen 当 FullScreen 属性改变时激发。该事件采用 VARIENT_BOOL 的一个输 入参数来指示 IE 是全屏显示方式(VARIENT_TRUE

14、 )还是普通显示方式(VARIENT_FALSE) OnMenuBar 改变 MenuBar 的属性时激发,标示参数是 VARIENT_BOOL 类型的。 VARIANT_TRUE 是可见,VARIANT_ FALSE 是隐藏 OnQuit 无论是用户关闭浏览器还是开发者调用 Quit 方法,当 IE 退出时就会激发 OnStatusBar 与 OnMenuBar 调用方法相同,标示状态栏是否可见。 OnToolBar 调用方法同上,标示工具栏是否可见。OnVisible 控制窗口的可见或隐藏,也使用一个 VARIENT_BOOL 类型的参数 StatusTextChange 如果要改变状态栏

15、中的文字,这个事件就会被激发,但它并不理会程序是否有状态栏TitleChange Title 有效或改变时激发总结:在 WebBrowser 页面上,可以采用两种方式与 Form 对象交互,一种是采用 windows.external 对象来调用 Form 类的公共成员函数,另一种方式是采用事件响应的方式。ref: http:/ C#WinForm 开发系列http:/www.our- Case 1:用 WinForm 的 Event Handler 响应 Web 页面的事件 现在有这样一个 Windows Application,它的界面上只有一个 WebBrowser,显示一个本地的 HT

16、ML 文件作为界面。现在的问题是,所有逻辑都可以放在 HTML 文件里,唯独“关闭”按钮遇到了困难通常,Web页面是没有办法直接控制浏览器的,更不用说结束这个 WinForm 程序了。但是,在.Net 2.0 当中,“由 Windows Form 响应 Web 页面的事件”已经成为了现实。在.Net 2.0 中,整个 HTML 文档以及其包含的各个 HTML 元素,都和一个个 HtmlDocument、HtmlElement之类的.Net 对象对应。因此只要找到这个“关闭”按钮对应的 HtmlElement 对象,为其 click 事件添加 Event Handler 即可。 假设 HTML

17、源代码如下: 1. 2. 3. 4. 5. 那么找出该按钮并为之添加 Event Handler 的代码如下: 1. HtmlDocument htmlDoc = webBrowser.Document; 2. HtmlElement btnElement = htmlDoc.All“btnClose“; 3. if (btnElement != null) 4. 5. btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click); 6. 其中 HtmlBtnClose_Click 是按下 Web 按钮时的 Event

18、Handler。 Study Case 2:表单(form)的自动填写和提交 要使我们的 WebBrowser 具有自动填表、甚至自动提交的功能,并不困难。 假设有一个最简单的登录页面,输入用户名密码,点“登录”按钮即可登录。已知用户名输入框的 id(或 Name,下同)是 username,密码输入框的 id 是 password,“登录”按钮的 id 是 submitbutton,那么我们只需要在 webBrowser 的 DocumentCompleted 事件中使用下面的代码即可: 1. HtmlElement btnSubmit = webBrowser.Document.All“s

19、ubmitbutton“; 2. HtmlElement tbUserid = webBrowser.Document.All“username“; 3. HtmlElement tbPasswd = webBrowser.Document.All“password“; 4. 5. if (tbUserid = null | tbPasswd = null | btnSubmit = null) 6. return; 7. tbUserid.SetAttribute(“value“, “smalldust“); 8. tbPasswd.SetAttribute(“value“, “123456

20、78“); 9. btnSubmit.InvokeMember(“click“); 这里我们用 SetAttribute 来设置文本框的“value”属性,用 InvokeMember 来调用了按钮的“click”方法。因为不同的 Html 元素,其拥有的属性和方法也不尽相同,所以.Net 2.0 提供了统一的 HtmlElement 来概括各种 Html 元素的同时,提供了这两个方法以调用元素特有的功能。关于各种 Html 元素的属性和方法一览,可以查阅 MSDN 的 DHTML Reference。 关于表单的提交,的确还有另一种方法就是获取 form 元素而不是 button,并用 fo

21、rm 元素的 submit 方法: 1. HtmlElement formLogin = webBrowser.Document.Forms“loginForm“; 2. / 3. formLogin.InvokeMember(“submit“); 本文之所以没有推荐这种方法,是因为现在的网页,很多都在 submit 按钮上添加 onclick 事件,以对提交的内容做最基本的验证。如果直接使用form 的 submit 方法,这些验证代码就得不到执行,有可能会引起错误。 Study Case 3:查找并选择文本 这次我们希望实现一个和 IE 一模一样的查找功能,以对 Web 页面内的文字进行查

22、找。 文本查找要借助于 TextRange 对象的 findText 方法。但是,.Net 里并没有这个对象。这是因为,.Net 2.0 提供的 HtmlDocument,HtmlWindow,HtmlElement 等类,只不过是对原有 mshtml 这个 COM 组件的不完整封装,只提供了 mshtml 的部分功能。所以许多时候,我们仍旧要借助 mshtml 来实现我们需要的功能。好在这些.Net 类都提供了 DomDocument 这个属性,使得我们很容易把.Net 对象转换为 COM 对象使用。下面的代码演示了如何查找 Web 页面的文本。 (需要添加 mshtml 的引用,并加上 u

23、sing mshtml;) 1. public partial class SearchDemo : Form 2. 3. / 建立一个查找用的 TextRange(IHTMLTxtRange 接口) 4. private IHTMLTxtRange searchRange = null; 5. public SearchDemo() 6. 7. InitializeComponent(); 8. 9. 10. private void btnSearch_Click(object sender, EventArgs e) 11. 12. / Document 的 DomDocument 属性

24、,就是该对象内部的 COM 对象。 13. IHTMLDocument2 document = (IHTMLDocument2)webBrowser.Document.DomDocument; 14. string keyword = txtKeyword.Text.Trim(); 15. if (keyword = “) 16. return; 17. 18. / IE 的查找逻辑就是,如果有选区,就从当前选区开头+1 字符处开始查找;没有的话就从页面最初开始查找。 19. / 这个逻辑其实是有点不大恰当的,我们这里不用管,和 IE 一致即可。 20. if (document.select

25、ion.type.ToLower() != “none“) 21. 22. searchRange = (IHTMLTxtRange)document.selection.createRange(); 23. searchRange.collapse(true); 24. searchRange.moveStart(“character“, 1); 25. 26. else 27. 28. IHTMLBodyElement body = (IHTMLBodyElement)document.body; 29. searchRange = (IHTMLTxtRange)body.createTe

26、xtRange(); 30. 31. 32. / 如果找到了,就选取(高亮显示)该关键字;否则弹出消息。 33. if (searchRange.findText(keyword, 1, 0) 34. 35. searchRange.select(); 36. 37. else 38. 39. MessageBox.Show(“已搜索到文档结尾。“); 40. 41. 42. 到此为止,简单的查找就搞定了。至于替换功能,看了下一个例子,我相信你就可以触类旁通轻松搞定了。 Study Case 4:高亮显示 上一个例子中我们学会了查找文本究跟到底,对 Web 页面还是只读不写。那么,如果说要把所

27、有的搜索结果高亮显示呢?我们很快会想到把所有匹配的文字颜色、背景改一下就可以了。 首先想到的可能是直接修改 HTML 文本吧但是,与 SourceCode 的高亮显示不同,我们需要并且只需要高亮页面中的文本部分。HTML 标签、脚本代码等等是绝对不应该去改动的。因此我们不能把整个页面的 Source Code 读进来然后 replace,那样有破坏 HTML 文件结构的可能;我们只能在能够分离出文本与其他内容(标签,脚本)的前提下进行。 具体方法有很多,下面提供两个比较简单的方法。 方法一:使用 TextRange(IHTMLTxtRange) 有了上一个 Case 的基础,相信大家立刻会想到

28、使用 TextRange。没错,TextRange 除了提供查找方法之外,还提供了一个 pasteHTML 方法,以指定的 HTML 文本替换当前 TextRange 中的内容。代码片断如下: 1. public partial class HilightDemo : Form 2. 3. / 定义高亮显示效果的标签。 4. string tagBefore = “; 5. string tagAfter = “; 6. 7. / 8. 9. private void btnHilight_Click(object sender, EventArgs e) 10. 11. HtmlDocume

29、nt htmlDoc = webBrowser.Document; 12. string keyword = txtKeyword.Text.Trim(); 13. if (keyword = “) 14. return; 15. 16. object oTextRange = htmlDoc.Body.InvokeMember(“createTextRange“); 17. 18. mshtml.IHTMLTxtRange txtrange = oTextRange as mshtml.IHTMLTxtRange; 19. 20. while (txtrange.findText(keywo

30、rd, 1, 4) 21. 22. try 23. 24. txtrange.pasteHTML(tagBefore + keyword + tagAfter); 25. 26. catch 27. txtrange.collapse(false); 28. 29. 30. 这段代码里获取 IHTMLTxtRange 的方式和上面的例子稍稍不同,其实所谓条条大路通罗马,本质是一样的。 方法二:使用 DOM(文档对象模型) 将 HTML 文档解析为 DOM,然后遍历每个节点,在其中搜索关键字并进行相应替换处理即可。 1. public partial class HilightDemo : Fo

31、rm 2. 3. / 4. 5. private void btnHilight_Click(object sender, EventArgs e) 6. 7. HTMLDocument document = (HTMLDocument)webBrowser.Document.DomDocument; 8. IHTMLDOMNode bodyNode = (IHTMLDOMNode)webBrowser.Document.Body.DomElement; 9. string keyword = txtKeyword.Text.Trim(); 10. if (keyword = “) 11. r

32、eturn; 12. 13. HilightText(document, bodyNode, keyword); 14. 15. 16. private void HilightText(HTMLDocument document, IHTMLDOMNode node, string keyword) 17. 18. / nodeType = 3:text 节点 19. if (node.nodeType = 3) 20. 21. string nodeText = node.nodeValue.ToString(); 22. / 如果找到了关键字 23. if (nodeText.Conta

33、ins(keyword) 24. 25. IHTMLDOMNode parentNode = node.parentNode; 26. / 将关键字作为分隔符,将文本分离,并逐个添加到原 text 节点的父节点 27. string result = nodeText.Split(new string keyword , StringSplitOptions.None); 28. for (int i = 0; i Hello World! 先不管作者出于什么目的让 Hel 三个字母成为粗体,总之显示在页面上的是一句“Hello World!”。在我们希望高亮页面中的“Hello”这个关键字时

34、,如果用 DOM 分析的话,会得出含有“Hel”的节点和文本节点“lo World!”两个节点,因此无法将其挑出来。而 TextRange 则能正确识别,将其设置为高亮。因此也可以说 TextRange 是只和文本有关,和 HTML 语法结构无关的对象。 但是,TextRange 也有其致命缺点,加亮容易,反向的话就很难。换句话说,去除高亮显示的时候不能再用 TextRange,而需要采用其他方法。 而 DOM 方法则正好相反, 由于 DOM 的树状结构特性,虽然不能(或者很难)跨越 Tag 搜索关键字,但是去除高亮显示并不繁琐。Study Case 5:与脚本的互操作 在 Case 1 当中

35、,我们已经看到,Web 页面的 HTML 元素的事件,可以由 Windows Form 端来响应,可以在某种程度上看作是 Web 页面调用 WinForm;那么反过来,WinForm 除了可以直接访问 Web 页面的 HTML 元素之外,能否调用 Web 页面里的各种 Script 呢?首先是调用 Web 页面的脚本中已经定义好的函数。假设 HTML 中有如下 Javascript: 1. function DoAdd(a, b) 2. return a + b; 3. 那么,我们要在 WinForm 调用它,只需如下代码即可: 1. object oSum = webBrowser.Docu

36、ment.InvokeScript(“DoAdd“, new object 1, 2 ); 2. int sum = Convert.ToInt32(oSum); 其次,如果我们想执行一段 Web 页面中原本没有的脚本,该怎么做呢?这次.Net 的类没有提供,看来还要依靠 COM 了。IHTMLWindow2 可以将任意的字符串作为脚本代码来执行。 1. string scriptline01 = “function ShowPageInfo() “; 2. string scriptline02 = “ var numLinks = document.links.length; “; 3.

37、string scriptline03 = “ var numForms = document.forms.length; “; 4. string scriptline04 = “ var numImages = document.images.length; “; 5. string scriptline05 = “ var numScripts = document.scripts.length; “; 6. string scriptline06 = “ alert(网页的统计结果:rn 链接数: + numLinks + “; 7. string scriptline07 = “ r

38、n 表单数: + numForms + “; 8. string scriptline08 = “ rn 图像数: + numImages + “; 9. string scriptline09 = “ rn 脚本数: + numScripts);“; 10. string scriptline10 = “ShowPageInfo();“; 11. 12. string strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 + scriptline05 + 13. scriptline06 + scriptline07 + scriptline08 + scriptline09 + scriptline10; 14. 15. IHTMLWindow2 win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow; 16. win.execScript(strScript, “Javascript“); OK,今天就写到这里吧,再想起什么来再补充吧。欢迎大家多多指正,欢迎讨论。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报