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


一:本篇將解決的問題

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

1.JsDialog的按鈕錯位的問題

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

2.右鍵菜單問題

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

3.打印的問題

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

4.打開chrome的調試器

  谷歌瀏覽器調試網頁的調試器非常好用,我們開發的瀏覽器也可以用這個工具。

二: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,也無法提供源碼了)

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

謝謝各位!


免責聲明!

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



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