一、背景
最開始準備使用的 Chromely 做一個終端機項目,本來以為挺順利的一個事情折騰了兩天半。由于無法直接控制窗體的屬性,最後還是切換到 .NET Framework 4.8 + CefSharp,記錄一下遇到的坑和問題。
二、問題
2.1 輸入法無法彈出
終端機系統最開始是 Windows 7,系統自帶的輸入法無法輸入中文,後面使用的多文輸入法有時候能夠輸入有時候不能夠輸入。最後折騰了半天,咨詢廠家可以安裝 Windows 10,安裝後系統自帶輸入法可以輸入中文。
新的問題又出現了,如果視窗沒有全屏的情況下,輸入法是可以将内容輸入到網頁的文本框。但是視窗置頂且全屏,觸摸 輸入的内容就像無法擷取焦點一樣,無法輸入。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuMjMwEjNyQzM50SN5QDOzIzMxEDNygDMwIDMy0CM2EzMwITMvwFOwAjMwIzLcBjNxMDMyEzLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
爬了很多網站,都沒有給出個明确的答案,最後在 某篇 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 的對應屬性替換成你自己的實作即可。