WINDOWS 换肤的原理及解析

来源:互联网 发布:bim软件nbims 编辑:程序博客网 时间:2024/05/07 18:29

关于软件换肤原理其实非常简单,就是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

原创粉丝点击