6

C#搞跨平台UI,封装Cef作为Cpf的控件支持Windows,Linux,Mac

 2 years ago
source link: https://www.cnblogs.com/dskin/p/14872520.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
C#搞跨平台UI,封装Cef作为Cpf的控件支持Windows,Linux,Mac - DSkin - 博客园

随笔- 18  文章- 0  评论- 261  阅读-

13万 

终于封装完成了,采用离屏渲染方式,支持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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK