zoukankan      html  css  js  c++  java
  • NanUI for Winform发布,让Winform界面设计拥有无限可能

    如今,尽管WPF、UWP大行其道,大有把Winform打残干废的趋势。但是还是有那么一波顽固不化的老家伙们固守着Winform,其中就包括我。

    好吧,既然都说Winform做得软件不如WPF界面美观效果绚丽,那么我们就找一个方法让Winform也拥有漂亮的界面。DevExpress和ComponentOne都是不错的选择,Telerik虽说是做Asp.net组件出生的,但是他家的UI for Winform做得也很不错。稍等,那问题来了,这些组件收费昂贵不说,而且是年付,起价都得几百美刀。对于我这种卢瑟程序员来说,是支付不起这样高昂的费用的。那有人要说了,你咋不用破解版的呢?是的,可以用,而且也在用,但是这样一来我的内心是无比纠结的,用破解的盗版的,我就得欠另外那群程序员一大个人情,我这人虽然卢瑟,不喜欢欠别人人情!开个玩笑而已:)那么,有没有什么开源的,免费的,好用的解决方案呢?

    研究了一段时间,本人发现用浏览器做壳用HTML和CSS呈现软件界面是一种新趋势,当然这里指的浏览器不是.net自己带的WebBroswer控件,原因不用我多说,大家都明白。这里说的是大名鼎鼎的CEF——Chromium Embedded Framework,通俗点也就是谷歌浏览器的核心了。CEF作为一个开源的浏览器核心组件对HTML5、CSS3和JS标准的支持不用我过多介绍,都是极好的。目前很多大厂都在使用CEF作为软件界面呈现,比如鹅厂大名鼎鼎的微信桌面版,网易的云音乐等等。所以,如果将CEF引入Winform作为界面呈现也是可行的。

    CEF的.net实现众多,最后相中了CefSharp和ChromimunFX两个开源项目,对比之,CefSharp除了传统的浏览器功能外还实现了离屏渲染,但是作为Winform忠狗的我来说,我并不需要离屏渲染这项高端技术。最终ChromiumFX使用PInvoke的方式调用CEF的API,更接近“原生”,也更利于定制。经过个把月的披星戴月,在ChromiumFX的基础上本人完成了自己的CEF界面封装,暂时命名为NanUI for Winform,目前处于预览阶段。

    那么,下面就来看看本人封装的NanUI完成了什么工作。上图先~~

     

    NanUI for Winform

    NanUI目前处于预览开发阶段,还有一些问题并未解决,因此暂时不传GitHub,等稳定一些会考虑开放源代码。

    目前实现的功能:

    • 无标题窗口
    • 支持css标记-webkit-app-region:drag|nodrag标记
    • 支持网页资源打包内嵌
    • 支持编译Any Cpu类型的项目
    • 其他ChromiumFX该有的功能

    那么,下面分项介绍上面列举的功能。

    无标题窗口

    你以为这里的无标题窗口就是单纯的把FormBorderStyle设置为None吗?当然不是。实现基础是调用DWM的DwmExtendFrameIntoClientArea,然后重绘了下窗口的边框,处理了各种鼠标事件。那有人要问了,那作着些事情不是狗解手吗,直接FormBorderStyle设置个None不就解决了?是的,这是可以解决,但是窗口就丧失了各种投影效果,各种放大缩小的效果。其次,还有各种鼠标消息和HITTEST消息,需要从ChromiumFX中传递到窗体上,要不然ChromiumFX一旦Dock然后Fill到窗口上,窗口还会相应鼠标事件才怪。所以,作为UI的基础,拖拽、放大、缩小等基本的操作都实现了。

    支持css标记-webkit-app-region:drag|nodrag标记

    在网页元素的css里打上“-webkit-app-region:drag”标记,就可以实现拖动该元素来移动窗体。

    如图所示,需要拖动的地方,就是drag,在标记过drag的元素上某些不给拖动的位置(例如关闭,最大化,最小化按钮位置)打上no-drag就拖动不了了。

    其他没标记的地方随意,拖动事件会直接交给JS。

    支持网页资源打包内嵌

    NanUI支持将做好的网页html、css、js、图片等文件直接作为嵌入资源编译到当前项目或者独立的DLL中,框架会自动调用嵌入的网页资源。既然用HTML做界面,HTML暴露在外被别人想改就改,那这个软件跟咸鱼有什么区别?所以网页文件作为内嵌资源功能被作为NanUI的核心功能之一,资源内嵌后,再给程序集加个强命,那要改你的软件就没那么简单了吧。

    支持编译Any Cpu类型的项目

    这也是本人为什么不选择CefSharp的的原因之一,CefSharp只支持编译成单一目标,非常不方便。ChromiumFX能够自动识别客户机环境加载对于的x86或是x64库。在此基础上NanUI扩展了自动下载CEF相关文件的功能,换句话说,发布项目的时候只需要发布项目本身生成的程序和程序集就可以了,软件首次在客户机运行时,会根据客户机的环境自动从指定网络位置下载CEF的相关文件,这样的好处就是软件发布的时候不用在软件本身内置CEF相关文件,极大的减小了打包文件的大小,而且不用去考虑客户机是32位系统还是64位系统,简化发布流程。例如微信Windows客户端,安装包30多兆,其中至少25M是CEF相关文件,而且,微信客户端只有一个x86的版本,NanUI很好的规避了这个问题,文章最后的示例程序可以很好的证明这点。

    其他ChromiumFX该有的功能

    最开始我就说了NanUI基于ChromiumFX开发,ChromiumFX本来应该有什么样的功能,NanUI就支持什么样的功能。要实现网页JS调用C#的类、方法等,C#操作网页DOM元素等,都可以通过ChromiumFX来实现。更多的功能,将会在后面的文章来介绍。

    NanUI的基本功能就是上面说的这些。有了NanUI对Winform程序的支持,想做什么样的界面都可以实现了,不论是模仿个微信Window客户端、网易云音乐,还是模拟下Win10里UWP那种款式的应用都是不在话下的。

    下面,我讲介绍下NanUI的基本使用方法。

    NanUI文件结构

    NetDimension.NanUI.dll
    NetDimension.ZipCompress.dll

    NanUI结构非常简单,“NetDimension.NanUI.dll”封装了ChromiumFX的全部内容并做了一些必要的修改,除此之外的其他内容就是NanUI的核心部分了。“NetDimension.ZipCompress.dll”是一个操作Zip文件的库,内容剽窃自DotNetZip,并做了一些修改。在此特别说明下,不论CEF、ChromiumFX还是DotNetZip都采用BSD开源协议,协议允许我对上述项目进行剽窃、修改和随便用于商业目的,哦呵呵,所以别骂我无耻。

    回归正题,在新建项目中引用“NetDimension.NanUI.dll”库即可。“NetDimension.ZipCompress.dll”仅作为需要远程下载CEF库时做解压ZIP文件用,实际项目中并不需要引用,如果项目发布时已在本地内嵌CEF框架,那么这个解压缩的库不需要随软件分发。

    在此特别说明下CEF框架的文件夹结构:

    fx与程序集放置在同一层级,如果项目编译时特意选择了x86架构或x64架构时,另外一种架构的文件夹是不需要存在的,仅当项目编译类型为any cpu时需要x86和x64文件同时存在,NanUI会根据客户机的运行环境来自动选择加载x86或是x64架构的CEF库。当fx存在的时候NanUI将不会启用CEF库下载的特性,仅当fx文件夹内的CEF框架不存在时,NanUI才会自动从远程服务器下载CEF框架文件。

    接下来,在Main函数中做一些简单的初始化的工作。

    复制代码
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
    
        UIStartupManager.UseSharedFramework = true;
    
        if(UIStartupManager.InitializeChromium(args=> {
            args.Settings.LogSeverity = Chromium.CfxLogSeverity.Default;
            //这里可以对CEF进行一些设定
                    
        },args=> {
            Console.WriteLine(args.CommandLine);
            //输出命令行开关,看看启用或是禁用了哪些功能
        }))
        {
            //初始化成功,加载程序集内嵌的资源到运行时中,当然也可以加载其他程序集里面的资源。
            UIStartupManager.RegisterEmbeddedScheme(System.Reflection.Assembly.GetExecutingAssembly());
    
            //启动主窗体
            Application.Run(new frmWelcome());
        }
    }
    复制代码

    主窗体

    复制代码
    public partial class frmWelcome : HtmlUIForm    //继承HtmlUIForm
    {
        frmAbout aboutForm = null;
        public frmWelcome()
            : base("embedded://www/index.html")    //设定启示页面,scheme是embedded就是我们在Main里注册的当前程序集资源
        {
            InitializeComponent();
    
            //在js中注册一个方法来打开About窗口
            UI.GlobalObject.AddFunction("showAboutForm").Execute += (sender, args) =>
            {
                ShowAboutWindow();
            };
    
    
            //网页加载完成时触发事件
            UI.LoadHandler.OnLoadEnd += (sender, args) =>
            {
                //判断下触发的事件是不是主框架的
                if(args.Frame.IsMain)
                {
                    //执行JS,将当前的CEF运行版本等信息通过JS加载到网页上
                    var js = $"$client.setRuntimeInfo({{ api: ['{CfxRuntime.ApiHash(0)}', '{CfxRuntime.ApiHash(1)}'], cef:'{CfxRuntime.GetCefVersion()}', chrome:'{CfxRuntime.GetChromeVersion()}',os:'{CfxRuntime.PlatformOS}', arch:'{CfxRuntime.PlatformArch}'}});";
                    UI.ExecuteJavascript(js);
                }
                    
    
            };
    
        }
    
        private void ShowAboutWindow()
        {
            //因为当前环境中的JS代码跑在另外的线程上,所以在Control上扩展个UpdateUI方法,简化InvokeRequired流程
            this.UpdateUI(() =>
            {
                //显示字窗体的过程,不解释
                if (aboutForm == null || aboutForm.IsDisposed)
                {
                    aboutForm = new frmAbout();
                    aboutForm.Show(this);
                }
                else
                {
                    aboutForm.Activate();
                }
    
            });
        }
    }
    复制代码

    就是这么简单几步,漂亮的HTML界面加载到了你的Winform上,当然,前提是你得先有个“漂亮”的HTML界面先:)

    好了,就像上面的图片里展示的一样,通过NanUI,Winform同样能够做出像其他两款软件那样的界面了。NanUI的预览版就先介绍到这里。在后续的文章中,我将以项目的形式再来深度的介绍NanUI在Winform中的各种运用。

    下面的会提供上述图片中展示的DEMO程序及源代码提供给有兴趣的朋友下载把玩。

    DEMO是用VS2015在Win10下编写的,.net需要4.5版本(Win10免安装,其他系统自行Google下载安装)能够运行。

    感谢观看,谢谢大家,欢迎拍砖。

    附件:

    Release.rar

    编译后的DEMO程序,不带CEF框架,第一次启动程序自动下载CEF相关文档。CEF将保存到%appdata%Net Dimension StudioNanUI

    Source.rar

    Demo程序的源代码,有兴趣的朋友可下载把玩。

    本文来自:http://www.cnblogs.com/linxuanchen/p/ChromiumFX-based-NanUI-for-Winform-has-been-published.html

  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/bubugao/p/Winform.html
Copyright © 2011-2022 走看看