我的玻璃盒子

WTL不完全窗口换肤技术

2013-2-5:注意!示例代码有严重的GDI内存泄露!请在实际使用过程中注意解决!这代码是我5年前写的了,当时可能没有注意到,我有空更新一下源码。

本文介绍了基于WTL框架的一种换肤方法,可以实现对话框或框架窗口的换肤。

给窗口换肤的方法有很多种,原理基本相同,无非就是对非客户区的重绘。只不过在实现手段上有很多种方式。本文介绍的是其中一种较简单和易于理解的方式。即对某个窗口句柄进行子类化操作,使该窗口的非客户区绘制被我们的代码所替换,从而实现换肤操作。

下图是我们进行换肤后的SDI窗口:
效果图

下面就实现的主要步骤做一些简单的说明:

一、我们首先创建自己的换肤窗口类,继承于CWindowImpl,并指定我们需要的窗体风格。例如:

typedef CWinTraits<WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX> CXuTraits;
class CXuSkinWindow : public CWindowImpl<CXuSkinWindow, CWindow, CXuTraits>


二、然后我们需要处理一些关键的消息,例如WM_NCPAINT、WM_ACTIVATE、WM_NCACTIVATE、WM_NCHITTEST、WM_SIZE等等。

三、我们还要提供一个方法,接收一个窗口的句柄,用于子类化换肤。例如:void EnableWindowFrame(HWND hWnd);

四、当然,我们的换肤图片、颜色绘制都离不开GDI。在我的示例程序里,封装了图片绘制的类,用于进行图片拉伸绘制、去透明背景色绘制等方法。(源码在我的blog中另外两篇文章中也有公布)

五、另外,图片和颜色值都是从INI文件中读取,这样方便实现动态换肤。


一些提示

1、绘制窗口非客户区主要分为四个部分:标题(需要拉伸绘制),左边框,右边框,底边框。我们在非客户区绘制消息中去分别绘制这四部分就好了。绘制的范围需要根据当前窗口的大小来计算好。

2、Windows标准主题、XP主题以及Vista窗口在绘制上有一些区别,主要是窗口的标题栏高度、边框宽度有些不同,需要根据情况动态判断,以适应各种主题下的显示。

示例工程(VC6 + WTL 7.0):Source Codes, Binary files and Theme files

posted on 2008-01-17 22:51 深蓝色系统 阅读(2933) 评论(7)  编辑 收藏 引用 所属分类: WTL

评论

# re: WTL不完全窗口换肤技术 2008-05-30 16:38 jom

感谢你的代码,3Q Very much.  回复  更多评论   

# re: WTL不完全窗口换肤技术 2008-05-30 16:47 jom

朋友,你好。运行以上源码的时候出现下列错误,是不是我装漏了什么?SDK,我都装了。

fatal error C1083: Cannot open include file: 'atlgdix.h': No such file or directory  回复  更多评论   

# re: WTL不完全窗口换肤技术 2008-05-30 17:03 jom

还有,运行以后的界面显示重绘的部分。不知道是什么原因。  回复  更多评论   

# re: WTL不完全窗口换肤技术 2008-05-30 17:03 jom

还有,运行以后的界面显示重绘的部分。不知道是什么原因。  回复  更多评论   

# re: WTL不完全窗口换肤技术 2009-03-17 18:08 深蓝色系统

抱歉各位,今天才发现没有把皮肤图片文件提交上来。现在补上了。  回复  更多评论   

# re: WTL不完全窗口换肤技术 2013-05-15 14:33 aeon

标题栏更换文字有问题哦  回复  更多评论   

# re: WTL不完全窗口换肤技术 2013-05-15 14:56 aeon

您好、有QQ吗、、加我
411850446
关于WTL不完全窗口换肤技术:请教一下  回复  更多评论   


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


导航

<2009年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

常用链接

留言簿(75)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜