博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于.net开发chrome核心浏览器【五】
阅读量:6201 次
发布时间:2019-06-21

本文共 5009 字,大约阅读时间需要 16 分钟。

原文:

一:本篇将解决的问题

本章主要为了解决一下几个问题:

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();        }

五:打开调试器

想打开调试器,我想看过下面这段代码你就知道了

///         /// 显示调试窗口        ///         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脚本

///         /// 执行JS脚本        ///         /// "CreatePage(1,2,3);"        public void RunScirpt(string js)        {            var frame = web_view.Browser.GetMainFrame();            frame.ExecuteJavaScript(js, frame.Url, 0);        }

就这样,不多做解释了。

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

PS:说明:

再次感谢各位关注这个系列的朋友。

我想你们可能会对这一篇文章比较失望。

(打印那部分虽然官方没有支持,但是我想肯定有更好的办法解决这个问题,在做项目的时候,我偷懒了,现在写文章,我又偷懒了。没有做深入研究。对不起)

(文章写的也有点匆忙,写的不够详细,比前几篇要差多了,我甚至没有做DEMO,也无法提供源码了)

接下去,短期内,我估计我不会再更新这个系列了。太忙,太累。

谢谢各位!

转载地址:http://tmxca.baihongyu.com/

你可能感兴趣的文章
Ruby 2.5.0概览
查看>>
使用Ballerina构建API网关
查看>>
dockerfile的expose
查看>>
【Mockplus教程】为什么删除多个页面的时候会有提示,如何取消提示?
查看>>
控制器中添加DB类才可以操作数据库表中的数据
查看>>
JS-面向对象
查看>>
zabbix在configure时候遇到的问题
查看>>
大公司都有哪些开源项目~~~简化版
查看>>
GIIS2017亿欧零售峰会:创业者和投资人共话产业新常态
查看>>
API网关为K8S容器应用集群提供强大的接入能力
查看>>
录取通知书玩出新花样,西工大加入AR技术
查看>>
“互联网+”农技推广让种地更简单
查看>>
Win10 Cloud会是微软的又一昏招?它会重蹈WinRT覆辙吗?
查看>>
WordPress能承载多大的数据?文章十万百万能承载吗?
查看>>
【IT背包客】第四期:CIO们的春游记
查看>>
PostgreSQL各命令行工具功能说明
查看>>
spring-编程式事务管理
查看>>
Linux系统怎么查看网卡的UUID
查看>>
NFS详细介绍与企业应用场景结合案例
查看>>
【李沐】十分钟从 PyTorch 转 MXNet
查看>>