WINDOWS 换肤的原理及解析

关于软件换肤原理其实非常简单,就是hook + subclass, 替换窗口过程,自己重写界面绘制,基本上就是响应WM_PAINT WM_NCPAINT消息。但难点就在绘制的处理上,Windows标准控件那么多,每个控件的表现形式可不一样。所以基本上所有的工作都集中在控件的消息响应上了。其实,标准控件是很好做的,捧一本msdn基本都可以搞定。难点都集中在滚动条,菜单换肤上。市面上换肤产品多如牛毛,但真正滚动条和菜单换肤上做的很好的真的没几个,在滚动条和菜单上我也是花费了2年的时间研究。这个库从2006年初开始动工,到现在已经3年半多了。一般标准控件的绘制我就不说了,基本查查msdn就可以了。下面我着重说下控件内部滚动条和菜单的换肤原理。

控件的内部滚动条并不是单独的控件,他是Windows窗体(或控件)的组成元素,滚动条换肤的难点就是如何禁止系统绘制,因为滚动条位于非客户区,当滚动条状态改变时系统会进行绘制,所以你无论怎么截获消息,都无法让系统不进行绘制。有些朋友可能用滚动条控件来代替控件内部的滚动条,但这是山寨的做法,弊端也是显而易见的。想让系统不进行绘制,那你必须全权接管滚动条信息的管理和绘制,Windows提供了有关滚动条的API,比如
GetScrollInfo,
SetScrollInfo等等,实际上Windows在内部维护的对用户开放的数据结构仅仅是SCROLLINFO这个结构体而已。那么,我们可不可以自己维护这个ScrollInfo,让用户或系统调用的滚动条相关操作都被我们所控制,我们来响应。答案是肯定的。这又回到之前我们说的原理Hook, 这次需要Hook的是API,
将滚动条的操作转入我们的处理过程,处理后返回给系统。这样就达到了我们的目的。至于API HOOK 方法很多,大家在网上一搜就可以找到一堆。

关于菜单的换肤,有些朋友可能已经知道菜单其实就是一个窗口类名为”#32768”, 所以你可以通过窗口类名来进行Hook了。主要的问题是你怎么才能获取到菜单的句柄呢?对于菜单消息,msdn上只有一个就是MN_GETHMENU, 不错,就是他。给菜单窗口发送这个消息就可以获取菜单句柄。这下好办了,有了菜单句柄,你可以随便操作了, 就这么简单。

还有一个比较难处理的就是窗口标题栏了,因为标题栏在元素改变时,系统也是会进行自绘的。很多换肤库(包括Skin++)的做法就是避开标题栏,把标题栏风格WS_CAPTION去掉,自己再留出一块非客户区再画标题栏,这种方法看似完美,其实弊端很多,对于窗体来说WS_CAPTION是一个很重要的风格。去掉WS_CAPTION系统菜单的很多项目就失效了。另外还有其他方便的弊端,比如在Vista系统下就可能出现系统绘制边框等等。所以作为换肤库,应该尽量避免修改程序的默认属性和风格。换肤库好比人的衣服,不能说衣服不合适,就要把骨头拆了。如何解决这个问题呢?其实有很多方法,比如设置剪裁区,锁定绘制等等。

总结下来,换肤库真正说技术,并没有多么高深,原理道理很简单。经过skinsharp开发,小生收获最多的就是对Windows消息机制的理解,对Windows API的运用等等。当然在牛人面前,小生仍然是个菜鸟。毕竟花了很多心血,所以收费也是有需要的,小生不是大款,说白了就一个it民工。也需要生活,也需要钱。马云说过免费是世界上最昂贵的东西。所以尽量不要免费。等你有了钱以后再考虑免费。虽然不能全部认可,但是还是有道理。
小生也乐意和有这方面兴趣的朋友一起讨论

 

网站:http://www.skinsharp.com

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
目前这方面的软件很多,但大部分都是收费的,不收费大部分又换的不全,对于一个学生来说花钱买是有些奢侈了,所以我一直就想做一个换肤软件提供给学生,让他们做课程设计或毕业设计时能轻易给自己软件美化界面。 但是一直苦于时间有限。工作太忙有时只能在周末或晚上写上两行代码。现在终于成形了本打算开源,但是有些地方还不完善(现只支持VC MFC, Windows Type: Dialog, SDI),所以现在只讲下原理,提供部分源码供感兴趣的人研究。现在发出来与大家共享。 现在商业的换肤软件大部分都是采用的Hook技术(呵呵,猜的,也许采用的更高深的技术)。Hook窗体消息,对窗体消息进行截获最终换成自已的处理方式。所以本人写的SkinMaster也是采用了同样的技术原理。说很简单但做起来有些困难。下面是我做Skin时遇到的问题及处理方式。 1.对于Windows基本控件进行Hook则可完成绘制。 2.对于菜单会制则有些麻烦,程序运行时窗体菜单WM_MEASUREITEM只运行一次,所以会出现在动态换另一套皮肤时菜单项大小不会跟据皮肤改变,解决方法是所有菜单你要动态生成。 3.主窗体的绘制,没啥太深技术就是要处理大量的消息。 4.滚动条的绘制,滚动条全靠Hook消息就没办法完成了,这个东西微软做的不像基本控件那样工作,还要对滚动条的API进行Hook。 先写这些,有时间我会把更详细的方法给大家写出来。下面程序中TestSkin程序提供源码,并完成了按钮等控件的换肤

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值