c++ - 设置子窗口的文本颜色
问题描述
我正在尝试更改静态控件的文本/背景颜色。我可以通过以下方式做到这一点:
// This is the 'main' window
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW &~WS_MAXIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT, 0, 1035, 764, nullptr, nullptr, hInstance, nullptr);
...
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_CTLCOLORSTATIC:
{
MessageBox( NULL, "CTLCOLORSTATIC called", "", MB_OK );
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(200, 200, 20));
SetBkColor(hdcStatic, RGB(10, 10, 10));
return (INT_PTR)CreateSolidBrush(RGB(30, 30, 30));
}
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
但是,如果我将窗口放在另一个窗口中,则子控件文本/背景颜色保持默认:
// This is the 'parent' window, which resides in the 'main' window
HWND parent = CreateWindowEx
(
0,
_TEXT("STATIC"),
"",
WS_TABSTOP | WS_VISIBLE | BS_SOLID | WS_CLIPCHILDREN,
10, 10, 500, 500,
hwnd,
NULL,
(HINSTANCE)GetWindowLong(hwnd, GWLP_HINSTANCE),
NULL
);
// This is the 'child' window which resides in the 'parent' window
HWND child = CreateWindowEx
(
0,
_TEXT("STATIC"),
"SubItem",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_SOLID,
10, 10, 100, 100,
parent,
NULL,
(HINSTANCE)GetWindowLong(parent, GWLP_HINSTANCE),
NULL
);
总而言之,我有 3 个窗口:
HWND hwnd; // the 'main' application window (color changes fine)
HWND parent; // the 'parent/container' window which is inside the 'main' window (color changes fine)
HWND child; // the 'child' window which is inside the 'parent' window (color DOES NOT change)
即使我将 MessageBox 放在 WM_CTLCOLORSTATIC 中,我看到它在每次绘制孩子时都会触发,但不会为孩子更改颜色,而只是为父母更改颜色。
据我了解,我需要在主窗口过程中处理消息,但我并不完全清楚如何执行此操作。如果我将 (HWND)lParam 与儿童的 HWND 进行比较,它们是相同的(在默认开关情况下),所以我可以在“默认”部分获得参考,但我不确定我应该如何处理它从那里..
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
case WM_CTLCOLORSTATIC:
{
if ((HWND)lParam == child )
MessageBox( NULL, "Reference Match for CTLCOLORSTATIC", "", MB_OK ); // <-- THIS NEVER TRIGGERS
}
....
default:
if ((HWND)lParam == child )
MessageBox( NULL, "Reference Match for DEFAULT", "", MB_OK ); // <-- THIS DOES TRIGGER
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
我将一个窗口放在另一个窗口中的原因是我可以在父级中使用 WS_CLIPCHILDREN 属性(因为子级会移动/滚动)。
解决方案
通过阅读MSDN文档,我知道了一个函数,SetWindowsLongPtr
它的参数GWLP_WNDPROC
可以为窗口过程设置一个新的地址。
这个函数可以改变子窗口的文字颜色和背景颜色,也就是说可以触发WM_CTLCOLORSTATIC
。
但是经过测试发现对辅助窗口无效,也就是说不能改变父窗口的文字颜色。
我也查阅了很多资料,关于三层windows的文档很少。
所以,我觉得要解决这个问题,让三个窗口都改变文字的颜色,你可能得WndProc
自己重写,但这很复杂,涉及的东西很多。
编辑:如果您只需要更改静态控件的文本颜色和背景颜色,您可以自定义一个控件,以便您可以处理它的所有操作。
希望能帮到你。
推荐阅读
- angular - NGRX 错误“调度期望一个对象,而不是它收到一个函数。如果您使用的是 createAction 函数......”
- android - Qaudioinput在android中有一个运行时错误
- javascript - 不允许在 Angular 8 中使用 pwa 离线
- java - 在Java中,表达式“++++++”执行后,编译器没有报错,能正确执行吗?
- git - 无法运行命令: git add 。&& git commit -m "初始提交'
- python - 使用 Keras 进行交叉验证如何适应?
- python-3.x - 我如何使用这样的假期列表在我的一天列表中查找假期。这种方法给了我一个错误
- javascript - 如何将多个图表添加到传单地图?
- c# - 如何将类型“System.Collections.Generic.Dictionary>”隐式转换为“System.Collections.Generic.IDictionary>”?
- mongodb - 如何使用 Java MongoDB Reactive 驱动程序更新文档中的字段类型?