天天看點

CefSharp 開發觸屏終端遇到的問題記錄

一、背景

最開始準備使用的 Chromely 做一個終端機項目,本來以為挺順利的一個事情折騰了兩天半。由于無法直接控制窗體的屬性,最後還是切換到 .NET Framework 4.8 + CefSharp,記錄一下遇到的坑和問題。

二、問題

2.1 輸入法無法彈出

終端機系統最開始是 Windows 7,系統自帶的輸入法無法輸入中文,後面使用的多文輸入法有時候能夠輸入有時候不能夠輸入。最後折騰了半天,咨詢廠家可以安裝 Windows 10,安裝後系統自帶輸入法可以輸入中文。

新的問題又出現了,如果視窗沒有全屏的情況下,輸入法是可以将内容輸入到網頁的文本框。但是視窗置頂且全屏,觸摸 輸入的内容就像無法擷取焦點一樣,無法輸入。

CefSharp 開發觸屏終端遇到的問題記錄

爬了很多網站,都沒有給出個明确的答案,最後在 某篇 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 的對應屬性替換成你自己的實作即可。