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

本篇我们讲解怎么用CefGlue开发一个最简单的浏览器

一:

CefGlue是建立在Cef项目之上的, Cef项目是C/C++的项目; CefGlue只不过是通过PInvoke来访问Cef项目生成的一些dll 下面我们来看看Cef项目生成的一些dll和资源都是做什么用的 打开这个目录\cef_binary_3.1453.1236_windows_xilium\Release libcef.dll-------------------------->Cef的核心类库 icudt.dll-------------------------->支持unicode的类库 ffmpegsumo.dll------------------>支持音频和视频的类库 d3dcompiler_43.dll--------------->WinXP下支持3D的类库 d3dcompiler_46.dll--------------->Win7和之后的Win支持3D的类库 libEGL.dll------------------------->用于支持3D libGLESv2.dll--------------------->用于支持3D

打开目录:\cef_binary_3.1453.1236_windows_xilium\Resources locales--------------------------->此文件夹存放了各种国家的语言资源 cef.pak-------------------------->为WebKit相关的资源(谷歌浏览器的核心是webkit) devtools_resources.pak--------->调试器的相关资源(我们做的项目是可以使用谷歌浏览器的调试器的)

二:

建立一个winform工程,取名加CefDemo 在程序集中创建一个文件夹取名dll 在程序集的属性里设置此程序集的预先生成事件的命令

xcopy $(ProjectDir)dll $(TargetDir) /e /i /y

这个命令的目的是:每次编译的时候把dll文件夹中的文件拷贝的输出目录中

把\cef_binary_3.1453.1236_windows_xilium\Release此目录下的所有文件都拷贝到CefDemo的dll目录中去 把\cef_binary_3.1453.1236_windows_xilium\Resources此目录下的所有文件和文件夹拷贝到dll目录中去 注意:locales子目录下的文件大部分都没有用,你可以把所有的文件都删掉,只留下zh-CN.pak文件。 打开Xilium.CefGlue工程,release编译CefGlue程序集,把生成的Xilium.CefGlue.dll也拷贝到CefDemo的dll目录中去 在CefDemo项目中添加Xilium.CefGlue.dll的引用

三:

修改Program.cs的代码:

        static void Main()
        {
            CefRuntime.Load();
            var mainArgs = new CefMainArgs(new string[] { });
            var exitCode = CefRuntime.ExecuteProcess(mainArgs, null);
            if (exitCode != -1)
                return;
            var settings = new CefSettings
            {
                SingleProcess = false,
                MultiThreadedMessageLoop = true,
                LogSeverity = CefLogSeverity.Disable,
                Locale = "zh-CN"
            };
            CefRuntime.Initialize(mainArgs, settings, null);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (!settings.MultiThreadedMessageLoop)
            {
                Application.Idle += (sender, e) => { CefRuntime.DoMessageLoopWork(); };
            }
            Application.Run(new CefBrowser());
            CefRuntime.Shutdown();
        }

我们来一点一点解释这些代码:

CefRuntime.Load(); 此行代码用于加载CEF的运行时 ———————————————————————— var mainArgs = new CefMainArgs(new string[] { }); 此行代码可以收集命令行参数,用于传递给CEF浏览器 ———————————————————————— var exitCode = CefRuntime.ExecuteProcess(mainArgs, null); if (exitCode != -1) return; 以上代码用于启动第二个进程,至于用第二个进程做什么,我没有深入研究过(可以是浏览器的第二个进程、也可以是一个可执行文件的) 注意:CefRuntime.ExecuteProcess方法必须在程序的入口处调用; —————————————————————————— var settings = new CefSettings { SingleProcess = false, MultiThreadedMessageLoop = true, LogSeverity = CefLogSeverity.Disable, Locale = "zh-CN" }; CEF的配置参数,有很多参数,我们这里挑几个解释一下: SingleProcess = false:此处目的是使用多进程。 注意:强烈不建议使用单进程,单进程不稳定,而且Chromium内核不支持 MultiThreadedMessageLoop = true:此处的目的是让浏览器的消息循环在一个单独的线程中执行 注意:强烈建议设置成true,要不然你得在你的程序中自己处理消息循环;自己调用CefDoMessageLoopWork() Locale = "zh-CN":webkit用到的语言资源,如果不设置,默认将为en-US 注意:可执行文件所在的目录一定要有locals目录,而且这个目录下要有相应的资源文件 —————————————————————————————— CefRuntime.Initialize(mainArgs, settings, null); 这句代码把创建的配置信息和命令行信息传递个cef的运行时 此函数必须在应用程序的主线程中调用 —————————————————————————————— if (!settings.MultiThreadedMessageLoop) { Application.Idle += (sender, e) => { CefRuntime.DoMessageLoopWork(); }; } 如果你在前面设置的MultiThreadedMessageLoop为false, 那么你可以加入如上代码,自行调用CefRuntime.DoMessageLoopWork(); —————————————————————————————— CefRuntime.Shutdown(); 主进程结束时,要释放CEF的资源,并结束浏览器的进程。

四:

在工程中创建一个窗体, 在设计视图中,把窗口调整到合适的大小 (你想让浏览器变成多大,就调整到多大) 然后我们调整一下这个窗体的一些属性

            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "CefBrowser";
            this.Text = "最简单的实现";

在这篇文章提供的例子,还没有实现浏览器随着容器窗体的大小变化而变化 所以:我们在这里禁用了窗口的最大化功能,也禁用了拖动改变窗口大小的功能。

五:

在窗口的构造函数中加入如下代码:

var cwi = CefWindowInfo.Create();
cwi.SetAsChild(this.Handle, new CefRectangle(0, 0, this.Width, this.Height));
var bc = new BrowserClient();
var bs = new CefBrowserSettings() { };
CefBrowserHost.CreateBrowser(cwi,bc, bs,"http://www.cnblogs.com/liulun");

然后运行程序,你就看到了一个浏览器,如下图:

六:

下面我们来详细解释一下上面几句代码的意义

CefWindowInfo是CEF浏览器窗口实现的类,其中包含了在windows、linux、MAC下的具体实现 此类中的Create静态方法负责创建这个类的实例, 我在windows下执行这一句,将得到windows下CEF浏览器的实现方式 ------------------ cwi.SetAsChild(this.Handle, new CefRectangle(0, 0, this.Width, this.Height)); 此行代码负责把创建的CEF浏览器窗口与我们创建的winform窗口结合起来 this.Handle就是我们创建的winform窗口的句柄 SetAsChild函数使CEF浏览器窗口作为winform窗口的子窗口呈现 CefRectangle标志着CEF浏览器窗口将出现在父窗口中的位置和大小 ------------------- var bc = new BrowserClient(); BrowserClient是我在工程中新建的一个类 这个类没有任何逻辑和属性,只是继承了CefClient类 CefClient类有很多虚方法以供重写, 比如GetDisplayHandler、GetDownloadHandler、GetJSDialogHandler等等 注意:此类很重要,我们将在接下来的章节中为这个类添加很多内容 --------------------- var bs = new CefBrowserSettings() { }; 之前我们在Program中设置的是CefSettings 那是针对CEF环境的一些全局设置 这里是CefBrowserSettings 这是针对CEF浏览器环境的一些全局设置 可以在这里配置的参数有很多 比如: DefaultEncoding(用于所有网页内容的编码方式,默认为ISO-8859-1) UserStyleSheetLocation(用于所有网页的样式,应该按照这样的格式设置这个字段:data:text/css;charset=utf-8;base64,[csscontent]) RemoteFonts(用于所有网页的字体) JavaScript(用于所有网页是否可以执行JS脚本) JavaScriptOpenWindows(用于所有网页是否可以通过JS来打开窗口) (还有很多类似的设置,读者可以自己去研究) ---------------------------- CefBrowserHost.CreateBrowser(cwi,bc, bs,"http://www.cnblogs.com/liulun"); 代码执行到这一行即开始创建浏览器子窗口 CreateBrowser前面三个参数不用多说了 最后一个参数就是你想让浏览器访问的页面 注意:这个方法是异步执行的(非阻塞的),也就是说你无法知道什么时候窗口被创建出来,(通过其他方式可以注册窗口创建成功的事件,以后再讲。)

源码下载 注意:为了下载方便,我已经去掉了dll文件夹中的资源和需要引用的类库

修改记录: 2013-4-22:创建文章,并完成了一部分内容 2013-4-29:添加了文章的一部分内容,碰到问题停滞不前。 2013-5-02:解决掉问题,更新并添加了大部分内容,修改了文章的排版 2013-5-11:增加了最后一部分内容,修改了排版,通读文章,纠正错别字

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏守望轩

Visual Studio 2008 每日提示(十)

#91、查找组合框的一些有趣的用法 原文链接:How to have fun with the Find Combo Box 操作步骤: 按Ctrl+D 转...

36770
来自专栏我和未来有约会

基于Cairngorm的Silverlight开发 - part5

搭建完整的Cairngorm项目 到这里已经都知道了如何独立的运用Cairngorm中两个特殊的部分,ModelLocator模型和View视图,现在需要的就是...

36750
来自专栏大数据钻研

前端开发必备!Emmet使用手册

介绍 Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的一个工具: 基本上,大多数的文本编辑器都会允许你存储和重用一些代码块,我们称...

40880
来自专栏Jerry的SAP技术分享

关于SAP UI5数据绑定我的一些原创内容

第6篇文章:https://blogs.sap.com/2015/10/25/how-i-do-self-study-on-a-given-fiori-cont...

17650
来自专栏破晓之歌

前端开发必备!Emmet使用手册 转

Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的一个工具:

8210
来自专栏网站源码

博客复制弹窗提示版权

CSS与JS文件配套下载:https://www.lanzous.com/i1j8ppi

28340
来自专栏西安-晁州

vuejs、eggjs、mqtt全栈式开发设备管理系统

vuejs、eggjs、mqtt全栈式开发简单设备管理系统 业余时间用eggjs、vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展...

3K70
来自专栏技术博客

ExtJs九(ExtJs Mvc用户管理之一)

首先要做的是为用户信息创建一个模型,在Scripts\app\model目录下创建一个名为User.js的文件,然后添加以下模型定义代码:

12520
来自专栏全沾开发(huā)

如何从0开发一个Atom组件

如何从0开发一个Atom组件 最近用Atom写博客比较多,然后发现一个很严重的问题。。 没有一个我想要的上传图片的方式,比如某乎上边...

37650
来自专栏自动化测试实战

获取响应头与发送头

48560

扫码关注云+社区

领取腾讯云代金券