zoukankan      html  css  js  c++  java
  • cefsharp + winform 内嵌网页的触屏输入焦点问题

    原文

    现象

    我正在使用 cefsharp + winform 建立一个桌面程序用于显示网页。但程序启动后触屏点击网页中的输入框,使用键盘输入,文字输入不进去。win + D 最小化程序后,再恢复窗口才能正常输入。

    临时措施

    //在 form loaded 事件里设置焦点
    ChromiumWebBrowser.GetBrowser().GetHost().SetFocus(true);
    

    又出现新问题

    程序在使用过程中,偶尔又会出现输入不进去的问题,win + D 最小化程序后,再恢复窗口才能正常输入。

    可能因为什么操作又丢失了焦点。但 ChromiumWebBrowser.GetBrowser().GetHost() 没有失去焦点事件,找不到好的事机再次使用临时措施(SetFocus)。

    Google 了一圈找到几个方案。

    方案一 FocusHandler(无效)

    browser.FocusHandler 属性设置为 null

    对于我的问题无效。没有解决

    方案二 关闭多线程消息循环(有效

    这个方法对于我的问题有效,即使我不使用临时措施设置 SetFocus ,输入也一切正常。我猜测那个偶发的新问题应该也不会再出现,待后续观察!

    而在官方论坛中这个 bug 被标记为不修复 ,所以即使升级版本也没用,有同样问题的同学可以试试这个方法。

    Program.cs/Main 内

    CefSettings settings = new CefSettings();
    settings.CefCommandLineArgs["multi-threaded-message-loop"] = "0";
    settings.MultiThreadedMessageLoop = false;
    Cef.Initialize(settings);
    Application.Idle += Application_Idle;
    
    //Application_Idle
    private static void Application_Idle(object sender, EventArgs e)
    {
        Cef.DoMessageLoopWork();
    }
    

    方案三 升级内核版本(无效)

    Cefsharp - keyboard not working until refocus

    答案里提到这个问题已经在 version 81 中修复。我目前使用的是 73 版本。

    于是升级到 81.3.10 版本。观察使用了几天,依旧出现偶尔输入不进去的问题

    方案四 设置主程序的 ExStyle(无效)

    继承 ChromiumWebBrowser 重写

    public class MyWebBrowser : ChromiumWebBrowser
        {
            public MyWebBrowser(string address, IRequestContext requestContext = null) : base(address, requestContext)
            {
            }
    
            const uint WS_EX_NOACTIVATE = 0x08000000;
    
            protected override IWindowInfo CreateBrowserWindowInfo(IntPtr handle)
            {
                var info = base.CreateBrowserWindowInfo(handle);
                info.ExStyle &= WS_EX_NOACTIVATE;
                return info;
            }
        }
    

    方案五 提取屏幕键盘(无效)

    之前屏幕键盘是一个control,在主程序的form中显示,现在提取成一个单独项目编译成 exe。设置键盘的窗口不抢焦点,就像输入法界面那样

    但已验证该方案没有效果,但我也保留这个修改,作为键盘的功能优化。

    public partial class KeyboardForm : Form
        {
            public KeyboardForm()
            {
                InitializeComponent();
            }
    
            private const int WS_EX_TOOLWINDOW = 0x00000080;
            private const int WS_EX_NOACTIVATE = 0x08000000;
    
            protected override CreateParams CreateParams
            {
                get
                {
                     const int WS_CHILD = 0x40000000;
                    CreateParams cp = base.CreateParams;
                    cp.ExStyle |= (WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW);
    
                    return cp;
                }
            }
        }
    
  • 相关阅读:
    通过C#的HttpClient模拟form表单请求
    通过Mysql连接ASP.Net Core2.0(Code First模式)
    每天一点产品思考(1):微博是否可以尝试取消点赞数展示?
    Google Analytics 学习笔记四 —— GA的Channels划分规则
    Google Analytics 学习笔记三 —— GA常用术语
    Google Analytics 学习笔记二 —— GA部署
    Google Analytics 学习笔记一 —— GA简介
    java基础知识总结(一)
    java源码解析之String类(二)
    java源码解析之String类(一)
  • 原文地址:https://www.cnblogs.com/ohzxc/p/15750206.html
Copyright © 2011-2022 走看看