一:本篇將解決的問題
本章主要為了解決一下幾個問題:
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,也無法提供原始碼了)
接下去,短期內,我估計我不會再更新這個系列了。太忙,太累。
謝謝各位!