現象
我正在使用 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;
}
}
}