随心所欲

做个幸福的人
posts - 147, comments - 1402, trackbacks - 28, articles - 0
  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理

WebBrowser控件的简单应用2

Posted on 2007-04-11 15:52 随心所欲 阅读(16564) 评论(30)  编辑 收藏 网摘 所属分类: VS2005

第一个简单应用里面讲述的是如何模拟调用当前网页的元素的事件或者赋值/取值。
这次的应用讲述的是
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);
        }


简单的类


后记:经过测试,终于找到了一种方法可以解决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,那么属性为空。
可能这个方法还是不够好,但是现下可用了。

Feedback

#1楼    回复  引用  查看    

2007-04-11 16:40 by jeky      
Good!!收藏了!!!!!!!!!!!谢谢!

#2楼    回复  引用  查看    

2007-04-11 17:00 by zfphere      
前几天我也试了下ie控件,不过是com下的。但是发现了一个问题就是js代码内触发的事件,无法被WinForm UI 捕捉到,比如如下代码:
function invokeBtnEvent()
{
var btn = document.getElementById("testBtn");
btn.onclick(); //WinUI 截获不到该btn的事件
}
但是,如果是手动的在页面上点击该btn,则可以触发WinUI上定义的事件处理函数。

#3楼 [楼主]   回复  引用  查看    

2007-04-11 17:09 by 随心所欲      
@zfphere
这一个不难。
你可以遍历element,然后代理事件。
在_DocumentCompleted事件里面
foreach(element)
{
element.AttachEventHandler("onclick", new EventHandler(ClickHandler));
}

#4楼 [楼主]   回复  引用  查看    

2007-04-11 17:10 by 随心所欲      
@zfphere
这样就可以把html的事件代理到win中。

可惜,我不知道window.close对应那一个事件,不然就容易处理多了。

#5楼    回复  引用  查看    

2007-04-11 18:50 by Justin      
比较实用!

#6楼    回复  引用  查看    

2007-04-11 20:22 by 臭石头      
不知道从ShellWindow得到的IWebBrowser2对象是否也可以挂接事件。

#7楼 [楼主]   回复  引用  查看    

2007-04-12 09:35 by 随心所欲      
@臭石头
不知道。或许可以。

#8楼    回复  引用    

2007-04-12 11:18 by zoti [未注册用户]
good.mark

#9楼    回复  引用    

2007-04-12 14:16 by 虚拟主机 [未注册用户]
呵呵路过看看还不错

#10楼    回复  引用  查看    

2007-04-12 20:32 by 队长      
请问,那个wb_Container就是.net2.0里面新增的WebBrowser吗?
如果是的话,wb_Container.Url这个好像还是原来的地址啊?如何得到新弹出窗口的地址呢?
如果方便的话,能发一下源码吗?

#11楼 [楼主]   回复  引用  查看    

2007-04-13 12:31 by 随心所欲      
@队长
是的,就是这个控件。
在_NewWindow事件里面得到的url就是新的将要打开的那个url了。
源码上边就有,完整的类,直接能用。

#12楼    回复  引用  查看    

2007-04-14 14:19 by 队长      
@随心所欲
谢谢你的回复!
不过,那个Url地址的确不是即将打开的地址,而是原来的地址(起码在我的例子中是这样的)
关于这个问题,我在codeproject上找到了一篇文章,作者定义了一个扩展的WebBrowser控件,地址如下:http://www.codeproject.com/csharp/ExtendedWebBrowser.asp
在他的文章里也提到了关于关闭页面的解决办法,非常值得参考
还有一个也不错:http://www.codeproject.com/vb/net/IE7_Clone_VS2005_Browser.asp?df=100&forumid=372409&exp=0&select=1854959

#13楼 [楼主]   回复  引用  查看    

2007-04-14 14:39 by 随心所欲      
@队长
是的,确实是我看错了。那个url不可以。
这里有两个网址,其中一个你已经给我了,另外一个是微软给的解决方案,相当不令人满意。
我也自己尝试了好多方法了,过几天写出来大家分享。

http://www.codeproject.com/csharp/ExtendedWebBrowser.asp

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=115195

#14楼    回复  引用    

2007-04-24 16:10 by 沈曦 [未注册用户]
使用 sender.url 就好了。

#15楼    回复  引用    

2007-04-24 16:23 by 沈曦 [未注册用户]
额。对不住,经过试验,使用sender.url也不行,抱歉。

#16楼 [楼主]   回复  引用  查看    

2007-04-24 18:30 by 随心所欲      
@沈曦
yes, that's the point.

#17楼 [楼主]   回复  引用  查看    

2007-04-24 18:31 by 随心所欲      
@沈曦
sender is the same control , WebBrowser.

#18楼    回复  引用    

2007-04-25 23:41 by sumaoyi [未注册用户]
请问下:
如果我要显示调用这个控件里面加载了的页面的类似<a>提交按钮这些的点击事件,有没解决方案呢?【显示调用,就是直接函数去调,不用再去点击这些】

#19楼 [楼主]   回复  引用  查看    

2007-04-26 09:58 by 随心所欲      
@sumaoyi
应该可以。
不论是“显式”还是“隐式”,最终都是通过java虚拟机来解释触发的。

#20楼    回复  引用    

2008-03-27 14:09 by 未注册 [未注册用户]
楼主你好,我有个webbrower的问题。
现在有3个站,我想依次打开。
怎么做到判断打开一个站后再打开下一个站。
谢谢
十分感谢
http://topic.csdn.net/u/20080326/00/80e6951d-5798-41ed-be00-13436182ab71.html?seed=1336715016

#21楼 [楼主]   回复  引用  查看    

2008-03-27 14:14 by 随心所欲      
@未注册
有点小技巧,我是通过判断DocumentCompleted的次数来确定的。每个网站这个时间完成的次数是一定的。
wb_Container_DocumentCompleted:
i++
if(i==xx)
xxx

#22楼    回复  引用  查看    

2008-04-29 01:13 by 镜涛      
学习啦!呵呵

#23楼    回复  引用    

2008-06-27 09:47 by sjw [未注册用户]
这个控件,能不能获得访问一个URL产生的数据。

#24楼    回复  引用    

2008-06-27 09:49 by sjw [未注册用户]
这个控件,能不能获得访问一个URL产生的所以数据。一般IE访问一个URL,先下载这个页面,然后去请求这个页面其它数据,这些数据怎么获得。我想得到这些数据。我该怎么做呢?

#25楼 [楼主]   回复  引用  查看    

2008-06-28 10:28 by 随心所欲      
@sjw
可以得到。
webBrowser.Document对象就是现实的内容,与代码自在其中。

#26楼    回复  引用  查看    

2008-08-16 16:26 by ye      
想问题下当它出现滚动条时怎样来控制它的滚动条的位置

#27楼 [楼主]   回复  引用  查看    

2008-08-18 09:34 by 随心所欲      
@ye
除非用更底层的控制。
我用的方法有点垃圾:模拟鼠标点击滚动条。

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-04-11 17:15 编辑过
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接:

 
Google