基於Chromium構建Chrome WebBrowser for .net 控件(還有點心得體會)

http://blog.csdn.net/lllllllllluoyi/article/details/8540054web

首先向360說句sorry,在2011年360極速瀏覽器出現的時候我去他們論壇裏罵過。爲何要到歉呢,由於2012年我把咱們公司使用IE WebBrowser改成Chrome控件了,中間遇到的辛酸使我明白360公司能作成產品確實不容易。言歸正轉,公司的殼程序是C#編寫的WinForm程序,剛開始我只找到delphi的Chromium項目,而後在delphi2010中安裝好控件後就生成DLL讓WinForm程序調用,這種策略是我作這個控件的最大失敗。由於我對delphi比較熟,很快控件就能在WinForm程序裏跑起來了,很開心,立馬根據殼中已經使用的事件和方法在自定義控件中實現,自測一下沒有問題後就交給測試人員來試用,半天的功夫,測試員小張就來對我說:羅兄,網頁中不能使用鍵盤上Tab鍵切換,回車事件響應不了......不會吧,是否是焦點沒有定位到自定義控件中,我第一時間就是這樣想,而後就是反覆的折騰,仍是不行。最後Google了一下,好不容易找到一個讓本身信服的答案,就是win32的消息循環機制與.net消息機制不同,嵌入到WinForm中的VCL控件不能獲得消息。我靠,這還得了,leader還不把我劈了,leader已經吩咐美工全按chrome瀏覽器的樣式來寫了。兵來將擋,水來土淹,我火速Google一個能在.net上跑的版本「CefSharp」  ,下載來看,傻眼了,是C++版的,咋辦?熬夜啃吧!chrome

我分爲了兩個項目,一是libfuncs,爲了使DLL名稱一致,我重命名了CefSharp項目,它負責提供操做瀏覽器的方法和觸發事件;二是cwber,它是自定義的WinForm控件,用於在Form上的佈局,必須引用libfuncs.dll。瀏覽器

源碼地址:https://sourceforge.net/projects/chromewebbrowse佈局

cwber比較簡單,如下是它的代碼:測試

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using libfuncs;

namespace cwber
{
    public partial class ChromeWebBrowser : UserControl
    {
        private ChromeApp chrome = null;
        ToolTip myToolTip = new ToolTip();
        public ChromeWebBrowser()
        {
            InitializeComponent();
            ChromeWebBrowser.CheckForIllegalCrossThreadCalls = false;
        }
        
      

        private void ChromeWebBrowser_Load(object sender, EventArgs e)
        {
            if (chrome == null)
            {
                chrome = new ChromeApp();
            }
            Start();
            
        }

        #region 外部調用方法
        libfuncs.DocumentCompletedEvent elementEvent1;
        libfuncs.FrameLoadStartEvent elementEvent2;
        libfuncs.FrameLoadEndEvent elementEvent3;
        libfuncs.FileDownloadingEvent fileDownloading;
        libfuncs.FileDownloadCompletedEvent fileDownloaded;
        libfuncs.ComponentInitialized componentInitialized;
        libfuncs.ToolTipEventListener toolTipEvent;
        public void Start()
        {
            if (chrome != null)
            {
                chrome.Dock = DockStyle.Fill;
                
                if (componentInitialized == null)
                {
                    componentInitialized = new libfuncs.ComponentInitialized(componentInitializedEvent);
                    chrome.RegisterEvent(componentInitialized);
                }
                Controls.Add(chrome);
                if (elementEvent1 == null)
                {
                    elementEvent1 = new libfuncs.DocumentCompletedEvent(documentComplete);
                    chrome.RegisterEvent(elementEvent1);
                }
                if (elementEvent2 == null)
                {
                    elementEvent2 = new libfuncs.FrameLoadStartEvent(frameStartStart);
                    chrome.RegisterEvent(elementEvent2);
                }
                if (elementEvent3 == null)
                {
                    elementEvent3 = new libfuncs.FrameLoadEndEvent(frameLoadEnd);
                    chrome.RegisterEvent(elementEvent3);
                }
                if (fileDownloading == null)
                {
                    fileDownloading = new libfuncs.FileDownloadingEvent(this.downloading);
                    chrome.RegisterEvent(fileDownloading);
                }
                if (fileDownloaded == null)
                {
                    fileDownloaded = new libfuncs.FileDownloadCompletedEvent(this.downloaded);
                    chrome.RegisterEvent(fileDownloaded);
                }
                if (toolTipEvent == null)
                {
                    toolTipEvent = new libfuncs.ToolTipEventListener(this.ShowToolTipText);
                    chrome.RegisterEvent(toolTipEvent);
                }
                
                chrome.Visible = true;
                chrome.BringToFront();
            }
        }
        /*
         * 描述:釋放瀏覽器
         */
        public void Free()
        {
            elementEvent1 = null;
            elementEvent2 = null;
            elementEvent3 = null;
            fileDownloading = null;
            fileDownloaded = null;
            componentInitialized = null;
            toolTipEvent = null;
            chrome.Dispose();
            chrome = null;
        }
        /*
         * 參數:Url 打開網頁地址
         * 描述:打開網址。
         */
        public void OpenUrl(string Url)
        {
            if (chrome != null)
                chrome.Load(Url);
        }
        /*
         * 參數:id 網頁中的控件元素ID
         * 描述:根據元素ID獲取元素的值,適用於Input,A標籤元素
         */
        public string GetElementValueById(string id)
        {
            return chrome == null ? "" : chrome.GetElementValueById(id);
        }
        /*
         * 參數:id 網頁中的控件元素ID, value 元素新值
         * 描述:爲頁面中元素賦予新值。
         */
        public void SetElementValueById(string id, string value)
        {
            if (chrome != null)
            {
                chrome.SetElementValueById(id, value);
            }
        }

        public delegate void TCallBackElementEventListener();
        private List<libfuncs.ElementEventListener> elementEventList = new List<libfuncs.ElementEventListener>();
        /*
         * 描述:附加元素的偵聽事件。當該元素觸發附加事件時,則執行TCallBackElementEventListener委託方法
         */
        public void AppendElementEventListener(string id, string eventName, TCallBackElementEventListener callFunc)
        {
            libfuncs.ElementEventListener elementEvent = new libfuncs.ElementEventListener(callFunc);
            elementEventList.Add(elementEvent);
            chrome.AddElementEventListener(id, eventName, elementEvent);
        }
        /*
         * 描述:向頁面中注入並執行腳本。
         */
        public void ExecuteScript(string script)
        {
            if (chrome != null)
                chrome.ExecuteScript(script);
        }

        public object EvaluateScript(string script)
        {
            if (chrome != null)
                return chrome.EvaluateScript(script);
            else
                return null;
        }

        /*
         * 描述:計算文件單位。用於文件下載。
         */
        private string CompareFileSize(Int64 size)
        {
            //計算K,M單位
            string strTotalSize = string.Empty;
            if (size < 1024)
            {
                strTotalSize = size.ToString() + " B";
            }
            else if (size >= 1024 && size < 1024 * 1024)
            {
                strTotalSize = (size / 1024).ToString() + " KB";
            }
            else
            {
                strTotalSize = (size / 1024 / 1024).ToString() + " MB";
            }
            return strTotalSize;
        }

        #endregion

        #region 屬性
        public string Url
        {
            get
            {
                return chrome == null?"":chrome.Core.Address;
            }
        }
        #endregion

        #region 事件
        /*控件初始化事件*/
        public event EventHandler ComponentInitializedEventHandler;
        private void componentInitializedEvent()
        {
            EventArgs e = new EventArgs();
            if (ComponentInitializedEventHandler != null)
                ComponentInitializedEventHandler(this, e);
        }
        /*頁面加載完成事件*/
        public event EventHandler DocumentCompletedEventHandler;
        private void documentComplete()
        {
            EventArgs e = new EventArgs();
            if (DocumentCompletedEventHandler != null)
                DocumentCompletedEventHandler(this, e);
        }
        /*Frame加載完成事件,這裏的Frame能夠是頁面自己,也是iFrame元素*/
        public event EventHandler PageLoadFinishEventHandler;
        private void frameLoadEnd()
        {
            EventArgs e = new EventArgs();
            if (PageLoadFinishEventHandler != null)
                PageLoadFinishEventHandler(this, e);
        }
        /*Frame加載開始事件,這裏的Frame能夠是頁面自己,也是iFrame元素*/
        public event EventHandler PageLoadStartEventHandler;
        private void frameStartStart()
        {
            EventArgs e = new EventArgs();
            if (PageLoadStartEventHandler != null)
                PageLoadStartEventHandler(this, e);
        }
        /*下載中事件,不開放該事件*/
        Form downloadForm = null;
        private void downloading(Int64 totalSize, Int64 loadedSize)
        {
            string strTotalSize = CompareFileSize(totalSize);
            string strLoadedSize = CompareFileSize(loadedSize);

            if (downloadForm == null)
            {
                downloadForm = new Form();
                downloadForm.Text = "下載中";
                downloadForm.Width = 280;
                downloadForm.Height = 150;
                downloadForm.MaximizeBox = false;
                downloadForm.MinimizeBox = false;
                downloadForm.ControlBox = false;
                downloadForm.StartPosition = FormStartPosition.CenterScreen;
                

                Label label = new Label();
                label.Left = 20;
                label.Top = 50;
                label.Width = 250;
                label.Text = "已下載:" + strLoadedSize + "/" + strTotalSize;
                downloadForm.Controls.Add(label);
            }
            downloadForm.Show();
            downloadForm.BringToFront();
            foreach (Control c in downloadForm.Controls)
            {
                if (c is Label)
                {
                    Label label = (Label)c;
                    label.Text = "已下載:" + strLoadedSize + "/" + strTotalSize;
                    label.Update();
                }
            }
            downloadForm.Update();
        }
        /*下載完成事件,不開放該事件*/
        private void downloaded()
        {
            if (downloadForm != null)
                downloadForm.Close();
            downloadForm = null;
        }
        /*消息提示事件,不開放*/
        private void ShowToolTipText(string text)
        {
            if (chrome == null) return;
            if (string.IsNullOrEmpty(text))
            {
                myToolTip.RemoveAll();
                return;
            }
            //保證每行40個字
            int len = text.Length;
            int offset = 40;
            int count = len / offset;
            for (int i = 1; i <= count; i++)
            {
                text = text.Insert(offset * i, "\n");
            }
            myToolTip.ShowAlways = false;
            myToolTip.UseAnimation = true;
            myToolTip.UseFading = true;
            //t.SetToolTip(button1, text);
            Point p = Control.MousePosition;
            Point p1 = this.PointToClient(p);
            myToolTip.Show(text, chrome, p1.X+20, p1.Y+10);
        }
        #endregion
    }
}


重點是libfuncs中的libfuncs.h、ChromeApp.h、ChromeApp.cpp、ClientAdapter.h、ClientAdapter.cpp五個文件,實現方法都在裏面,其餘的文件基本都是接口文件。我本身只根據項目實際需求來作的功能,接口沒有所有實現。這個部分你們看源代碼吧,我用到的地方都註釋了。文采不行,寫不動,你們原諒。睡了。this

最後說句,咱們公司網頁美工解脫了!lua

相關文章
相關標籤/搜索