原文:WebBrowser控件的简单应用2

第一个简单应用里面讲述的是如何模拟调用当前网页的元素的事件或者赋值/取值。
这次的应用讲述的是
1:如何处理弹出新页面的事件(总是在我的浏览器里面现实新页面)
2:如何处理window.close事件,让我的浏览器页关闭
3:让html页面的js调用我的browse的函数
4:如何让我的browse调用html的js函数。

使用场景:一个web程序,让用户使用自定义浏览器来浏览,该web程序会调用浏览者机器上一些接口。
我的这个浏览器叫做AppBrowser。
关于ObjectForScripting 的介绍http://msdn2.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting.aspx
首先,第一个问题。
如果只是放置一个browse在那里,在html中打开新页面的时候,他默认使用IE或者其他浏览器来打开网页。如果想要让我的browse也同时能处理所有的新开页面,就要增加一个对_NewWindow事件的处理。
        private void wb_Container_NewWindow(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
            AppBrowser newAB = new AppBrowser(wb_Container.Url.ToString());
            newAB.Show();
        }
在这里要注意的是
1:e.Cancel = true;是为了取消这个事件,不然又打开一个IE
2:wb_Container.Url.接受到的是新页面的参数

关于关闭浏览器
通常,如果设置了这样的js:window.close,那么,IE会自动关闭。但是我的browse却不会,至少默认的是如此的。
为了关闭我的浏览器,我需要接收这个函数。但是,很可惜,找了半天都没找到这个事件在那里处理,于是结合下一个问题,一下子解决了。(其实是半个解决,只有自己写的web程序才能处理)。

关于web调用我的浏览器的函数。
这就成了web和win的交互了,这个win就是在客户端的。以前交互的方式是写一个ActiveX控件,让web调用他,进而访问客户机器上的一些资源。现在的这种方式则是通过自己提供一个符合COM接口的自定义browse来实现。
1:我的browse必须是符合COM接口的[System.Runtime.InteropServices.ComVisibleAttribute(true)]
2:设置一个属性 this.wb_Container.ObjectForScripting = this
这样,Web中就可以这样调用了javascript:window.external.xxx('xx')。比方说上边的那个关闭窗口的调用就可以这样写:
onclick="javascript:window.external.close();"
这个调用,其实是调用的我的browse的Close函数。这个函数是我的winForm上默认的那一个函数。调用其他函数亦然,只要是公开方法就可以。

关于如何browse调用web页面中的函数。
第一个,可以通过直接调用页面中元素的方式来实现,在我上一篇里面有所介绍。
第二个,就是可以直接访问.Document.InvokeScript函数来实现。
比如:
        public object InvokeHtmlJsScript(string scriptName,object[] objects)
        {
           return  this.wb_Container.Document.InvokeScript(scriptName, objects);
        }

简单的类
 1  //set this class as a COM
 2    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
 3    public partial class AppBrowser : Form
 4    {
 5        public AppBrowser()
 6        {
 7            InitializeComponent();
 8        }
 9        /**//// <summary>
10        /// which the url will be go
11        /// </summary>
12        /// <param name="url"></param>
13        public AppBrowser(string url)
14        {
15            InitializeComponent();
16            _url = url;
17            this.wb_Container.Navigate(_url);
18            this.wb_Container.ObjectForScripting = this;//set this to be the COM handler
19           
20        }
21        private string _url;
22        public string Url
23        {
24            get { return this._url; }
25        }
26        /**//// <summary>
27        /// open new page in the window which is also in my brower but not in IE
28        /// </summary>
29        /// <param name="sender"></param>
30        /// <param name="e"></param>
31        private void wb_Container_NewWindow(object sender, CancelEventArgs e)
32        {
33            e.Cancel = true;
34            AppBrowser newAB = new AppBrowser(wb_Container.Url.ToString());
35            newAB.Show();
36        }
37        /**//// <summary>
38        /// this function can be invoked by js in html
39        /// like this 'javascript:window.external.ShowMessage('this is invoke from web');'
40        /// </summary>
41        /// <param name="msg"></param>
42        public void ShowMessage(string msg)
43        {
44            MessageBox.Show(msg);
45        }
46        /**//// <summary>
47        /// can invoke script in the html showing in the webbrowser
48        /// </summary>
49        /// <param name="scriptName"></param>
50        /// <param name="objects"></param>
51        /// <returns></returns>
52        public object InvokeHtmlJsScript(string scriptName,object[] objects)
53        {
54           return  this.wb_Container.Document.InvokeScript(scriptName, objects);
55        }
56    }

后记:经过测试,终于找到了一种方法可以解决window.close的问题了(第二个问题)

 1   private void wb_Container_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
 2        {
 3            wb_Container.Document.Window.Unload += new HtmlElementEventHandler(Window_Unload);
 4        }
 5
 6        void Window_Unload(object sender, HtmlElementEventArgs e)
 7        {
 8            if (this.wb_Container.Document == null)
 9                this.Close();
10        }

原理:
1:代理window的unload事件。这个事件在页面卸载的时候触发。
2:在这个事件之后检查webbrowser的值。如果是window.close,那么属性为空。
可能这个方法还是不够好,但是现下可用了。

WebBrowser控件的简单应用2的更多相关文章

  1. vs2005中的WebBrowser控件的简单应用

    原文:vs2005中的WebBrowser控件的简单应用 这个控件被封装了一下,和以前的调用方式稍有不同.事件还是那几个,变化不大.方法变了不少.从网上能查到的资料不多,贴出一些代码来作参考.看看这段 ...

  2. WebBrowser控件应用:弹出新窗体和关闭窗口

    缘起:上次写了一个<WebBrowser控件的简单应用2>,提到了在NewWindow事件中打开新窗口的例子.有网友“队长 ”提出那个事件得到的参数是本页面的,而不是新页面的,经过测试,果 ...

  3. WebBrowser控件使用技巧分享

    原文:WebBrowser控件使用技巧分享 在发布“淘宝登货员”时发现不少朋友对WebBrowser控件比较感兴趣,故在此分享一下使用心得. 首先分享一个WebBrowser的扩展类(此类所需的dll ...

  4. Webbrowser控件判断网页加载完毕的简单方法 (转)

    摘自:http://blog.csdn.net/cometnet/article/details/5261192 一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,W ...

  5. Webbrowser控件判断网页加载完毕的简单方法

    一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,Webbrowser控件会通过触发DocumentCompleted事件来指示网页加载完毕.但当加载的网页包含fra ...

  6. C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)控制 WebBrowser 控件的外观和行为

    在 CSDN 上经常看到以下两个问题:1.在 MFC 应用程序中,如果创建了一个 WebBrowser 控件(包括 CHtmlView 在内),如何可以把该控件的三维边框禁止掉?2.在 MFC 应用程 ...

  7. C# WebBrowser控件 模拟登录 抓取数据

    参考博客:C#中的WebBrowser控件的使用 参考博客:C#中利用WebBrowser控件,获得HTML源码 一.问题点: 1.模拟登录后,如果带有嵌套的iframe嵌套,不好读取iframe内容 ...

  8. VC++使用WebBrowser控件,强制给控件指定版本显示网页

    转载:http://www.cnblogs.com/1175429393wljblog/p/5398928.html 最近为了抓取淘宝的成交数据,用C#的WebBrowser控件开发了一个简单的程序. ...

  9. C# 禁止 Webbrowser 控件的弹出脚本错误对话框

    当IE浏览器遇到脚本错误时浏览器,左下 角会出现一个黄色图标,点击可以查看脚本错误的详细信息,并不会有弹出的错误信息框.当我们使用 WebBrowser控件时有错误信息框弹出,这样程序显的很不友好,而 ...

随机推荐

  1. 【原版的】Redis事件驱动内核

    Redis事件驱动内核 作者:cf (360电商技术组) 概述 Redis实现了自己的事件驱动,与开源事件库libevent.libev一样,都是基于I/O多路复用技术实现的.出于性能和代码精炼双方面 ...

  2. org.eclipse.birt.report.data.oda.jdbc.JDBCException: Missing properties in Connection.open(Propertie

    首先查看project的web.xml档"BIRT_RESOURCE_PATH"属性的设置.此属性设置的是"用户资源存放路径.这些资源包含 library 文件,imag ...

  3. 微软系统工具套件SysinternalsSuite各个工具功能说明

    下载地址:http://download.sysinternals.com/files/SysinternalsSuite.zip 工具名    工具说明 Accesschk      Windows ...

  4. jstack:将Process Explorer中看到的进程ID做16进制转换,到ThreadDump中加上0x 前缀即能找到对应线程(转)

    原文链接:http://www.iteye.com/topic/1133941 症状: 使用Eclipse win 64位版本,indigo及kepler都重现了,使用tomcat 6.0.39,jd ...

  5. 高效C++规划

    推荐写C++代码风格.看似easy.坚持不易,且写且珍惜! --陈国林 1. 版本号和版本号声明 版本号和版本号文件声明位于头文件和定义文件的开头,主要内容 (1)版本号信息 (2)文件名.标识符.摘 ...

  6. css3 menu 手机菜单1

    首先看一下效果图; 效果1,主要是 translateY(100px) -->translateY(0px);opacity:0;—>opacity: 1; 然后递归延迟 怕麻烦也可以自己 ...

  7. UVA 11174 Stand in a Line 树dp+算

    主题链接:点击打开链接 题意:白书的P103. 加个虚根就能够了...然后就是一个多重集排列. import java.io.PrintWriter; import java.util.ArrayLi ...

  8. JavaEE(15) - JPA实体继承

    1. 实体继承映射的三种策略 #1. 整个类层次对应一张表 #2. 连接子类 #3. 每个具体类对应一张表 2. 使用抽象实体 3. 使用非实体父类 4. 重定义子类实体的外键列 ---------- ...

  9. thinkphp学习笔记10—看不懂的路由规则

    原文:thinkphp学习笔记10-看不懂的路由规则 路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INF ...

  10. 流动python - 写port扫描仪和各种并发尝试(多线程/多进程/gevent/futures)

    port扫描仪的原理非常easy.没有什么比操作更socket,能够connect它认为,port打开. import socket def scan(port): s = socket.socket ...