使用控件,想对一个static控件做一些操作,使用了SetWindowLong将其的WNDPROC修改成自己调用的一个函数,在这个函数里面如果对WM_PAINT进行操作,那么这时在对于其父窗口的WM_CTLCOLORSTATIC所进行的颜色修改就没有作用了,如果不处理WM_PAINT就没有问题。另外一点也很奇怪,如果在创建这个static时其属性中如果增加了颜色特征,WM_CTLCOLORSTATIC也会失去作用。所以很想知道static控件的颜色是如何控制的,修改它的HBRBKGROUDBRUSH没有任何用处。盼高手解答,越详细越好测试程序如下:
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
TCHAR szBuffer[200];
HINSTANCE hInstance;
static HWND hstatic;
static HBRUSH hBrushStatic, hBrushStatic2;
LONG style; switch(message)
{
case WM_CREATE:
hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
hstatic = CreateWindow( TEXT("STATIC"), TEXT("LIST is joke"),
WS_CHILD|WS_VISIBLE|SS_CENTER|SS_GRAYRECT,//如果有了SS_GRAYRECT,WM_CTLCOLORSTATIC就无效了
100, 100, 200, 200,
hwnd, (HMENU)1, hInstance, NULL); OldStatic = (WNDPROC) SetWindowLong (hstatic, GWL_WNDPROC, (LONG) StaticProc );
hBrushStatic2 = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
SetClassLong(hstatic, GCL_HBRBACKGROUND, hBrushStatic2);
hBrushStatic = (HBRUSH)GetStockObject(BLACK_BRUSH); return 0; case WM_CTLCOLORSTATIC:
SetTextColor((HDC)wParam, RGB(70, 0, 80));
SetBkColor((HDC)wParam, RGB(0, 90, 130));
return (LRESULT)hBrushStatic;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}LRESULT CALLBACK StaticProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(message)
{
case WM_PAINT: ,//如果处理了此消息,WM_CTLCOLORSTATIC也无效了
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 10, "This is a Test", 14);
EndPaint(hwnd, &ps);
break;
}
return CallWindowProc( OldStatic, hwnd, message, wParam, lParam );
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
TCHAR szBuffer[200];
HINSTANCE hInstance;
static HWND hstatic;
static HBRUSH hBrushStatic, hBrushStatic2;
LONG style; switch(message)
{
case WM_CREATE:
hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
hstatic = CreateWindow( TEXT("STATIC"), TEXT("LIST is joke"),
WS_CHILD|WS_VISIBLE|SS_CENTER|SS_GRAYRECT,//如果有了SS_GRAYRECT,WM_CTLCOLORSTATIC就无效了
100, 100, 200, 200,
hwnd, (HMENU)1, hInstance, NULL); OldStatic = (WNDPROC) SetWindowLong (hstatic, GWL_WNDPROC, (LONG) StaticProc );
hBrushStatic2 = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
SetClassLong(hstatic, GCL_HBRBACKGROUND, hBrushStatic2);
hBrushStatic = (HBRUSH)GetStockObject(BLACK_BRUSH); return 0; case WM_CTLCOLORSTATIC:
SetTextColor((HDC)wParam, RGB(70, 0, 80));
SetBkColor((HDC)wParam, RGB(0, 90, 130));
return (LRESULT)hBrushStatic;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}LRESULT CALLBACK StaticProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(message)
{
case WM_PAINT: ,//如果处理了此消息,WM_CTLCOLORSTATIC也无效了
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 10, "This is a Test", 14);
EndPaint(hwnd, &ps);
break;
}
return CallWindowProc( OldStatic, hwnd, message, wParam, lParam );
}
When this member is NULL, an application must paint its own background whenever it is requested to paint in its client area. To determine whether the background must be painted, an application can either process the WM_ERASEBKGND message or test the fErase member of the PAINTSTRUCT structure filled by the BeginPaint function.
也就是说系统会帮你刷背景,轮不到你刷了。除非你把WNDCLASS结构中的hbrBackgroud置为空
fErase
Specifies whether the background must be erased. This value is nonzero if the application should erase the background. The application is responsible for erasing the background if a window class is created without a background brush. For more information, see the description of the hbrBackground member of the WNDCLASS structure.
return CallWindowProc(OldStatic, hwnd, message, wParam, lParam );
发出的:WM_CTLCOLORSTATIC,试试://
LRESULT CALLBACK StaticProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(message)
{
case WM_PAINT: //如果处理了此消息,WM_CTLCOLORSTATIC也无效了
OutputDebugString("StaticProc\n");
return CallWindowProc(OldStatic, hwnd, message, wParam, lParam );
// hdc = BeginPaint(hwnd, &ps);
// TextOut(hdc, 10, 10, "Test", 4);
// EndPaint(hwnd, &ps);
break;
}
return CallWindowProc( OldStatic, hwnd, message, wParam, lParam );
}BeginPaint(hwnd, &ps);不发送WM_CTLCOLORSTATIC
case WM_PAINT: //如果处理了此消息,WM_CTLCOLORSTATIC也无效了
// OutputDebugString("StaticProc3\n");
// return CallWindowProc(OldStatic, hwnd, message, wParam, lParam );
hparentwnd=GetParent(hwnd);
hdc = BeginPaint(hwnd, &ps);
SendMessage(hparentwnd,WM_CTLCOLORSTATIC,(WPARAM)hdc,(LPARAM)hwnd);
TextOut(hdc, 10, 10, "Test", 4);
EndPaint(hwnd, &ps);
break;
case WM_CTLCOLORSTATIC:
OutputDebugString("WM_CTLCOLORSTATIC3\n");
可以发现,只是BeginPaint(hwnd, &ps)时,不输出以上信息,
case WM_PAINT: ,//如果处理了此消息,WM_CTLCOLORSTATIC也无效了
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 10, "This is a Test", 14);
EndPaint(hwnd, &ps);
break;
break后是:
return CallWindowProc( OldStatic, hwnd, message, wParam, lParam );
就是它又调用你的WM_CTLCOLORSTATIC。可惜已经晚了。
“用break,仍然会产生WM_CTLCOLORSTATIC(是因为CallWindowProc),如果用return,就不会产生WM_CTLCOLORSTATIC(也是因为CallWindowProc),”,很明显是CallWindowProc产生的WM_CTLCOLORSTATIC。你看看9楼的程序,试试。
{...
case WM_CTLCOLORSTATIC:
i=GetWindowLong((HWND)lParam,GWL_ID);
switch(i)
{
case 3:
SetTextColor((HDC)wParam,crText[i%3]);// text 颜色变化
SetBkColor((HDC)wParam,RGB(255,255,255));
//
OutputDebugString("WM_CTLCOLORSTATIC3\n");
return (LRESULT)hStaticBrush;//这是Brush
break;
...
}
//位置一定要对。
hparentwnd=GetParent(hwnd);
hdc = BeginPaint(hwnd, &ps);
//!!!这句就是用来改变hdc的,放在TextOut还有什么用?
SendMessage(hparentwnd,WM_CTLCOLORSTATIC,(WPARAM)hdc,(LPARAM)hwnd);
TextOut(hdc, 10, 10, "Test", 4);
case WM_PAINT: //如果处理了此消息,WM_CTLCOLORSTATIC也无效了
// OutputDebugString("StaticProc3\n");
// return CallWindowProc(OldStatic, hwnd, message, wParam, lParam );
hparentwnd=GetParent(hwnd);
hdc = BeginPaint(hwnd, &ps);
//!!!
brsh=(HBRUSH) SendMessage(hparentwnd,WM_CTLCOLORSTATIC,(WPARAM)hdc,(LPARAM)hwnd);
::FillRect(hdc,&ps.rcPaint,brsh);
//!!!
TextOut(hdc, 10, 10, "Test", 4);
EndPaint(hwnd, &ps);
return 0;
这下应该理解更深了吧。