本文属于第35期, 适合中级读者
对于应用程序的换肤及子类化。下面是我尝试过一些方法,以在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;
MFC界面编程之 关于如何换肤、子类化的解决方案
最新推荐文章于 2023-01-06 18:52:58 发布
本文详细介绍了MFC界面编程中换肤和子类化的七种方法,包括直接使用自定义类、Hook机制、窗口过程等,并讨论了各种方法的优缺点。在换肤过程中遇到的重复子类化、系统对话框处理和类名识别等问题也被提出,同时分享了解决这些问题的一些思路和简化CWnd类的方案。
摘要由CSDN通过智能技术生成