已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
窗口与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的Url与ObjectForScripting两个属性。private void InitializeWebBrowser() /设置URL string path = Application.StartupPath + TOC.html; if (File.Exists(path) webBrowser1.Url = new Uri(path); m_Ready = true; else webBrowser1.Url = new Uri(about:blank); /如果TOC文件不存在 /设置脚本调用对象 webBrowser1.ObjectForScripting = this; Url属性:WebBrowser控件显示的网页路径ObjectForScripting属性:该对象可由显示在WebBrowser控件中的网页所包含的脚本代码访问。3. 在C#中调用Javascript方法通过WebBrowser类的Document属性中的InvokeScript方法调用当前网页的Javascript方法。代码示例如下:webBrowser1.Document.InvokeScript(AppendLayer, new object1 layerNameStr );其中,AppendLayer是网页中的javascript方法名称,object数组是其参数。4. 在Javascript中调用C#方法JavaScript通过window.external调用C#公开的方法。即由ObjectForScripting属性设置的类的实例中所包含的公共方法。代码示例如下:window.external.RemoveLayer(index);实现Form与页面的交互 HtmlDocumenthtmlDoc=webBrowser1.Document;/得到webBrowser1控件中页面的所有文档HtmlElementbtnElement=htmlDoc.AllbtnClose;/在文档中找到需要和form交互的元素if(btnElement!=null)btnElement.Click+=newHtmlElementEventHandler(HtmlBtnClose_Click);/给这个元素Click事件(元素为Button)加上EventHandler(委托方法名)WebBrowser控件说明使用 WebBrowser 控件还可以显示在应用程序中创建的内容或从数据库或资源文件检索的内容。 使用 DocumentText 或 DocumentStream 属性,以字符串或数据流的形式获取或设置当前文档的内容。 还可以通过 Document 属性操作网页的内容,该属性包含一个 HtmlDocument 对象,向当前页提供对 HTML 文档对象模型 (DOM) 的托管访问。 该属性与 ObjectForScripting 属性组合使用时,对在应用程序代码与网页中的动态 HTML (DHTML) 代码之间实现双向通信十分有用,使用它可以在单个用户界面中组合基于 Web 的控件和 Windows 窗体控件。 在应用程序中可以使用 Document 属性调用脚本代码方法。 脚本代码可以通过 window.external 对象访问应用程序,该对象是用于主机访问的内置 DOM 对象,它映射到为 ObjectForScripting 属性指定的对象。 The WebBrowser 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) 模式的线程中使用。 若要使用此类,请确保您的 Main 方法已用 STAThreadAttribute 特性标记它。WebBrowser控件使用详解方法说明GoBack 相当于IE的“后退”按钮,使你在当前历史列表中后退一项 GoForward 相当于IE的“前进”按钮,使你在当前历史列表中前进一项 GoHome 相当于IE的“主页”按钮,连接用户默认的主页 GoSearch 相当于IE的“搜索”按钮,连接用户默认的搜索页面 Navigate 连接到指定的URL Refresh 刷新当前页面Refresh2 同上,只是可以指定刷新级别,所指定的刷新级别的值来自RefreshConstants枚举表, 该表定义在ExDisp.h中,可以指定的不同值如下: REFRESH_NORMAL 执行简单的刷新,不将HTTP pragma: no-cache头发送给服务器 REFRESH_IFEXPIRED 只有在网页过期后才进行简单的刷新 REFRESH_CONTINUE 仅作内部使用。在MSDN里写着DO NOT USE! 请勿使用 REFRESH_COMPLETELY 将包含pragma: no-cache头的请求发送到服务器 Stop 相当于IE的“停止”按钮,停止当前页面及其内容的载入 属性说明Application 如果该对象有效,则返回掌管WebBrowser控件的应用程序实现的自动化对象(IDispatch)。如果在宿主对象中自动化对象无效,这个程序将返回WebBrowser 控件的自动化对象 Parent 返回WebBrowser控件的父自动化对象,通常是一个容器,例如是宿主或IE窗口 Container 返回WebBrowser控件容器的自动化对象。通常该值与Parent属性返回的值相同 Document 为活动的文档返回自动化对象。如果HTML当前正被显示在WebBrowser中,则 Document属性提供对DHTML Object Model的访问途径 TopLevelContainer 返回一个Boolean值,表明IE是否是WebBrowser控件顶层容器,是就返回true Type 返回已被WebBrowser控件加载的对象的类型。例如:如果加载.doc文件,就会返 回Microsoft Word Document Left 返回或设置WebBrowser控件窗口的内部左边与容器窗口左边的距离 Top 返回或设置WebBrowser控件窗口的内部左边与容器窗口顶边的距离 Width 返回或设置WebBrowser窗口的宽度,以像素为单位 Height 返回或设置WebBrowser窗口的高度,以像素为单位 LocationName 返回一个字符串,该字符串包含着WebBrowser当前显示的资源的名称,如果资源 是网页就是网页的标题;如果是文件或文件夹,就是文件或文件夹的名称 LocationURL 返回WebBrowser当前正在显示的资源的URL Busy 返回一个Boolean值,说明WebBrowser当前是否正在加载URL,如果返回true 就可以使用stop方法来撤销正在执行的访问操作 WebBrowser 的事件 Private Events Description BeforeNavigate2 导航发生前激发,刷新时不激发CommandStateChange 当命令的激活状态改变时激发。它表明何时激活或关闭Back和Forward 菜单项或按钮 DocumentComplete 当整个文档完成是激发,刷新页面不激发DownloadBegin 当某项下载操作已经开始后激发,刷新也可激发此事件DownloadComplete 当某项下载操作已经完成后激发,刷新也可激发此事件NavigateComplete2 导航完成后激发,刷新时不激发NewWindow2 在创建新窗口以前激发OnFullScreen 当FullScreen属性改变时激发。该事件采用VARIENT_BOOL的一个输 入参数来指示IE是全屏显示方式(VARIENT_TRUE)还是普通显示方式(VARIENT_FALSE) OnMenuBar 改变MenuBar的属性时激发,标示参数是VARIENT_BOOL类型的。 VARIANT_TRUE是可见,VARIANT_ FALSE是隐藏 OnQuit 无论是用户关闭浏览器还是开发者调用Quit方法,当IE退出时就会激发 OnStatusBar 与OnMenuBar调用方法相同,标示状态栏是否可见。 OnToolBar 调用方法同上,标示工具栏是否可见。OnVisible 控制窗口的可见或隐藏,也使用一个VARIENT_BOOL类型的参数 StatusTextChange 如果要改变状态栏中的文字,这个事件就会被激发,但它并不理会程序是否有状态栏TitleChange Title有效或改变时激发总结:在WebBrowser页面上,可以采用两种方式与Form对象交互,一种是采用windows.external对象来调用Form类的公共成员函数,另一种方式是采用事件响应的方式。ref: /337979/243222 C#WinForm开发系列/news/2010914/n2711116.htmlExtension:Study Case 1:用WinForm的Event Handler响应Web页面的事件 现在有这样一个Windows Application,它的界面上只有一个WebBrowser,显示一个本地的HTML文件作为界面。现在的问题是,所有逻辑都可以放在HTML文件里,唯独“关闭”按钮遇到了困难通常,Web页面是没有办法直接控制浏览器的,更不用说结束这个WinForm程序了。但是,在.Net 2.0当中,“由Windows Form响应Web页面的事件”已经成为了现实。在.Net 2.0中,整个HTML文档以及其包含的各个HTML元素,都和一个个HtmlDocument、HtmlElement之类的.Net对象对应。因此只要找到这个“关闭”按钮对应的HtmlElement对象,为其click事件添加Event Handler即可。 假设HTML源代码如下: 1. 2. 3. 4. 5. 那么找出该按钮并为之添加Event Handler的代码如下: 1. HtmlDocumenthtmlDoc=webBrowser.Document; 2. HtmlElementbtnElement=htmlDoc.AllbtnClose; 3. if(btnElement!=null) 4. 5. btnElement.click+=newHtmlElementEventHandler(HtmlBtnClose_Click); 6. 其中HtmlBtnClose_Click是按下Web按钮时的Event Handler。 Study Case 2:表单(form)的自动填写和提交 要使我们的WebBrowser具有自动填表、甚至自动提交的功能,并不困难。 假设有一个最简单的登录页面,输入用户名密码,点“登录”按钮即可登录。已知用户名输入框的id(或Name,下同)是username,密码输入框的id是password,“登录”按钮的id是submitbutton,那么我们只需要在webBrowser的DocumentCompleted事件中使用下面的代码即可: 1. HtmlElementbtnSubmit=webBrowser.Document.Allsubmitbutton; 2. HtmlElementtbUserid=webBrowser.Document.Allusername; 3. HtmlElementtbPasswd=webBrowser.Document.Allpassword; 4. 5. if(tbUserid=null|tbPasswd=null|btnSubmit=null) 6. return; 7. tbUserid.SetAttribute(value,smalldust); 8. tbPasswd.SetAttribute(value,12345678); 9. btnSubmit.InvokeMember(click); 这里我们用SetAttribute来设置文本框的“value”属性,用InvokeMember来调用了按钮的“click”方法。因为不同的Html元素,其拥有的属性和方法也不尽相同,所以.Net 2.0提供了统一的HtmlElement来概括各种Html元素的同时,提供了这两个方法以调用元素特有的功能。关于各种Html元素的属性和方法一览,可以查阅MSDN的DHTML Reference。 关于表单的提交,的确还有另一种方法就是获取form元素而不是button,并用form元素的submit方法: 1. HtmlElementformLogin=webBrowser.Document.FormsloginForm; 2. / 3. formLogin.InvokeMember(submit); 本文之所以没有推荐这种方法,是因为现在的网页,很多都在submit按钮上添加onclick事件,以对提交的内容做最基本的验证。如果直接使用form的submit方法,这些验证代码就得不到执行,有可能会引起错误。 Study Case 3:查找并选择文本 这次我们希望实现一个和IE一模一样的查找功能,以对Web页面内的文字进行查找。 文本查找要借助于TextRange对象的findText方法。但是,.Net里并没有这个对象。这是因为,.Net 2.0提供的HtmlDocument,HtmlWindow,HtmlElement等类,只不过是对原有mshtml这个COM组件的不完整封装,只提供了mshtml的部分功能。所以许多时候,我们仍旧要借助mshtml来实现我们需要的功能。好在这些.Net类都提供了DomDocument这个属性,使得我们很容易把.Net对象转换为COM对象使用。下面的代码演示了如何查找Web页面的文本。 (需要添加mshtml的引用,并加上using mshtml;) 1. publicpartialclassSearchDemo:Form 2. 3. /建立一个查找用的TextRange(IHTMLTxtRange接口) 4. privateIHTMLTxtRangesearchRange=null; 5. publicSearchDemo() 6. 7. InitializeComponent(); 8. 9. 10. privatevoidbtnSearch_Click(objectsender,EventArgse) 11. 12. /Document的DomDocument属性,就是该对象内部的COM对象。 13. IHTMLDocument2document=(IHTMLDocument2)webBrowser.Document.DomDocument; 14. stringkeyword=txtKeyword.Text.Trim(); 15. if(keyword=) 16. return; 17. 18. /IE的查找逻辑就是,如果有选区,就从当前选区开头+1字符处开始查找;没有的话就从页面最初开始查找。 19. /这个逻辑其实是有点不大恰当的,我们这里不用管,和IE一致即可。 20. if(document.selection.type.ToLower()!=none) 21. 22. searchRange=(IHTMLTxtRange)document.selection.createRange(); 23. searchRange.collapse(true); 24. searchRange.moveStart(character,1); 25. 26. else 27. 28. IHTMLBodyElementbody=(IHTMLBodyElement)document.body; 29. searchRange=(IHTMLTxtRange)body.createTextRange(); 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页面还是只读不写。那么,如果说要把所有的搜索结果高亮显示呢?我们很快会想到把所有匹配的文字颜色、背景改一下就可以了。 首先想到的可能是直接修改HTML文本吧但是,与SourceCode的高亮显示不同,我们需要并且只需要高亮页面中的文本部分。HTML标签、脚本代码等等是绝对不应该去改动的。因此我们不能把整个页面的Source Code读进来然后replace,那样有破坏HTML文件结构的可能;我们只能在能够分离出文本与其他内容(标签,脚本)的前提下进行。 具体方法有很多,下面提供两个比较简单的方法。 方法一:使用TextRange(IHTMLTxtRange) 有了上一个Case的基础,相信大家立刻会想到使用TextRange。没错,TextRange除了提供查找方法之外,还提供了一个pasteHTML方法,以指定的HTML文本替换当前TextRange中的内容。代码片断如下: 1. publicpartialclassHilightDemo:Form 2. 3. /定义高亮显示效果的标签。 4. stringtagBefore=; 5. stringtagAfter=; 6. 7. / 8. 9. privatevoidbtnHilight_Click(objectsender,EventArgse) 10. 11. HtmlDocumenthtmlDoc=webBrowser.Document; 12. stringkeyword=txtKeyword.Text.Trim(); 13. if(keyword=) 14. return; 15. 16. objectoTextRange=htmlDoc.Body.InvokeMember(createTextRange); 17. 18. mshtml.IHTMLTxtRangetxtrange=oTextRangeasmshtml.IHTMLTxtRange; 19. 20. while(txtrange.findText(keyword,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. publicpartialclassHilightDemo:Form 2. 3. / 4. 5. privatevoidbtnHilight_Click(objectsender,EventArgse) 6. 7. HTMLDocumentdocument=(HTMLDocument)webBrowser.Document.DomDocument; 8. IHTMLDOMNodebodyNode=(IHTMLDOMNode)webBrowser.Document.Body.DomElement; 9. stringkeyword=txtKeyword.Text.Trim(); 10. if(keyword=) 11. return; 12. 13. HilightText(document,bodyNode,keyword); 14. 15. 16. privatevoidHilightText(HTMLDocumentdocument,IHTMLDOMNodenode,stringkeyword) 17. 18. /nodeType=3:text节点 19. if(node.nodeType=3) 20. 21. stringnodeText=node.nodeValue.ToString(); 22. /如果找到了关键字 23. if(nodeText.Contains(keyword) 24. 25. IHTMLDOMNodeparentNode=node.parentNode; 26. /将关键字作为分隔符,将文本分离,并逐个添加到原text节点的父节点 27. stringresult=nodeText.Split(newstringkeyword,StringSplitOptions.None); 28. for(inti=0;iresult.Length-1;i+) 29. 30. if(resulti!=) 31. 32. IHTMLDOMNodetxtNode=document.createTextNode(resulti); 33. parentNode.insertBefore(txtNode,node); 34. 35. IHTMLDOMNodeorgNode=document.createTextNode(keyword); 36. IHTMLDOMNodehilightedNode=(IHTMLDOMNode)document.createElement(SPAN); 37. IHTMLStylestyle=(IHTMLElement)hilightedNode).style; 38. style.color=black; 39. style.backgroundColor=yellow; 40. hilightedNode.appendChild(orgNode); 41. 42. parentNode.insertBefore(hilightedNode,node); 43. 44. if(resultresult.Length-1!=) 45. 46. IHTMLDOMNodepostNode=document.createTextNode(resultresult.Length-1); 47. parentNode.insertBefore(postNode,node); 48. 49. parentNode.removeChild(node); 50. /EndofnodeText.Contains(keyword) 51. 52. else 53. 54. /如果不是text节点,则递归搜索其子节点 55. IHTMLDOMChildrenCollectionchildNodes=node.childNodesasIHTMLDOMChildrenCollection; 56. foreach(IHTMLDOMNodeninchildNodes) 57. 58. HilightText(document,n,keyword); 59. 60. 61. 62. 上面的两段代码都是为了清晰易懂而精简得不能再简的,有很多地方很不完善。比如,没考虑到如何从高亮显示状态复原;也没有大小写匹配等等。当然,掌握了原理之后相信这些都不会太难。 这两种方法各有优缺点: 使用TextRange较轻量迅速,而且有一个特长,就是可以把跨标签(Tag)的关键字挑出来。例如,有这么一段HTML: 1. HelloWorld! 先不管作者出于什么目的让Hel三个字母成为粗体,总之显示在页面上的是一句“Hello World!”。在我们希望高亮页面中的“Hello”这个关键字时,如果用DOM分析的话,会得出含有“Hel”的节点和文本节点“lo World!”两个节点,因此无法将其挑出来。而TextRange则能正确识别,将其设置为高亮。因此也可以说TextRange是只和文本有关,和HTML语法结构无关的对象。 但是,TextRange也有其致命缺点,加亮容易,反向的话就很难。换句话说,去除高亮显示的时候不能再用TextRange,而需要采用其他方法。 而DOM方法则正好相反, 由于DOM的树状结构特性,虽然不能(或者很难)跨越Tag搜索关键字,但是去除高亮显示并不繁琐。Study Case 5:与脚本的互操作 在Case 1当中,我们已经看到,Web页面的HTML元素的事件,可以由Windows
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年低压电工操作证理论考试练习题及答案
- 服装加工厂裁剪设备安全防护方案
- 梅尼埃病限盐饮水量化管理共识
- 2026学年广东省河源市五年级语文期末深度自测快速提分题(详细参考解析)详细答案和解析
- 2026年畜牧兽医考试题库及答案
- OC岗位综合考核试题及详细答案
- 2027届江苏省句容市数学八上期末联考模拟试题含解析
- 职业健康促进企业创建实施方案
- 儿童共同性斜视随访观察指南(2026版)
- 液压管路预制酸洗操作工规程
- 项目管理人员资格报审表模板
- 洋葱根尖细胞有丝分裂研究
- 2025年05月内蒙古锡林郭勒盟盟直事业单位引进急需紧缺人才85人笔试历年典型考题(历年真题考点)解题思路附带答案详解
- DB31-T 983-2016 热固改性聚苯板节能与安全技术要求
- DB45T 1942-2019 汽车加油站职业卫生管理规范
- 九宫数独200题(附答案全)
- (正式版)JTT 382-2024 内河运输船舶评价指标
- (高清版)DZT 0004-2015 重力调查技术规范(150 000)
- 变应性支气管肺曲霉病诊治专家-共识(2022年修订版)解读
- 第2章 CR400AF动车组司机室设备操作《复兴号动车组司机操作及整备》教学课件
- 金融实习证明
评论
0/150
提交评论