基于net开发chrome核心浏览器四.doc

上传人:scccc 文档编号:12061436 上传时间:2021-12-01 格式:DOC 页数:15 大小:50.50KB
返回 下载 相关 举报
基于net开发chrome核心浏览器四.doc_第1页
第1页 / 共15页
基于net开发chrome核心浏览器四.doc_第2页
第2页 / 共15页
基于net开发chrome核心浏览器四.doc_第3页
第3页 / 共15页
基于net开发chrome核心浏览器四.doc_第4页
第4页 / 共15页
基于net开发chrome核心浏览器四.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《基于net开发chrome核心浏览器四.doc》由会员分享,可在线阅读,更多相关《基于net开发chrome核心浏览器四.doc(15页珍藏版)》请在三一文库上搜索。

1、基于 .net 开发 chrome 核心浏览器【四】上周去北京出差,给国家电网的项目做架构方案,每天都很 晚睡,客户那边的副总也这样拼命工作。 累的不行了,直接导致第四篇文章没有按时发出来。 希望虚心学习 1,小侠客等关注我的朋友们原谅我。在这篇文章中,我们主要实现下面三个功能: 浏览器地址栏、浏览器窗口大小变化、浏览器下载文件 为了实现这三个功能,我们新创建了一个工程, program.cs 文件里的内容没有任何变动; dll 文件夹里的内容没有任何变动; 资源的引用,程序集的配置,都没有做任何变动;. .-.我们在解决方案中创建一个 bs 文件夹,这个文件夹中放置 与浏览器相关的类。首先在

2、这个文件夹中创建一个叫 BsDownloadHandler 的类 顾名思义,这个类是为下载文件而创建的。 如果想实现下载文件,首先要让这个类继承CefDownloadHandler然后重写父类的 OnBeforeDownload 和OnDownloadUpdated 两个方法 重写的代码如下:protected override voidOnBeforeDownload(CefBrowser browser,CefDownloadItem downloadItem, string suggestedName,CefBeforeDownloadCallback callback)callback

3、.Continue(string.Empty, true);protected override voidOnDownloadUpdated(CefBrowser browser,CefDownloadItem downloadItem,CefDownloadItemCallback callback)if (downloadItem.IsComplete)MessageBox.Show(" 下载成功 "); if (browser.IsPopup&& !browser.HasDocument)browser.GetHost().Parent

4、WindowWillClose();browser.GetHost().CloseBrowser();OnBeforeDownload 方法,在浏览器开始下载文件之前被调 用, CEF 在默认情况下屏蔽了所有文件下载的事件 如果希望 CEF 处理下载事件,那么就要调用 callback 参数 的 Continue 事件。suggested_name 参数是下载文件的建议名称,也就是保存 文件对话框出来之后,文件名称文本框里的内容。OnDownloadUpdated 方法, CEF 在下载文件过程中会多次 调用此方法,并不是只有完成下载了之后再调用这个方法。 如果你想终止下载,也可以调用 cal

5、lback 参数的 Cancel 方 法downloadItem 是描述下载文件的类型的实例, 他里面有一系列的属性, 包括:是否完成、是否取消、当前速度、完成的百分比、完 成了多少比特、一共有多少比特、开始时间、结束时间等等不要试图在上面两个方法之外,引用这个实例 因为浏览器下载文件有很多方式,有可能是通过 window.open(js) 的方式打开一个路径来下载文件 这时,我们要关掉被打开的窗口, (CEF 不会自动帮我们关 掉这类窗口 )所以在获知下载完成之后, 又执行了如下两句代 码:if (browser.IsPopup&& !browser.HasD

6、ocument)browser.GetHost().ParentWindowWillClose(); browser.GetHost().CloseBrowser();四: 为了能使浏览器的窗口大小,随着容器的窗口大小变化而变 化。我们必须要知道,浏览器的窗口句柄何时创建成功,何时被 加入到父窗口中去了。在上一篇文章中, 我们提到 CefBrowserHost.CreateBrowser 方法是异步的。 我们要想一些办法,来获取这个方法执行成功后,所创建的 浏览器窗口的句柄。首先,我们要在 bs 文件夹内创建一个名为 BsLifeSpanHandler 的类 这个类继承自 CefLifeSpa

7、nHandler ,我们在这个类中重写了 OnAfterCreated 方法 整个类的代码如下:public class BsLifeSpanHandler : CefLifeSpanHandler private BsClient bClient;public BsLifeSpanHandler(BsClient bc)bClient = bc; protected override voidOnAfterCreated(Xilium.CefGlue.CefBrowser browser)base.OnAfterCreated(browser);bClient.Created(browser

8、);创建这个类的实例,必须传入一个 BsClient 的实例,关于 BsClient 的内容,我们稍后再讲 基类 CefLifeSpanHandler 中有很多方法可供重载。 包括:弹窗之前的事件、浏览器窗口创建成功后的事件、执 行模态窗的事件、关闭窗口之前的事件 (虽然这里叫事件,但其实是方法,只不过 CEF 会自动调 用这些方法) 我们在这个类中重写了 OnAfterCreated 方法(浏览器窗口 创建成功后的事件) , 在这个方法中,我们调用了 BsClient 实例的 Created 方法, 并且把 browser 实例当作参数传递给了这个方法 这里的 browser 其实就是我们创

9、建出来的浏览器核心,可以 通过它获取浏览器的窗口句柄。五: 我们在上一篇文章中,创建了一个 BrowserClient 类,这个 类继承自 CefClient 。 但我们并没有给这个类任何实现,只是在调用 CefBrowserHost.CreateBrowser 方法时,传递了这个类的 一个实例 现在,我们把这个类放到 bs 文件夹中去, 并改名为 BsClient ,为这个类增加如下实现代码:public class BsClient:CefClientpublic event EventHandler OnCreated;private readonly CefLifeSpanHandle

10、r lifeSpanHandler;private readonly CefDownloadHandler downloadHandler;public BsClient()lifeSpanHandler = newBsLifeSpanHandler(this);downloadHandler = newBsDownloadHandler();protected override CefLifeSpanHandler GetLifeSpanHandler()return lifeSpanHandler;protected override CefDownloadHandlerGetDownlo

11、adHandler()return downloadHandler;public void Created(CefBrowser bs)if (OnCreated != null)OnCreated(bs, EventArgs.Empty);在这个类中,我们重写了 GetLifeSpanHandler 和GetDownloadHandler 方法, 这样,我们前面创建的 BsLifeSpanHandler 和 BsDownloadHandler 才会物尽其用。 还可以在这里重写很多方法, 比如: GetContextMenuHandler (右键菜单句柄) , GetDialogHandler

12、 (对话框句柄) GetKeyboardHandler (键 盘句柄)等 在这个类中我们还公开了一个 OnCreated 的事件, Created 方法会调用这个事件。而这个方法,是在 BsLifeSpanHandler 类中被调用的。 也就是说, 当浏览器创建完成时, OnCreated 事件会被触发。 六:我们在 bs 文件夹下创建一个类 BsCtl 这个类就是我们的浏览器控件, 先来看一下这个类唯一的构造函数:public BsCtl(Control ctl)parent = ctl;var cwi = CefWindowInfo.Create(); cwi.SetAsChild(par

13、ent.Handle, newCefRectangle(0, 0, parent.Width, parent.Height);var bc = new BsClient();bc.OnCreated += bc_OnCreated; var bs = new CefBrowserSettings() ; CefBrowserHost.CreateBrowser(cwi, bc, bs, "parent.SizeChanged +=parent_SizeChanged; 你会发现, 上一篇文章中的几行核心代码, 都搬到这里来了。 构造函数的参数 ctl ,是一个 windows 控件,

14、 一般是个 panel 之类的容器控件, 我们创建的浏览器窗口就将呈现在这个容器控件内 同时,我们为这个容器控件注册了 SizeChanged 事件 也为 BsClient 注册了 OnCreated 事件。 我们在创建默认浏览器的时候,指定了它的默认主页(就是 我的博客) 你如果不想这么办,你可以指定它为: about:blank面我们看一下这两个事件的实现代码void bc_OnCreated(object sender, EventArgs e)bs = (CefBrowser)sender;var handle =bs.GetHost().GetWindowHandle();Resiz

15、eWindow(handle,parent.Width,parent.Height);void parent_SizeChanged(object sender,EventArgs e)if (bs != null)var handle =bs.GetHost().GetWindowHandle();ResizeWindow(handle, parent.Width, parent.Height);在浏览器创建成功的事件中,我们把浏览器的实例保存成了 私有属性他是一个核心对象,以后有很多地方会用到。我们通过 bs.GetHost().GetWindowHandle(); 来获得浏览器 窗口的句

16、柄。有了这个句柄,我们就可以重置浏览器窗口的大小,使他随 着主窗体的大小变化而变化面来看一下 ResizeWindow 方法的代码:DllImport("user32.dll")return: MarshalAs(UnmanagedType.Bool) public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);private void ResizeWindow(IntPtr handle, int

17、 width, int height)if (handle != IntPtr.Zero)NativeMethod.SetWindowPos(handle, IntPtr.Zero,0, 0, width, height,0x0002 | 0x0004);在 ResizeWindow 方法中,通过 PInvoke 方式调用了 windows api 的方法,来设置浏览器窗口的位置和大小 其中 0x0002 相当于 SWP_NOMOVE ; 0x0004 相当于SWP_NOZORDER在这个类中,还有一个方法,代码如下: public void LoadUrl(string url)bs.Get

18、MainFrame().LoadUrl(url);这个方法负责切换浏览器的地址七:现在我们来设计主窗口一些必要的布局代码如下,就不多做解释了:this.AddressContainer.Anchor =(System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Left)this.GoBtn.Anchor =(System.Windows.Forms.AnchorStyles)(System.Window s.Forms.AnchorSt

19、yles.Top |System.Windows.Forms.AnchorStyles.Right);this.AddressTB.Anchor =(System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top |System.Windows.Forms.AnchorStyles.Left)this.BrowserContainer.Anchor =(System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top |System.

20、Windows.Forms.AnchorStyles.Bottom)this.StatusContainer.Anchor =(System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Bottom |System.Windows.Forms.AnchorStyles.Left)经过前面的一系列工作,我们主窗口的代码就精简了很多public partial class Demo : FormBsCtl bs;public Demo()InitializeComponent(); this.Name = "

21、CefBrowser" this.Text = " 最简单的实现 "private void CefBrowser_Load(object sender,EventArgs e)bs = new BsCtl(BrowserContainer);private void GoBtn_Click(object sender,EventArgs e)if(!string.IsNullOrWhiteSpace(AddressTB.Text)bs.LoadUrl(AddressTB.Text);在窗口加载成功后,我们创建了浏览器的实例(创建时把浏览器容器传递给了构造函数) ,当点击 GO 按钮的时候,切换了浏览器的地址。最终的效果如下(浏览器窗口的大小会随着主窗口的大小而 变化) 源码下载:

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

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1