四、Windows子窗口控件的滚动条类别—给背景着色
当COLORS1定义它的窗口类别时,也为其显示区域背景定义了一个实心的黑色画刷:
wndclass.hbrBackground = CreateSolidBrush (0) ;
当您改变COLORS1的滚动条设定时,程序必须建立一个新的画刷,并将该新画刷句柄放入窗口类别结构中。如同使用GetWindowLong和SetWindowLong能得到并设定滚动条窗口消息处理程序一样,用GetClassWord和SetClassWord能得到这个画刷的句柄。
您可以建立新的画刷并将其句柄插入窗口类别结构中,然后删除旧的画刷:
DeleteObject ((HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) CreateSolidBrush (RGB (color[0], color[1], color[2])))) ;
Windows下一次重新为窗口的背景着色时,将使用这个新画刷。为了强迫Windows抹掉背景,我们将使整个显示区域无效:
InvalidateRect (hwnd, &rcColor, TRUE) ;
TRUE(非零)值作为第三个参数,表示希望在重新着色之前删去背景。
InvalidateRect使Windows在窗口消息处理程序的消息队列中放进一个WM_PAINT消息。由于WM_PAINT消息的优先等级比较低,所以,如果您还在使用鼠标或者光标键移动滚动条的话,这个消息将不会立即被处理。如果您想在颜色改变之后使该窗口立即变成最新的(目前的),那么您可以在InvalidateRect之后增加下面的叙述:
UpdateWindow (hwnd) ;
但这会使得键盘和鼠标处理变慢。
COLORS1中的WndProc函数不处理WM_PAINT消息,而是将其传给DefWindowProc。Windows对WM_PAINT消息的内定处理只是呼叫BeginPaint和EndPaint使窗口生效。因为在InvalidateRect呼叫中已经指定背景要被抹掉,所以BeginPaint呼叫使Windows发出一个WM_ERASEBKGND(删除背景)消息,WndProc也将忽略这个消息。Windows用窗口类别中指定的画刷将显示区域的背景抹去,这样就处理了这个消息。
在终止以前进行清除总是一个好主意,因此在处理WM_DESTROY消息处理期间,再一次呼叫DeleteObject:
DeleteObject ((HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) GetStockObject (WHITE_BRUSH))) ;