基於.net開發chrome核心瀏覽器【五】

一:本篇將解決的問題web

本章主要爲了解決一下幾個問題:chrome

1.JsDialog的按鈕錯位的問題瀏覽器

  咱們開發出的瀏覽器,在有些操系統上調用alert,confirm之類的對話框時,肯定和取消按鈕會出現錯位的狀況ide

2.右鍵菜單問題函數

  咱們開發的瀏覽器,在網頁上點右鍵,會出現一些討厭的英文菜單。工具

3.打印的問題spa

  咱們開發的瀏覽器,網頁在調用window.print的時候,沒有任何反應。調試

4.打開chrome的調試器code

  谷歌瀏覽器調試網頁的調試器很是好用,咱們開發的瀏覽器也能夠用這個工具。orm

二:JsDialog的按鈕錯位的問題

先在BS文件夾中新建一個類,取名爲JsDialogHandler,讓這個類繼承自CefJSDialogHandler

而後在這個類中重寫OnJSDialog函數,代碼以下:

protected override bool OnJSDialog(CefBrowser browser, string originUrl, string acceptLang, CefJSDialogType dialogType, string message_text, string default_prompt_text, CefJSDialogCallback callback, out bool suppress_message)
        {
            switch (dialogType)
            {
                case CefJSDialogType.Alert:
                    MessageBox.Show(message_text, "XXX系統提示");
                    suppress_message = true;
                    return false;
                    break;
                case CefJSDialogType.Confirm:
                    var dr = MessageBox.Show(message_text, "XXX系統提示", MessageBoxButtons.YesNo);
                    if (dr == DialogResult.Yes)
                    {
                        callback.Continue(true, string.Empty);
                        suppress_message = false;
                        return true;
                    }
                    else
                    {
                        callback.Continue(false, string.Empty);
                        suppress_message = false;
                        return true;
                    }
                    break;
                case CefJSDialogType.Prompt:
                    MessageBox.Show("系統不支持prompt形式的提示框", "UTMP系統提示");
                    break;
            }
            suppress_message = true;
            return false;
        }

下面咱們來解釋一下代碼中的內容

default_prompt_text參數:

爲prompt類型的dialog服務的(這種dialog能夠接收用戶的輸入,通常已經不多見了,咱們沒有實現這種類型的dialog);

suppress_message參數:

若是這個參數被設置爲true,而且函數返回值爲false,將阻止頁面打開JS的彈出窗口。

若是這個參數被設置爲false,而且函數返回值也是false,頁面將會打開這個JS彈出窗口。

message_text參數:

是彈出窗口將要顯示的內容

dialogType參數:

是彈出窗口的類型(alert,confirm,Prompt)

callback參數:

當用戶點擊了彈出窗口的肯定按鈕,能夠用callback.Continue(true, string.Empty);回調肯定函數

當用戶點擊了彈出窗口的取消按鈕,能夠用callback.Continue(false, string.Empty);回調取消函數

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

在函數內部,咱們使用系統的彈出框替換了CEF的彈出框,從以解決彈出框按鈕顯示的問題。

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

在這個類中還須要重寫兩個虛方法:

OnResetDialogState

此方法能夠取消掉全部即將彈出的對話框,通常在頁面跳轉時會被調用。

OnBeforeUnloadDialog

當用戶離開頁面的時候,彈出的詢問對話框,返回false將使用默認的彈出窗口

這兩個方法只要簡單重寫一下就能夠了。不用有其餘實現

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

這個類建立好以後,要在BsClient類中,增長一個私有屬性

private readonly CefJSDialogHandler jsDialogHandler;

而後在構造函數中爲這個屬性賦值

jsDialogHandler = new JsDialogHandler();

而後重寫父類的一個方法:

        protected override CefJSDialogHandler GetJSDialogHandler()
        {
            return jsDialogHandler;
        }

至此:咱們的jsDialogHandler才能生效。

三:右鍵菜單的問題

要想去掉系統默認的右鍵菜單,

只要實現CefContextMenuHandler的子類

而後重寫OnBeforeContextMenu方法,

下面咱們看看這個方法:

        protected override void OnBeforeContextMenu(CefBrowser browser, CefFrame frame, CefContextMenuParams state, CefMenuModel model)
        {
            model.Clear();
        }

model包括默認的右鍵菜單中的全部的項,若是想不顯示右鍵菜單,只要Clear一下就能夠了

而後和jsDialogHandler同樣,重寫CefClient的 GetContextMenuHandler方法

把這個類的實例返回就能夠了。

四:打印的問題

我是這麼處理的:

在前面提到的OnJsDialog方法中

加入以下代碼

                case CefJSDialogType.Alert:
                    if (message_text.StartsWith("$Print$"))
                    {
                        var str = message_text.Substring(7);
                        var ieb = new IEBrow();
                        ieb.Print(str);
                        ieb.Show();
                        suppress_message = true;
                        return false;
                    }

彈出框的內容前綴若是是「$Print$」就進入打印的流程

(這是多麼蛋疼的作法!!首先window.print是不能用了,只能用alert(「$Print$balabalabala」)。)

ieb是一個iebrowser

裏面的關鍵代碼以下:

        public void Print(string doc)
        {
            webBrowser1.DocumentText = doc;
        }
        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            webBrowser1.Print();
        }

五:打開調試器

想打開調試器,我想看過下面這段代碼你就知道了

        /// <summary>
        /// 顯示調試窗口
        /// </summary>
        public void ShowDevWin()
        {
            try
            {
                if (string.IsNullOrEmpty(devToolsUrl))
                {
                    devToolsUrl = web_view.Browser.GetHost().GetDevToolsUrl(true);
                }
                var frame = web_view.Browser.GetMainFrame();
                //frame.ExecuteJavaScript(string.Format("window.open('{0}');", devToolsUrl), "about:blank", 0);
                var p = Process.Start(devToolsUrl);
            }
            catch
            {
                MessageBox.Show("請等待頁面加載完成以後再打開調試器");
            }
        }

注意!必定要把相關資源放在指定的位置!

六:讓瀏覽器執行JS腳本

        /// <summary>
        /// 執行JS腳本
        /// </summary>
        /// <param name="js">"CreatePage(1,2,3);"</param>
        public void RunScirpt(string js)
        {
            var frame = web_view.Browser.GetMainFrame();
            frame.ExecuteJavaScript(js, frame.Url, 0);
        }

就這樣,很少作解釋了。

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

PS:說明:

再次感謝各位關注這個系列的朋友。

我想大家可能會對這一篇文章比較失望。

(打印那部分雖然官方沒有支持,可是我想確定有更好的辦法解決這個問題,在作項目的時候,我偷懶了,如今寫文章,我又偷懶了。沒有作深刻研究。對不起)

(文章寫的也有點匆忙,寫的不夠詳細,比前幾篇要差多了,我甚至沒有作DEMO,也沒法提供源碼了)

接下去,短時間內,我估計我不會再更新這個系列了。太忙,太累。

謝謝各位!

相關文章
相關標籤/搜索