我正在尝试更改静态控件的文本/背景颜色。我可以通过以下方式做到这一点:
// 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属性(以防子级将移动/滚动)。
答案 0 :(得分:0)
WM_CTLCOLORSTATIC
由静态控件发送到其父窗口,而不是顶级窗口。
hwndMain: WM_CTLCOLORSTATIC for hwnd1
|
\--hwnd1: WM_CTLCOLORSTATIC for hwnd2 (You might have to subclass hwnd1)
|
\--hwnd2
您还会泄漏画笔,在创建窗口时将CreateSolidBrush
处的画笔存储在某个位置,并在窗口被破坏时将其删除。
答案 1 :(得分:0)
通过阅读MSDN文档,我知道一个函数SetWindowsLongPtr
,其参数GWLP_WNDPROC
可以为窗口过程设置一个新地址。
此功能可以更改子窗口的文本颜色和背景颜色,也就是说,它可以触发WM_CTLCOLORSTATIC
。
但是经过测试,我发现它对次要窗口无效,也就是说,它不能更改父窗口的文本颜色。
我还查阅了很多信息,很少涉及三层窗户的文件。
因此,我认为要解决此问题并使所有三个窗口都更改文本的颜色,您可能必须自己重写WndProc
,但这非常复杂并且涉及很多事情。
编辑:如果只需要更改文本颜色和背景颜色 您可以自定义控件,以便可以 处理所有操作。
希望能为您提供帮助。