基於.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前面三個參數不用多說了
最后一個參數就是你想讓瀏覽器訪問的頁面
注意:這個方法是異步執行的(非阻塞的),也就是說你無法知道什么時候窗口被創建出來,(通過其他方式可以注冊窗口創建成功的事件,以后再講。)

源碼下載:

http://files.cnblogs.com/liulun/CefDemo.zip
注意:為了下載方便,我已經去掉了dll文件夾中的資源和需要引用的類庫

修改記錄:
2013-4-22:創建文章,並完成了一部分內容
2013-4-29:添加了文章的一部分內容,碰到問題停滯不前。
2013-5-02:解決掉問題,更新並添加了大部分內容,修改了文章的排版
2013-5-11:增加了最后一部分內容,修改了排版,通讀文章,糾正錯別字




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM