当前位置:C++技术网 > 精选软件 > 静态控件颜色修改WM_CTLCOLORSTATIC消息原理分析图解

静态控件颜色修改WM_CTLCOLORSTATIC消息原理分析图解

更新时间:2016-02-15 23:53:35浏览次数:1+次

    在文章《win32的Static控件颜色文字颜色文字背景颜色的设置》中我们介绍了如何设置静态控件的文字颜色、文字背景颜色和静态控件背景颜色。
    在此,我需要强调一下,这里有三个颜色。显示在控件上面的文字的颜色,在文字底下有一个文字背景层,这层也有一个颜色,就像屏风一样。然后整个静态控件,作为一个窗口,也有一个控件窗口的背景颜色。这里啰嗦了一下,免得看晕了。
    在说明一下,静态控件不只是显示文字一种哦。图片控件就是静态控件的一种。
    为什么我们在WM_CTLCOLORSTATIC消息中可以实现静态控件的颜色修改呢。这是因为,在静态控件在准备重绘自己的时候,会向父窗口发送WM_CTLCOLORSTATIC消息。这个不只静态控件,还包括只读编辑框、禁用的编辑框。比如用SendMessage函数将这个消息发送给父窗口的窗口过程。简单理解,SendMessage函数内部就调用了父窗口的窗口过程。WM_CTLCOLORSTATIC消息传入SendMessage函数,同时传入两个参数,WPARAM参数携带了静态控件创建好的设备上下文DC句柄,LPARAM参数携带了静态控件的窗口句柄。
    下面模拟发送WM_CTLCOLORSTATIC消息的代码:
case WM_PAINT:
    HDC hdc = BeginPaint(hwnd,&ps);
    //准备绘画前,向父窗口发送WM_CTLCOLORSTATIC消息
    HBRUSH hBrush = (HBRUSH)SendMessage(GetParent(hwnd),WM_CTLCOLORSTATIC,(WPARAM)hdc,(LPARAM)hwnd);
    RECT rect;
    GetClientRect(hwnd,&rect);//获取静态控件客户区大小
    FillRect(hdc,&rect,hBrush);//用父窗口传回来的画刷填充客户区
    EndPaint(hwnd,&ps);
    return 0;
    虽然是模拟实现这个消息的原理,但是这个代码是实际可用的。有了代码,可以很直观的了解到,静态控件的颜色修改,实际上是由父窗口来完成。在静态控件的窗口过程中,只是提供了绘制的过程,并没有提供绘制需要的各种设置。向父窗口发送WM_CTLCOLORSTATIC消息的目的,就是让父窗口可以参与静态控件的颜色显示。
    你要知道,控件都是事先封装好的,不能再改动内部的代码了的。所以,在控件中无法固化各种参数,否则无法提供个性化的控件。所以就用这种方式实现参数的传递,然后控件根据得到的DC设置来绘制。SetTextColor和SetBkColor都是将设置存入了HDC对应的设备上下文中存储起来了。WM_CTLCOLORSTATIC消息处理完毕后即SendMessage执行完毕,代码执行就回到了静态控件的重绘消息中继续执行绘制工作。

    我们可以看看下面我画的控件颜色修改过程的流程图:

控件颜色修改的流程图

【控件颜色修改的流程图】
    实际上,这个原理是所有控件颜色修改都适用的,并非只有静态控件。理解了这个流程图和模拟发送WM_CTLCOLORSTATIC消息的代码,就再也不怕忘记这代码怎么写了。
    需要注意一点,WM_CTLCOLORSTATIC只在相同的线程中发送。也就是说,不同线程创建的控件,是不同使用这种方法修改颜色的。