• CefSharp 开发触屏终端遇到的问题记录


    一、背景

    最开始准备使用的 Chromely 做一个终端机项目,本来以为挺顺利的一个事情折腾了两天半。由于无法直接控制窗体的属性,最后还是切换到 .NET Framework 4.8 + CefSharp,记录一下遇到的坑和问题。

    二、问题

    2.1 输入法无法弹出

    终端机系统最开始是 Windows 7,系统自带的输入法无法输入中文,后面使用的多文输入法有时候能够输入有时候不能够输入。最后折腾了半天,咨询厂家可以安装 Windows 10,安装后系统自带输入法可以输入中文。

    新的问题又出现了,如果窗口没有全屏的情况下,输入法是可以将内容输入到网页的文本框。但是窗口置顶且全屏,触摸 输入的内容就像无法获取焦点一样,无法输入。

    爬了很多网站,都没有给出个明确的答案,最后在 某篇 Issue 里面说将 browser.FocusHandler 属性设置为 null,解决该问题。

    2.2 重写右键菜单

    这个问题比较简单,只需要重新实现 IMenuHandler 接口,替换掉 Cef Browser 的对应组件即可。

    示例:

    public class CustomMenuHandler : IContextMenuHandler
    {
        public void OnBeforeContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
        {
            model.Clear();
    
            model.AddItem((CefMenuCommand) 21000, "菜单项1");
        }
    
        public bool OnContextMenuCommand(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId,
            CefEventFlags eventFlags)
        {
            if (commandId == (CefMenuCommand) 21000)
            {
                MessageBox.Show("我是菜单项1");
            }
            return false;
        }
    
        public void OnContextMenuDismissed(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame)
        {
        }
    
        public bool RunContextMenu(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model,
            IRunContextMenuCallback callback)
        {
            return false;
        }
    }
    

    2.3 身份证读卡器对接

    身份证读卡器终端机上面是集成新中新的,跟着 SDK 的 Demo 来,一跑程序就炸。没有跑出任何异常,最后发现是 Chromely 吞掉了异常。实际的错误问题是 DLL 的版本不对,新中新只提供了 x86 的 DLL,但程序编译的是 x64。最后将程序的目标平台改为 x86 解决问题。

    2.4 前端同后端通讯

    其实就是 JS 调用后端的接口,之前搜索的文章都是 CefSharp 的老版本代码,最新的是使用 browser.JavascriptObjectRepository.Register() 注入处理器,然后前端再进行调用。具体代码可以参考 CefSharp 的 官方 Demo

    2.5 打开调试窗口

    CefSharp Browser 提供了一个 ShowDevTools() 方法用于打开调试窗口,需要注意的是,必须在浏览器完全初始化之后才能够调用。所以你需要判断一下 CefSharp Browser 的状态。

    browser.IsBrowserInitializedChanged += (sender, args) =>
    {
        if (browser.IsBrowserInitialized)
        {
            browser.ShowDevTools();
        }
    };
    

    2.6 关于触屏的其他配置

    在 Cef 初始化的时候,需要对 Cef 进行一些其他的配置,例如开启触屏事件、禁用 USB 键盘等。

    private static void InitializeCef()
    {
        CefSharpSettings.LegacyJavascriptBindingEnabled = true;
        CefSharpSettings.SubprocessExitIfParentProcessClosed = true;
    
        Cef.EnableHighDPISupport();
    
        var settings = new CefSettings();
        settings.CefCommandLineArgs.Add("disable-usb-keyboard-detect", "1");
        settings.CefCommandLineArgs.Add("enable-media-stream", "1");
        settings.CefCommandLineArgs.Add("touch-events", "1");
    
        Cef.Initialize(settings);
    }
    

    2.7 允许前端跨域和调用摄像头

    在 [2.6](#2.6 关于触屏的其他配置) 一节中,我通过添加 enable-media-stream 参数让前端可以直接调用摄像头。如果想要让前端发起跨域请求,就得在 Browser 里面将 WebSecurity 属性设置为 Disabled

    browser.BrowserSettings.WebSecurity = CefState.Disabled;
    

    2.8 下载文件

    CefSharp 针对于前端的下载文件动作进行了处理,如果你对于这个动作有自己的处理逻辑,可以实现 IDownloadHandler 接口。然后在 Browser 的对应属性替换成你自己的实现即可。

  • 相关阅读:
    怎么才能学好php
    MySQL: ON DUPLICATE KEY UPDATE 用法 避免重复插入数据
    RabbitMQ挂掉问题处理
    页面出现假死的问题
    memkeys 安装时遇到的问题及解决办法
    php 中的$argv与$argc
    PHPExcell单元格中某些时间格式的内容不能正确获得的处理办法
    php中的后期静态绑定("Late Static Binding")
    mybatis从零阅读(一)大纲
    windows 命令
  • 原文地址:https://www.cnblogs.com/myzony/p/13552902.html
Copyright © 2020-2023  润新知