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

上传人:b****7 文档编号:10544200 上传时间:2023-02-21 格式:DOCX 页数:11 大小:18.08KB
下载 相关 举报
基于net开发chrome核心浏览器四.docx_第1页
第1页 / 共11页
基于net开发chrome核心浏览器四.docx_第2页
第2页 / 共11页
基于net开发chrome核心浏览器四.docx_第3页
第3页 / 共11页
基于net开发chrome核心浏览器四.docx_第4页
第4页 / 共11页
基于net开发chrome核心浏览器四.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

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

《基于net开发chrome核心浏览器四.docx》由会员分享,可在线阅读,更多相关《基于net开发chrome核心浏览器四.docx(11页珍藏版)》请在冰豆网上搜索。

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

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

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

一:

上周去北京出差,给国家电网的项目做架构方案,每天都很晚睡,客户那边的副总也这样拼命工作。

累的不行了,直接导致第四篇文章没有按时发出来。

希望虚心学习1,小侠客等关注我的朋友们原谅我。

二:

在这篇文章中,我们主要实现下面三个功能:

浏览器地址栏、浏览器窗口大小变化、浏览器下载文件

为了实现这三个功能,我们新创建了一个工程,

program.cs文件里的内容没有任何变动;

dll文件夹里的内容没有任何变动;

资源的引用,程序集的配置,都没有做任何变动;

三:

我们在解决方案中创建一个bs文件夹,这个文件夹中放置与浏览器相关的类。

首先在这个文件夹中创建一个叫BsDownloadHandler的类

顾名思义,这个类是为下载文件而创建的。

如果想实现下载文件,首先要让这个类继承CefDownloadHandler

然后重写父类的OnBeforeDownload和OnDownloadUpdated两个方法

重写的代码如下:

protectedoverridevoidOnBeforeDownload(CefBrowserbrowser,CefDownloadItemdownloadItem,stringsuggestedName,CefBeforeDownloadCallbackcallback)

{

callback.Continue(string.Empty,true);

}

protectedoverridevoidOnDownloadUpdated(CefBrowserbrowser,CefDownloadItemdownloadItem,CefDownloadItemCallbackcallback)

{

if(downloadItem.IsComplete)

{

MessageBox.Show("下载成功");

if(browser.IsPopup&&!

browser.HasDocument)

{

browser.GetHost().ParentWindowWillClose();

browser.GetHost().CloseBrowser();

}

}

}

OnBeforeDownload方法,在浏览器开始下载文件之前被调用,CEF在默认情况下屏蔽了所有文件下载的事件

如果希望CEF处理下载事件,那么就要调用callback参数的Continue事件。

suggested_name参数是下载文件的建议名称,也就是保存文件对话框出来之后,文件名称文本框里的内容。

--------------------------

OnDownloadUpdated方法,CEF在下载文件过程中会多次调用此方法,并不是只有完成下载了之后再调用这个方法。

如果你想终止下载,也可以调用callback参数的Cancel方法

--------------------------

downloadItem是描述下载文件的类型的实例,

他里面有一系列的属性,

包括:

是否完成、是否取消、当前速度、完成的百分比、完成了多少比特、一共有多少比特、开始时间、结束时间等等

不要试图在上面两个方法之外,引用这个实例。

----------------------------

因为浏览器下载文件有很多方式,有可能是通过window.open(js)的方式打开一个路径来下载文件

这时,我们要关掉被打开的窗口,(CEF不会自动帮我们关掉这类窗口)所以在获知下载完成之后,又执行了如下两句代码:

if(browser.IsPopup&&!

browser.HasDocument)

{

browser.GetHost().ParentWindowWillClose();

browser.GetHost().CloseBrowser();

}

四:

为了能使浏览器的窗口大小,随着容器的窗口大小变化而变化。

我们必须要知道,浏览器的窗口句柄何时创建成功,何时被加入到父窗口中去了。

在上一篇文章中,我们提到CefBrowserHost.CreateBrowser方法是异步的。

我们要想一些办法,来获取这个方法执行成功后,所创建的浏览器窗口的句柄。

首先,我们要在bs文件夹内创建一个名为BsLifeSpanHandler的类

这个类继承自CefLifeSpanHandler,我们在这个类中重写了OnAfterCreated方法

整个类的代码如下:

publicclassBsLifeSpanHandler:

CefLifeSpanHandler

{

privateBsClientbClient;

publicBsLifeSpanHandler(BsClientbc)

{

bClient=bc;

}

protectedoverridevoidOnAfterCreated(Xilium.CefGlue.CefBrowserbrowser)

{

base.OnAfterCreated(browser);

bClient.Created(browser);

}

}

创建这个类的实例,必须传入一个BsClient的实例,关于BsClient的内容,我们稍后再讲

基类CefLifeSpanHandler中有很多方法可供重载。

包括:

弹窗之前的事件、浏览器窗口创建成功后的事件、执行模态窗的事件、关闭窗口之前的事件

(虽然这里叫事件,但其实是方法,只不过CEF会自动调用这些方法)

我们在这个类中重写了OnAfterCreated方法(浏览器窗口创建成功后的事件),

在这个方法中,我们调用了BsClient实例的Created方法,

并且把browser实例当作参数传递给了这个方法

这里的browser其实就是我们创建出来的浏览器核心,可以通过它获取浏览器的窗口句柄。

五:

我们在上一篇文章中,创建了一个BrowserClient类,这个类继承自CefClient。

但我们并没有给这个类任何实现,只是在调用CefBrowserHost.CreateBrowser方法时,传递了这个类的一个实例

现在,我们把这个类放到bs文件夹中去,并改名为BsClient,为这个类增加如下实现代码:

publicclassBsClient:

CefClient

{

publiceventEventHandlerOnCreated;

privatereadonlyCefLifeSpanHandlerlifeSpanHandler;

privatereadonlyCefDownloadHandlerdownloadHandler;

publicBsClient()

{

lifeSpanHandler=newBsLifeSpanHandler(this);

downloadHandler=newBsDownloadHandler();

}

protectedoverrideCefLifeSpanHandlerGetLifeSpanHandler()

{

returnlifeSpanHandler;

}

protectedoverrideCefDownloadHandlerGetDownloadHandler()

{

returndownloadHandler;

}

publicvoidCreated(CefBrowserbs)

{

if(OnCreated!

=null)

{

OnCreated(bs,EventArgs.Empty);

}

}

}

在这个类中,我们重写了GetLifeSpanHandler和GetDownloadHandler方法,

这样,我们前面创建的BsLifeSpanHandler和BsDownloadHandler才会物尽其用。

还可以在这里重写很多方法,

比如:

GetContextMenuHandler(右键菜单句柄),GetDialogHandler(对话框句柄)GetKeyboardHandler(键盘句柄)等

在这个类中我们还公开了一个OnCreated的事件,Created方法会调用这个事件。

而这个方法,是在BsLifeSpanHandler类中被调用的。

也就是说,当浏览器创建完成时,OnCreated事件会被触发。

六:

我们在bs文件夹下创建一个类BsCtl

这个类就是我们的浏览器控件,

先来看一下这个类唯一的构造函数:

publicBsCtl(Controlctl)

{

parent=ctl;

varcwi=CefWindowInfo.Create();

cwi.SetAsChild(parent.Handle,newCefRectangle(0,0,parent.Width,parent.Height));

varbc=newBsClient();

bc.OnCreated+=bc_OnCreated;

varbs=newCefBrowserSettings(){};

CefBrowserHost.CreateBrowser(cwi,bc,bs,"

parent.SizeChanged+=parent_SizeChanged;

}

你会发现,上一篇文章中的几行核心代码,都搬到这里来了。

构造函数的参数ctl,是一个windows控件,一般是个panel之类的容器控件,

我们创建的浏览器窗口就将呈现在这个容器控件内

同时,我们为这个容器控件注册了SizeChanged事件

也为BsClient注册了OnCreated事件。

我们在创建默认浏览器的时候,指定了它的默认主页(就是我的博客)

你如果不想这么办,你可以指定它为:

about:

blank

----------------------------

下面我们看一下这两个事件的实现代码

voidbc_OnCreated(objectsender,EventArgse)

{

bs=(CefBrowser)sender;

varhandle=bs.GetHost().GetWindowHandle();

ResizeWindow(handle,parent.Width,parent.Height);

}

voidparent_SizeChanged(objectsender,EventArgse)

{

if(bs!

=null)

{

varhandle=bs.GetHost().GetWindowHandle();

ResizeWindow(handle,parent.Width,parent.Height);

}

}

在浏览器创建成功的事件中,我们把浏览器的实例保存成了私有属性

他是一个核心对象,以后有很多地方会用到。

我们通过bs.GetHost().GetWindowHandle();来获得浏览器窗口的句柄。

有了这个句柄,我们就可以重置浏览器窗口的大小,使他随着主窗体的大小变化而变化

--------------------------------

下面来看一下ResizeWindow方法的代码:

[DllImport("user32.dll")]

[return:

MarshalAs(UnmanagedType.Bool)]

publicstaticexternboolSetWindowPos(IntPtrhWnd,IntPtrhWndInsertAfter,intX,intY,intcx,intcy,uintuFlags);

privatevoidResizeWindow(IntPtrhandle,intwidth,intheight)

{

if(handle!

=IntPtr.Zero)

{

NativeMethod.SetWindowPos(handle,IntPtr.Zero,

0,0,width,height,

0x0002|0x0004

);

}

}

在ResizeWindow方法中,通过PInvoke方式调用了windowsapi的方法,来设置浏览器窗口的位置和大小

其中0x0002相当于SWP_NOMOVE;0x0004相当于SWP_NOZORDER

---------------------------

在这个类中,还有一个方法,代码如下:

publicvoidLoadUrl(stringurl)

{

bs.GetMainFrame().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.Windows.Forms.AnchorStyles.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.Windows.Forms.AnchorStyles.Bottom)

this.StatusContainer.Anchor=((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom|System.Windows.Forms.AnchorStyles.Left)

------------------------------------------

经过前面的一系列工作,我们主窗口的代码就精简了很多

publicpartialclassDemo:

Form

{

BsCtlbs;

publicDemo()

{

InitializeComponent();

this.Name="CefBrowser";

this.Text="最简单的实现";

}

privatevoidCefBrowser_Load(objectsender,EventArgse)

{

bs=newBsCtl(BrowserContainer);

}

privatevoidGoBtn_Click(objectsender,EventArgse)

{

if(!

string.IsNullOrWhiteSpace(AddressTB.Text))

{

bs.LoadUrl(AddressTB.Text);

}

}

}

在窗口加载成功后,我们创建了浏览器的实例(创建时把浏览器容器传递给了构造函数),

当点击GO按钮的时候,切换了浏览器的地址。

-------------------------------------------------

最终的效果如下(浏览器窗口的大小会随着主窗口的大小而变化)

源码下载:

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

当前位置:首页 > 人文社科 > 军事政治

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1