当前位置:C++技术网 > 资讯 > WM_CTLCOLORBTN消息就是一个摆设

WM_CTLCOLORBTN消息就是一个摆设

更新时间:2016-02-05 22:55:59浏览次数:1+次

    在Windows程序设计书上说,在理论上可以行。也就表示,这个消息在实际上,用处不大,成了摆设。所以,如果你寄希望于这个消息来改变按钮的背景颜色,你会失望的。
    WM_CTLCOLORBTN消息是子窗口即将给客户区着色的时候,由按钮控件给父窗口发的消息。这个消息的WPARAM参数是按钮控件的客户区(整个按钮表面)设备描述表句柄,LPARAM参数是按钮控件的窗口句柄。
    有了按钮控件的客户区的设备描述表句柄后,我们只要修改设备描述表中的信息,即可对按钮产生作用。所以消息规定我们在处理WM_CTLCOLORBTN消息时要设置文本的颜色,文本背景颜色,然后再返回要给画刷给子窗口。设置文本颜色使用SetTextColor,设置文本背景颜色使用SetBkColor。
    而返回的画刷,则由窗口创建,这样我们可以创建一个我们喜欢的画刷,然后返回画刷即可。这个画刷用来是我们自己创建的,所以,用完后需要自己释放。
    下面是实现代码:
case WM_CTLCOLORBTN:
    {
        HDC hdc = (HDC)wParam;
        SetTextColor(hdc,RGB(255,0,0));//设置文字颜色为红色
        SetBkColor(hdc,RGB(0,0,255));//设置文字背景颜色为蓝色
        return (LRESULT)GetStockObject(DKGRAY_BRUSH);//返回深灰色画刷
    }
    return 0;

    然而,你看到的按钮效果如下:

处理WM_CTLCOLORBTN消息后,按钮样子还是没有变化

【处理WM_CTLCOLORBTN消息后,按钮样子还是没有变化】
    可以看到,按钮没有任何变化。是我们的代码写错了吗?不是。我们看看这个消息的注意事项。
    在子窗口的处理上出了差错。第一、只有下压按钮和自绘按钮才给父窗口发送WM_CTLCOLORBTN消息。这一点,我们是满足的。第二、只有自绘按钮才会响应父窗口过程对WM_CTLCOLORBTN消息的处理,然后使用返回的画刷来着色背景。
    也就是说,下压按钮根本就不会在WM_CTLCOLORBTN消息处理完毕后,用返回的画刷填充客户区,也就无法改变按钮的表面的颜色。这是在逗我吗?下压按钮既然给父窗口发送这个消息,竟然不用返回的画刷填充客户区。这纯粹就是逗逼的设计。
    会使用返回的画刷填充客户区的是自绘按钮,即拥有BS_OWNERDRAW按钮风格的按钮。好像好有点希望。然而,自绘按钮是父窗口响应WM_DRAWITEM消息来绘制按钮控件的。也就是说,自绘按钮要绘制客户区的时候,会向父窗口发送WM_DRAWITEM消息,而在WM_DRAWITEM消息的参数中,包含了绘制所需要的所有参数。这样,父窗口可以完全掌控按钮控件的绘制,更不用说按钮表面的颜色了。
    那么此时,自绘按钮得到WM_CTLCOLORBTN消息处理返回的画刷填充背景,然后又由父窗口完全绘制按钮,这不是越高越麻烦嘛。反正WM_CTLCOLORBTN消息和WM_DRAWITEM消息都是父窗口在处理,而且WM_DRAWITEM消息消息可以完全控制绘制的过程,那WM_CTLCOLORBTN消息已经没有意义了。而且自绘按钮一定会处理WM_DRAWITEM消息,有何必多此一举再去处理WM_CTLCOLORBTN消息呢!
    所以WM_CTLCOLORBTN消息的设计,就是一个摆设,用处不大。如果这个消息可以支持下压按钮改变按钮表面的颜色,那倒是不错,那样也有意义了。然而下压按钮不支持呀。估计设计这个消息的人,是被WM_DRAWITEM消息的设计给搞晕头了。
    所以,WM_CTLCOLORBTN消息基本就可以废弃了。这是微软设计消息的一个失败品。是不是有幸看到呀。关键微软还没有取消这个消息,不知道是为什么,估计没有时间理会吧。