如何访问属性表的WM_CTLCOLOR等窗口消息以修改界面配色?
问题解答
该需求完全可实现,不需要依赖PFNPROPSHEETCALLBACK的内置消息支持,核心实现思路是子类化属性表顶层窗口,自行拦截处理所有窗口消息,具体操作步骤如下:
操作步骤
步骤1:在PFNPROPSHEETCALLBACK的
PSCB_INITIALIZED消息中执行子类化
当回调收到PSCB_INITIALIZED通知时,属性表窗口已经完成创建,此时可以直接拿到窗口句柄,调用通用控件库提供的安全子类化API SetWindowSubclass绑定自定义窗口过程:
// 自定义子类化标识,确保全局唯一即可 #define PROPSHEET_SUBCLASS_ID 0x1001 // PFNPROPSHEETCALLBACK 回调实现 INT_PTR CALLBACK MyPropSheetCallback(HWND hDlg, UINT uMsg, LPARAM lParam) { if (uMsg == PSCB_INITIALIZED) { // 绑定自定义窗口过程,拦截所有窗口消息 SetWindowSubclass(hDlg, PropSheetSubProc, PROPSHEET_SUBCLASS_ID, 0); } return 0; }
步骤2:在自定义窗口过程中处理WM_CTLCOLOR相关消息
绑定的子类化过程可以捕获属性表收到的全部窗口消息,你需要处理两类消息即可实现需求:
WM_CTLCOLORTAB:专门负责标签控件的颜色绘制WM_CTLCOLORDLG:负责属性表对话框整体外框的背景绘制
// 提前创建自定义画刷,示例为浅灰背景 HBRUSH g_hTabBrush = CreateSolidBrush(RGB(240,240,240)); HBRUSH g_hDlgBrush = CreateSolidBrush(RGB(230,230,230)); LRESULT CALLBACK PropSheetSubProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) { switch(uMsg) { // 处理标签控件颜色 case WM_CTLCOLORTAB: { HDC hTabDC = (HDC)wParam; SetTextColor(hTabDC, RGB(0,0,0)); // 标签文本设为黑色 SetBkColor(hTabDC, RGB(240,240,240)); // 标签背景设为浅灰 return (LRESULT)g_hTabBrush; } // 处理属性表外框背景色 case WM_CTLCOLORDLG: { HDC hDlgDC = (HDC)wParam; SetBkColor(hDlgDC, RGB(230,230,230)); return (LRESULT)g_hDlgBrush; } // 窗口销毁时清理资源 case WM_NCDESTROY: { RemoveWindowSubclass(hWnd, PropSheetSubProc, uIdSubclass); DeleteObject(g_hTabBrush); DeleteObject(g_hDlgBrush); break; } } // 其余消息走默认处理逻辑 return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
兼容说明
如果需要适配Windows XP及更早版本系统,没有SetWindowSubclass可用,可以替换为传统SetWindowLongPtr(GWL_WNDPROC)方式实现子类化,注意保存原窗口过程指针完成消息转发即可。
内容的提问来源于stack exchange,提问作者fidel espanto
相关产品推荐
相关产品推荐

