看到有些朋友对软件换肤比较感兴趣, 我这里就以我自己的经验分析一下,当人本人不是专门做界面库开发的,所以可能有不些地方讲的不一定正确。

说到换肤就要提到界面库,界面库一般来说分2种,一种是基于传统窗口句柄控件的, 还有一种是基于DirectUI的。

当然比较早的专业界面库都是基于传统窗口句柄控件的,而这种界面库实现换肤的方式一般是基于Hook,大概原理是:
(1)安装窗口过程Hook(如WH_CBT Hook),准备截获应用程序所有窗口的创建事件
(2) 收到窗口创建等消息,根据类名、风格等一些条件来判断是否对该窗口控件进行Subclass
(3)
如果需要则安装相应控件类型的Subclass,窗口Subclass后即可以收到该窗口所有的消息
(4)根据不同的消息进行相应的处理, 根据皮肤类型进行相应的绘画
(5)窗口销毁是进行UnSubclass

用上面这种Hook的方式可以拦截所有系统控件的消息,界面库可以根据当前的皮肤类型进行相应的绘画和处理。
对于使用者来说往往非常简单,我们只要在程序中直接使用系统的标准控件,然后通常只需在程序初始化时调用界面库的一个初始化函数即可实现完整的换肤。
当然要所有换肤的工作量都移到了界面库里,界面库要根据皮肤类型实现所有控件的绘画处理,而且Windows系统的各个版本又各有差异,所以界面库往往会非常复杂。这种方式的优点是使用简单,并且程序的开发语言也没有限制;缺点是界面库复杂性带来的不稳定性。

还有一种对窗口控件实现换肤的方式是用户根据需要,自己Subclass某些控件,
自己根据皮肤风格,自己贴图处理,这种方式被大部分不依赖第三方专业界面库的程序所采用。我前面的截屏小工具就属于这种方式,它的优点是灵活稳定,自己好控制;缺点是开发人员需要一些控件知识和绘画技能,并且也不能跨语言共用。

另外,关于换肤本身,又分不同类型。有的换肤只是简单的改变一下背景图片(颜色), 也有的换肤是改变整个窗口的大小和Region(异形窗口), 还有的换肤还改变了控件的位置,这取决于皮肤的类型设置了哪些东西要变化,变得越多实现越复杂。

最新的界面库一般采用的是DirectUI技术,即按照游戏界面的思想,所有的控件全都画在一个窗口上模拟出来,这种方式的优点是透明度和动画等全都可以自己控制,从而可以实现很炫的界面效果,当然换肤对它来说更是小菜一碟。

我们基本上可以从QQ界面的演变来验证这一趋势,从最早的单一风格窗口,到后来的换肤和异形窗口,再到现在的DirectUI。当然QQ采用DirectUI技术除了实现界面炫方面考虑,应该还有安全方面的考虑。

总的来说DirectUI是趋势,而微软的WPF代表了DirectUI最先进的技术方向,换肤对于DirectUI来说非常容易。随着Win7,Win8 的普及,传统界面库的市场会越来越小,一来因为
系统本身已经很炫了,二来微软自己的WPF和Xaml技术基本上已经可以实现任何想要的效果。当然只要XP不消亡,传统的界面库还是有自己的一席之地。

posted on 2012-08-21 22:33 Richard Wei 阅读(5919) 评论(2)  编辑 收藏 引用 所属分类: windows desktop

FeedBack:
# re: 软件换肤的原理
2013-03-05 08:38 | mike
一直用GDI+做界面开发。win7新增了Direct2D支持。是选择Direct2D sdk开发呢,还是WPF开发?  回复  更多评论
  
# re: 软件换肤的原理
2013-03-05 08:59 | Richard Wei
@mike

这个看产品定位吧?
GDI最通用, 各个系统上都能直接跑;
GDI+稍微有点依赖,但是一般问题不大,开发也方便很多;
D2D性能和效果都不错,如果自己开发DirectUI的界面库可以考虑,另外它也不支持XP;
WPF依赖.net, 程序大小和性能方面都有些限制,但是开发效率和效果都不错。

所以一般来说如果你开发的是通用软件,比如QQ或者迅雷,既要考虑性能还要考虑各个平台的支持,在XP没有消亡之前还是会选择GDI(+)。
如果你做是项目型的管理软件, 要考虑开发效率, 一般会选择WPF。
如果你是自己开发DirectUI界面库, 可以考虑同时支持GDI(+)和Direct2D。
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理