关于如何换肤、子类化的解决方案

2016-01-29 11:57 12 1 收藏

关于如何换肤、子类化的解决方案,关于如何换肤、子类化的解决方案

【 tulaoshi.com - C语言心得技巧 】

关于如何换肤、子类化的解决方案

作者:peterbing@sohu.com

  对于应用程序的换肤及子类化。下面是我尝试过一些方法,以在CAboutDlg中子类化其中的Button为例:

第一种:直接用现成的类

1、自己写一个类class CButtonXP : public CButton{/*...*/}

用MessageMap处理感兴趣的消息。

2、用CButtonXP代替CButton来声明变量m_btn;

3、在void CAboutDlg:DoDataExchange(CDataExchange* pDX)中加上一句:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
DDX_Control(pDX, IDB_BUTTON1, m_edit);

或者在 InitDialog() 中加上

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
m_btn.SubclassDlgItem(IDB_BUTTON1, this);

这两种效果差不多的。

第二种:在 Hook 中使用现成的类

1、自己写一个类 class CButtonXP : public CButton{/*...*/}

用 MessageMap 处理感兴趣的消息。

2、使用 SetWindowsHookEx 安装一个钩子:

g_hWndProcHook = ::SetWindowsHookEx(WH_CALLWNDPROC,WndProcHook,NULL,::GetCurrentThreadId());

3、在 WndProcHook 中处理窗口创建和销毁的消息:

LRESULT CALLBACK WndProcHook(int code, WPARAM wParam, LPARAM lParam){if (code == HC_ACTION){switch (((CWPSTRUCT*) lParam)-message){case WM_CREATE:BeginSubclassing(((CWPSTRUCT*) lParam)-hwnd);break;case WM_NCDESTROY:// TODO: clear subclass info.EndSubclassing(((CWPSTRUCT*) lParam)-hwnd);break;default:break;}}return CallNextHookEx(g_hWndProcHook, code, wParam, lParam);}      
4、在 BeginSubclassing 中用 GetClassName 得到类名,例如 "Button",然后用 CButtonXP 类进行子类化。
CButtonXP pButton = new CButtonXP;VERIFY(pButton -SubclassWindow(hWnd));

第三种 在Hook中使用窗口过程

1、自己写一个按钮的窗口过程

WNDPROC oldProc;LRESULT CALLBACK ProcButton(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){ASSERT(oldProc != 0);if (oldProc == 0) return TRUE;switch (uMsg){case WM_ERASEBKGND:break;//......default:break;}return CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam);}      
2、同第二种
3、同第二种

4、在 BeginSubclassing 中得到类名后,用 SetWindowLong 的方式子类化:
oldProc = (WNDPROC) GetWindowLong(hWnd, GWL_WNDPROC);SetWindowLong(hWnd, GWL_WNDPROC, (LONG) ProcButton);      
第四种:不用 Hook

在一个对话框的 OnInitDialog 中枚举它的所有子窗体,例如用下面两句来实现:
hWnd=GetWindow(hDlg,GW_CHILD); hWnd=GetWindow(hWnd,GW_HWNDNEXT);

对每个子窗体进行子类化处理,处理过程同第二种与第三种。

第五种:如果是在XP下运行,可以使用manifest,也就是如下的一个XML文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"? <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" <assemblyIdentity name="Microsoft.Windows.XXXX"                   processorArchitecture="x86"                   version="5.1.0.0"                   type="win32"/ <descriptionWindows Shell</description <dependency <dependentAssembly <assemblyIdentity type="win32"                   name="Microsoft.Windows.Common-Controls"                   version="6.0.0.0"                   processorArchitecture="x86"                   publicKeyToken="6595b64144ccf1df"                   language="*"/ </dependentAssembly </dependency </assembly       
  把它存为应用程序名 .manifest,放到和应用程序对应的目录下,或者把它作为资源类型为24的资源编译进应用程序中。这样程序在XP下就自动拥有了XP的风格。

第六种:使用第三方的库Skin++(www.uipower.com)实现换肤

第七种:用第三方应用程序给整个windows换肤(windowblinds)

  以上七种方式各有优缺点。我在使用过程中也遇到不少问题,现在一一道来,希望和大家共同解决问题。先排除几种不准备深入探讨的方式:

来源:http://www.tulaoshi.com/n/20160129/1484027.html

延伸阅读
微软在桌面系统上的成功,令我们不得不大量使用它的办公产品,如:Word,Excel。时至今日,它的源代码仍然不公开已封锁了我们的进一步应用和开发。然而在要求更高的服务器领域,微软本身的产品移植性不好, 性能不佳。在我们实际的开发中,表现层的解决方案虽然有多样,但是Ie浏览器已成为最多人使用的浏览器,因为大家都用Windows。在企业...
随着ADSL宽带接入技术的成熟,各种全新的技术应用已经深入到千家万户,由此引发的故障也随之而来。下面,笔者将维护过程中遇到的几则ADSL宽带经典故障分享给大家,希望能够给ADSL用户一定的帮助。 一、拨号时出现678错误 帮障表现:Windows XP SP2操作系统,ADSL虚拟拨号用户。点击“宽带连接”时出现678错误。...
解说Win32的窗口子类化            作者:李马(home.nuc.edu.cn/~titilima) 下载本文的配套源代码         也许你需要一个特殊的Edit来限制浮点数的输入,但是现有的Edit却并不能完成这项工作——因为它只能够单纯的限制大小写或者纯数字。当你在论坛上求救的时候,某个网友告诉你:...
标签: 电脑入门
当您尝试运行 Windows Server 2003、 Windows XP、 Windows 2000 或 Windows NT 4.0 的计算机中注销时,可能会遇到下列症状: 1、备份可能无法启动。从备份程序的应用程序日志中有错。但是,如果您看到事件 ID 1524,备份已运行。 2、当您尝试在 Windows 2000 中注销时,很长的时间,将显示"正在保存设置..."消息,Windows 会停止...
标签: windows 操作系统
Windows Installer(windows安装服务)是一种通用的软件发布方式,现在许多软件都使用windows Installer作为自己的安装程序,有时因为各种原因以及windows Installer本身的缺陷,会导致windows Installer出错。 症状一:删除某个程序后,在运行某些软件时,老会弹出一个“windows正在配置Windows Installer,请稍候”的窗口。 ...

经验教程

298

收藏

97
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部