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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM