先说一下,我学到的方法,后面再说问题
原理:利用钩子截获窗口消息,再用子类化技术,使用自己的窗口类,实现换肤
方法:
1、在App类中安装钩子:
1 2 3 4 5 | hWndHook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, NULL, GetCurrentThreadId()); CallWndProc是系统的回调函数,它可以截获窗口消息 |
2、CallWndProc的具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) { if(nCode < 0) return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); switch(nCode) { case HC_ACTION: switch(((CWPSTRUCT*)lParam)->message) { case WM_CREATE: BeginSubclassing(((CWPSTRUCT*)lParam)->hwnd); break; case WM_DESTROY: EndSubclassing(((CWPSTRUCT*)lParam)->hwnd); break; } break; } return CallNextHookEx(hWndHook, nCode, wParam, lParam); } |
别忘了在窗口销毁的时候进行取消子类化!BeginSubclassing和EndSubclassing都不是API,具体实现请参见文后的源码
3、最后在ExitInstance中UnhookWindowsHookEx就行了
运行的效果如图:
可能大家觉得我基本上没怎么讲解这个代码。其实我的重点不是在这个方法上,因为这个方法比较有缺陷。
我也是从vckbase的一篇文章上学的,但是我还没看完就急着自己去做了,过了好久才发现,我遇到的问题,同那上面提到的完全一样!
问题一:重复子类化问题
比如在InitDlg中添加了用CButton类动态产生按钮的代码,就不能运行了。因为它已经Attach了一遍,后来又在BeginSubclassing中Attach一遍,所以会出去问题。那作者给的解决办法是,把换肤的代码弄到dll中。
但是这样,还是有问题
问题二:
MessageBox的按钮、CFileDialog的按钮都消失了!
子类化是成功了的,只是不能显示而已
问题三:
除了按钮外,其它控件也有问题,各种各样,不可预见的问题!
现在该说说,更好的办法了!
这个办法的思路就是,实现各个窗口类的时候,不是从CWnd、CButton直接派生来自绘控件,而是从头实现,自己写窗口过程,自己处理n多消息。这对MFC、Windows底层机制必须要特别熟悉才做得下去了!然后,后面的步骤同以上的方法是一致的
列几篇参考的VckBase的文章:
测试源码下载:
用窗口过程实现换肤的代码下载:


我不是IT行业的,我做这个换肤也是自己用,二个人可能会快点,我也是使用业余时间来做的
1、我前几天就已经发送了Q好友添加请求,为什么还没有回应呢?
2、点@即可嵌套回复
说实话,这个我还真不懂……
下一篇就懂了
话说有蛊惑的嫌疑~~
来看西瓜哥啦!嘻嘻
春节好!
C瓜哥,,病好点米。睡觉不要踢被子哈,多穿点衣服,,风好大啊,冷
今天好多了,不再流清涕了!
看不懂文章内容,我是来探望左下角的西瓜小贱贱的~
记得你以前好像写过这个啊.
是吗?~
西瓜。西瓜..
vc以前学过一点,不过再忘记了
也是写窗口?
还好我转去研究Linux了,呵呵,windows以后再折腾,瓜哥加油啊!
Windows makes our life easier, while linux makes server easier!
寒假的时间用好了,比下学期一学期学的东西都多!
怎么还弄起英文,诶,我英语不好,看不懂!
我觉得Linux有点难用,以后再说吧
来看C瓜哥,不看代码。
考完了吗?
今天考完,不会要补几天课
被到什么时候呢?
那代码关键字还好。就是其余的看起来特纠结。。。