windows中的static控件的背景色不好改变,因为一般的做法是依赖他的父窗口来给他传入背景画刷才能实现,也就是说需要依赖父窗口。这种方式在duilib中会导致主窗口逻辑会混入子窗口的逻辑,控件也不能复用。
windows提供了一种机制,子类化窗口。可以实现对窗口的功能进行扩展。
参考资料:https://docs.microsoft.com/en-us/windows/win32/controls/subclassing-overview
总结来说子类化窗口是对窗口消息的重定向。
先来看下正常的窗口消息的处理过程。
消息循环把消息队列中的消息取出来后,派发到不同的窗口,各个窗口都有自己的窗口过程,用来处理派发过来的消息。
如果我们需要定制我们特有的功能,就需要能自己处理这些消息,完成定制的逻辑。这个就可以通过子类化窗口来实现。
下面来看下子类化窗口之后的窗口消息处理过程。
消息循环把窗口B的消息派发给窗口B后,消息并没有直接交给窗口B的窗口过程,而是交给了我们自定义的窗口过程,在这里,我们可以做我们想做的事情,来实现定制的功能。
然后根据需要是再次调用原来的窗口过程(Case 1),还是认为消息已经处理完毕了(Case 2)。
目前有两种方式来实现:
使用SetWindowLong设置新的窗口过程。
使用SetWindowSubclass来设置子类化窗口过程。
-
创建窗口CreateWindowExW
-
通过SetWindowLong设置新的窗口过程
-
在窗口过程中处理自己感兴趣的消息
WNDPROC OldProc = NULL;
HWND hwnd = ::CreateWindowExW(dwStyleEx, L"Static", NULL, dwStyle, left, top, width, height,
hParentWnd, NULL, hInstance, NULL);
OldProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)StaticControlProc);
LRESULT CALLBACK StaticControlProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_PAINT)
{
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
::GetClientRect(hWnd, &rect);
DWORD dwColor = RGB(255, 0, 0);
HBRUSH hBrush = ::CreateSolidBrush(dwColor);
HPEN hPen = ::CreatePen(PS_SOLID, 1, dwColor);
HBRUSH hOldBrush = (HBRUSH)::SelectObject(hdc, hBrush);
HPEN hOldPen = (HPEN)::SelectObject(hdc, hPen);
::Rectangle(hdc, 0, 0, rect.right, rect.bottom);
::SelectObject(hdc, hOldBrush);
::SelectObject(hdc, hOldPen);
::DeleteObject(hBrush);
::DeleteObject(hPen);
EndPaint(hWnd, &ps);
return 0;
}
else
{
return ::CallWindowProc(OldProc, hWnd, msg, wParam, lParam);
}
}
-
创建窗口CreateWindowExW
-
通过SetWindowSubclass设置新的窗口过程
-
在窗口过程中处理自己感兴趣的消息
HWND hwnd = ::CreateWindowExW(dwStyleEx, L"Static", NULL, dwStyle, left, top, width, height,
hParentWnd, NULL, hInstance, NULL);
SetWindowSubclass(hwnd, StaticControlProc, 0, 0);
LRESULT CALLBACK StaticControlProc(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if (uMsg == WM_PAINT)
{
// ...
return 0;
}
else
{
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
}
参考资料:
https://www.cnblogs.com/kekec/p/3210696.html
https://blog.csdn.net/bjbz_cxy/article/details/80762692