zoukankan      html  css  js  c++  java
  • 基于.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前面三个参数不用多说了
    最后一个参数就是你想让浏览器访问的页面
    注意:这个方法是异步执行的(非阻塞的),也就是说你无法知道什么时候窗口被创建出来,(通过其他方式可以注册窗口创建成功的事件,以后再讲。)

    源码下载:

    https://files.cnblogs.com/liulun/CefDemo.zip
    注意:为了下载方便,我已经去掉了dll文件夹中的资源和需要引用的类库

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



  • 相关阅读:
    insert 语句后面的一些参数使用知识
    mysql通信协议的半双工机制理解
    整理超级全局变量与全局变量的知识
    php获取输入流
    插入数据sql使用“insert into set”形式的理解
    《LINUX与UNIX SHELL编程指南》学习笔记
    转载别人空间的一篇好文技术没有转换成生产力
    C# 查找打开的窗口
    sql:inner join,left join,right join,full join的用法及含义
    pc doctor启动到进度条的时候自动退出
  • 原文地址:https://www.cnblogs.com/liulun/p/3035127.html
Copyright © 2011-2022 走看看