終於封裝完成了,採用離屏渲染方式,支援JS和C#互相呼叫,C#方法自動繫結到JS裡,中文輸入有自動調整輸入法位置。
基於開源的CefGlue 移植,本來想用CefSharp,不過這個裡面有很多C++的,而且很多程式碼還是基於Windows編寫的,不好移植成跨平臺的。
不過CefGlue 裡的功能不夠完善,沒有帶JS遠端呼叫功能,Cef是多程序的,JS呼叫需要在渲染程序,那就需要主程序傳送訊息給渲染程序來呼叫JS,還要把呼叫結果傳送回主程序,很麻煩。我這邊是採用管道通訊。
C#註冊方法到JS裡的時候,需要先反射獲取方法名,根據方法名註冊到JS裡,註冊之後的方法在被呼叫的時候,渲染程序會有回撥,把回撥裡的引數和資料資訊傳送到主程序,再根據引數以及反射獲取的C#方法的引數型別對比,並轉換為相應的C#資料型別,再呼叫該C#方法,最後還要把C#呼叫的結果返回到渲染程序。現在只做了常用的資料型別轉換,比如 string,int,double等這些,其他型別轉換暫時不支援。
封裝不同系統平臺,有很多細節不同,有很多坑,比如:
1、MultiThreadedMessageLoop 在Mac裡不支援,那你就需要另外搞個Timer,不斷呼叫DoMessageLoopWork
2、由於Mac裡的特殊的程序機制,你還需要在CommandLine呼叫SetProgram設定程式路徑,否則無法啟動子程序,關鍵子程序還自帶工作列圖示,你還需要想辦法把子程序工作列圖示隱藏,cef預設例子裡就是靠多個程式目錄,裡面配置Info.plist為後臺程序來隱藏子程序圖示。
3、Linux裡的話,還需單獨設定CommandLine 禁用GPU,設定no-zygote
4、Mac裡必須將鍵盤事件的Characters和UnmodifiedCharacter傳給cef,否則還沒法觸發事件,另外還必須用系統的原生KeyCode設定給cef的鍵盤事件的NativeKeyCode,而Windows和Linux是設定WindowsKeyCode
5、Xamarin.Mac裡有個坑,你無法繼承NSApplication重寫並增加方法屬性,由於CPF.Mac採用的是精簡版的Xamarin.Mac,而Xamarin.Mac採用的是繫結原生API的方式實現的,但是對NSApplication的子類沒有實現自動註冊功能,就是你繼承擴充套件的子類無法在Object-C裡獲取到對應的物件。而cef在Mac端要求主程式的NSApplication增加IsHandlingSendEvent屬性,沒有這個屬性就無法執行,好在Object-C支援類的動態增加屬性,手動呼叫註冊屬性就好了
6、cef裡封裝的輸入法搞的真麻煩,明明只要提供個獲取游標位置的介面就行,卻還搞個拼寫過程輸入效果,不呼叫這些介面還無法觸發獲取游標位置的回撥,本來這個功能輸入法提供就行的,cef裡搞這個功能很坑,尤其是文字框限制字元數量的時候,比如文字框限制最大字元數是2,那你輸入中文的時候,用拼音輸入,就無法直接完整的拼寫完兩個中文字元,因為這個長度限制還會限制拼寫過程的字母數量。好在可以規避掉這個拼寫功能。
去 https://cef-builds.spotifycdn.com/ 下載cef二進位制檔案有個大坑,就是Linux的libcef.so檔案都是1個G的,太大了,估計是配置檔案寫錯了,就只能自己編譯過。其他系統平臺的都只有100多M。
最終封裝成cpf的控制元件使用就很方便了,案例原始碼:http://cpf.cskin.net/Item/19