当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 关于如何换肤、子类化的解决方案

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 101 ::
收藏到网摘: n/a

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

作者:[email protected]

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

第一种:直接用现成的类

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

用MessageMap处理感兴趣的消息。

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

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

DDX_Control(pDX, IDB_BUTTON1, m_edit);

或者在 InitDialog() 中加上

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"/> <description>Windows 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)

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