专栏首页liulun基于.net开发chrome核心浏览器【五】

基于.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,也无法提供源码了)

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

谢谢各位!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • typescript里一些有趣的点

    在原生的JS里,null和undefined经常会导致BUG的产生, 在ts里,你又想用null,又担心出错的时候 你可以考虑用联合类型,当某值可能为 nu...

    liulun
  • Nim教程【四】

    这是国内第一个关于Nim的系列教程 先说废话 Screenshot (2).png 高雅的Nim Screenshot (3).png 方法 Screens...

    liulun
  • Nim教程【三】

    这是国内第一个关于Nim的系列教程 (至少我百度和必应是没有找到类似的教程) 先说废话 有人说 Golang的编译器/工具...

    liulun
  • Exceptionless(二) - 使用进阶

    在上一篇文章Exceptionless - .Net Core开源日志框架中就说到如何对Exceptionless进行本地化部署,不过我也跟大家说了,仅限于能用...

    .Net框架学苑
  • PHP实现的敏感词过滤方法示例

    JavaScript正则表达式在线测试工具: http://tools.zalou.cn/regex/javascript

    砸漏
  • Redis的数据结构

    也就是说redis的存储类型 key(string) -- value(string、hash、list、set、zet)

    Devops海洋的渔夫
  • C#中char[]与string之间的转换;byte[]与string之间的转化

    跟着阿笨一起玩NET
  • 《统计学习方法》第八章-提升方法

    在《统计学习方法》中第八章提升方法,包括四节,第一节介绍AdaBoost、第二节介绍AdaBoost的误差、第三节介绍从前向分布算法来实现AdaBoost、第四...

    用户1176270
  • Inotify机制

    Inotify API用于检测文件系统变化的机制。Inotify可用于检测单个文件,也可以检测整个目录。当检测的对象是一个目录的时候,目录本身和目录里的内容都会...

    DragonKingZhu
  • jacoco 生成单测覆盖率报告

    jacoco 是一个开源的覆盖率工具,它针对的开发语言是 java。其使用方法很灵活,可以嵌入到 ant、maven 中;可以作为 Eclipse 插件;可以作...

    JMCui

扫码关注云+社区

领取腾讯云代金券