中年人学C语言Windows程序设计,22修改静态文本框static控件背景颜色和文字颜色

当 static 控件或具有 ES_READONLY 风格的 edit 控件被绘制时,会向父窗口发送 WM_CTLCOLORSTATIC 消息。如果我们在窗口过程中处理该消息,就必须返回一个画刷句柄,Windows 会使用该画刷来绘制控件背景(子窗口背景)。

也就是说,改变 static 控件的背景颜色只有这一种方式,就是处理 WM_CTLCOLORSTATIC 消息。WM_CTLCOLORSTATIC 消息就是用来设置背景画刷的。

改变 static 控件的背景颜色

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
    HDC hdc;//定义设备环境句柄  
    static TCHAR  szBuffer[128];
    //TEXTMETRIC tm;
   // SCROLLINFO si;
    PAINTSTRUCT ps;
    size_t iStrLength;
    static int cxChar, cyChar, cxClient, cyClient;
    static HWND hStatic;//静态文本框
    static HFONT hFont[6]; //声明一个逻辑字体句柄为静态变量
    static HBRUSH hBrush;  //画刷
    int i,n;
    //size_t iLength;
    static int iClick = 0;
    static TCHAR  szFont[10][6] = { TEXT("微软雅黑"),  TEXT("宋体"), TEXT("黑体"),  TEXT("楷体"),  TEXT("幼圆"),  TEXT("隶书") };
    switch (message)
    {
        case WM_SIZE://窗体大小改变
            hdc = GetDC(hWnd);
            //GetClientRect(hwnd, &rect);
            cxClient = LOWORD(lParam);//当前x像素
            cyClient = HIWORD(lParam);//当前y像素
            StringCchPrintf(szBuffer, 128, TEXT("当前客户区的分辨率:%d * %d px"), cxClient, cyClient);
            StringCchLength(szBuffer, 128, &iStrLength);
            SetTextAlign(hdc, TA_CENTER | TA_TOP);
            TextOut(hdc, cxClient / 2, 0, szBuffer, iStrLength);
            ReleaseDC(hWnd, hdc);
            return 0;

        case  WM_CREATE:     
            //创建画刷
            hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F));  //翠绿色
            //创建6个字体
            for (i = 0; i < 6; i++)
            {
                hFont[i] = CreateFont(
                    -20/*高度*/, -10/*宽度*/, 0/*不用管*/, 0/*不用管*/, 400,//设置字体粗细程度一般这个值设为400,
                    FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
                    DEFAULT_CHARSET,  //这里我们使用默认字符集,还有其他以 _CHARSET 结尾的常量可用
                    OUT_CHARACTER_PRECIS, //输出精度
                    CLIP_CHARACTER_PRECIS,  //剪裁精度
                    DEFAULT_QUALITY,  //默认输出质量
                    FF_DONTCARE,  //不指定字体族*/
                    szFont[i]  //字体名
                );
            }
            
            hStatic = CreateWindow(
                TEXT("static"), //静态文本框的类名
                TEXT("我其实是一个静态文本框"),  //控件的文本
                WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/ | SS_CENTER /*水平居中*/ | SS_CENTERIMAGE /*垂直居中*/,
                20 /*X坐标*/, 20 /*Y坐标*/, 400 /*宽度*/, 300 /*高度*/,
                hWnd,  //父窗口句柄
                (HMENU)1,  //为控件指定一个唯一标识符
                hInst,  //当前程序实例句柄
                NULL
            );
            break;
        case WM_CTLCOLORSTATIC:
            return (INT_PTR)hBrush;  //这里必须返回画刷句柄

        case WM_PAINT://窗口绘画:点
        {
            //int x, xLast;
            HDC hdc = BeginPaint(hWnd, &ps);//函数为指定窗口进行绘画作准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT 结构中。
            EndPaint(hWnd, &ps);
            return 0;
        }
        case WM_LBUTTONDOWN:  //鼠标左键单击消息
            iClick++;//鼠标点击次数
            //设置控件字体
            n = (iClick) % 6-1;//取余减一,
            //更改静态文本框 字体
            SendMessage(
                hStatic,  //欲设置字体的控件句柄
                WM_SETFONT,  //消息名(消息类型)
                (WPARAM)hFont[n],  //取得字体句柄
                NULL  //传空值即可
            );     
            StringCchPrintf(szBuffer, 128, TEXT("鼠标左键被单击%d次"), iClick);            
            SetWindowText(hStatic, szBuffer);            
            break;
            
        case WM_DESTROY:
            DeleteObject(hBrush);
            DeleteObject(hFont);//删除创建的字体
            PostQuitMessage(0);
            break;             
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    return 0;
}

效果
在这里插入图片描述

修改文字颜色和文字背景颜色

上图中,我们的代码只是改变了控件的背景颜色(整个子窗口的背景颜色),却忽略了文字的背景颜色。

修改文字背景颜色使用 SetBkColor 函数,它的原型为:

COLORREF SetBkColor(
    HDC      hdc,  //设备环境句柄
    COLORREF crColor  //背景颜色
);

修改文字前景色(文字颜色)使用 SetTextColor 函数,它的原型为:

COLORREF SetTextColor(
    HDC      hdc,  //设备环境句柄
    COLORREF crColor  //背景颜色
);

这里我们修改的是 static 控件中的文本颜色,所以需要获取 static 控件的设备环境句柄。非常巧妙的是,发送 WM_CTLCOLORSTATIC 消息时,wParam 参数表示的就是 static 控件的设备环境句柄(lParam 表示控件句柄)。

下面的代码会修改文本的背景色和前景色:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    HDC hdc;//定义设备环境句柄  
    HDC hdcStatic;
    static TCHAR  szBuffer[128];
    //TEXTMETRIC tm;
   // SCROLLINFO si;
    PAINTSTRUCT ps;
    size_t iStrLength;
    static int cxChar, cyChar, cxClient, cyClient;
    static HWND hStatic;//静态文本框
    static HFONT hFont[6]; //声明一个逻辑字体句柄为静态变量
    static HBRUSH hBrush;  //画刷
    int i, n;
    //size_t iLength;
    static int iClick = 0;
    static TCHAR  szFont[10][6] = { TEXT("微软雅黑"),  TEXT("宋体"), TEXT("黑体"),  TEXT("楷体"),  TEXT("幼圆"),  TEXT("隶书") };
    switch (message)
    {
    case WM_SIZE://窗体大小改变
        hdc = GetDC(hWnd);
        //GetClientRect(hwnd, &rect);
        cxClient = LOWORD(lParam);//当前x像素
        cyClient = HIWORD(lParam);//当前y像素
        StringCchPrintf(szBuffer, 128, TEXT("当前客户区的分辨率:%d * %d px"), cxClient, cyClient);
        StringCchLength(szBuffer, 128, &iStrLength);
        SetTextAlign(hdc, TA_CENTER | TA_TOP);
        TextOut(hdc, cxClient / 2, 0, szBuffer, iStrLength);
        ReleaseDC(hWnd, hdc);
        return 0;

    case  WM_CREATE:
        //创建画刷
        hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F));  //翠绿色
        //创建6个字体
        for (i = 0; i < 6; i++)
        {
            hFont[i] = CreateFont(
                -20/*高度*/, -10/*宽度*/, 0/*不用管*/, 0/*不用管*/, 400,//设置字体粗细程度一般这个值设为400,
                FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
                DEFAULT_CHARSET,  //这里我们使用默认字符集,还有其他以 _CHARSET 结尾的常量可用
                OUT_CHARACTER_PRECIS, //输出精度
                CLIP_CHARACTER_PRECIS,  //剪裁精度
                DEFAULT_QUALITY,  //默认输出质量
                FF_DONTCARE,  //不指定字体族*/
                szFont[i]  //字体名
            );
        }

        hStatic = CreateWindow(
            TEXT("static"), //静态文本框的类名
            TEXT("我其实是一个静态文本框"),  //控件的文本
            WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/ | SS_CENTER /*水平居中*/ | SS_CENTERIMAGE /*垂直居中*/,
            20 /*X坐标*/, 20 /*Y坐标*/, 400 /*宽度*/, 300 /*高度*/,
            hWnd,  //父窗口句柄
            (HMENU)1,  //为控件指定一个唯一标识符
            hInst,  //当前程序实例句柄
            NULL
        );
        break;
    case WM_CTLCOLORSTATIC:
        hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(255, 255, 255));  //白色
        SetBkColor(hdcStatic, RGB(0x41, 0x96, 0x4F));   //设置字体背景为翠绿色
        return (INT_PTR)hBrush; //这里必须返回画刷句柄
         

    case WM_PAINT://窗口绘画:点
    {
        //int x, xLast;
        HDC hdc = BeginPaint(hWnd, &ps);//函数为指定窗口进行绘画作准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT 结构中。
        EndPaint(hWnd, &ps);
        return 0;
    }
    case WM_LBUTTONDOWN:  //鼠标左键单击消息
        iClick++;//鼠标点击次数
        //设置控件字体
        n = (iClick) % 6 - 1;//取余减一,
        //更改静态文本框 字体
        SendMessage(
            hStatic,  //欲设置字体的控件句柄
            WM_SETFONT,  //消息名(消息类型)
            (WPARAM)hFont[n],  //取得字体句柄
            NULL  //传空值即可
        );
        StringCchPrintf(szBuffer, 128, TEXT("鼠标左键被单击%d次"), iClick);
        SetWindowText(hStatic, szBuffer);
        break;

    case WM_DESTROY:
        DeleteObject(hBrush);
        DeleteObject(hFont);//删除创建的字体
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

运行结果:
在这里插入图片描述
所以要想达到修改背景颜色的目的,除了修改static 控件的背景颜色,还要修改文本的背景颜色。

透明背景

实现透明背景需要设置文本背景颜色透明,同时返回没有颜色的画刷。

  1. SetBkMode 函数可以用来设置文本的背景模式,它的原型为:
int SetBkMode(
    HDC hdc,  //设备环境句柄
    int iBkMode  //背景模式
);

iBkMode 有下面两种取值:
取值 说明
OPAQUE 使用当前背景颜色来填充背景。
TRANSPARENT 背景透明。

  1. GetStockObject (NULL_BRUSH); 语句可以返回没有颜色的画刷。

示例代码:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    HDC hdc;//定义设备环境句柄  
    HDC hdcStatic;
    static TCHAR  szBuffer[128];
    //TEXTMETRIC tm;
   // SCROLLINFO si;
    PAINTSTRUCT ps;
    size_t iStrLength;
    static int cxChar, cyChar, cxClient, cyClient;
    static HWND hStatic;//静态文本框
    static HFONT hFont[6]; //声明一个逻辑字体句柄为静态变量
    static HBRUSH hBrush;  //画刷
    int i, n;
    //size_t iLength;
    static int iClick = 0;
    static TCHAR  szFont[10][6] = { TEXT("微软雅黑"),  TEXT("宋体"), TEXT("黑体"),  TEXT("楷体"),  TEXT("幼圆"),  TEXT("隶书") };
    switch (message)
    {
    case WM_SIZE://窗体大小改变
        hdc = GetDC(hWnd);
        //GetClientRect(hwnd, &rect);
        cxClient = LOWORD(lParam);//当前x像素
        cyClient = HIWORD(lParam);//当前y像素
        StringCchPrintf(szBuffer, 128, TEXT("当前客户区的分辨率:%d * %d px"), cxClient, cyClient);
        StringCchLength(szBuffer, 128, &iStrLength);
        SetTextAlign(hdc, TA_CENTER | TA_TOP);
        TextOut(hdc, cxClient / 2, 0, szBuffer, iStrLength);
        ReleaseDC(hWnd, hdc);
        return 0;

    case  WM_CREATE:
        //创建画刷
        hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F));  //翠绿色
        //创建6个字体
        for (i = 0; i < 6; i++)
        {
            hFont[i] = CreateFont(
                -20/*高度*/, -10/*宽度*/, 0/*不用管*/, 0/*不用管*/, 400,//设置字体粗细程度一般这个值设为400,
                FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
                DEFAULT_CHARSET,  //这里我们使用默认字符集,还有其他以 _CHARSET 结尾的常量可用
                OUT_CHARACTER_PRECIS, //输出精度
                CLIP_CHARACTER_PRECIS,  //剪裁精度
                DEFAULT_QUALITY,  //默认输出质量
                FF_DONTCARE,  //不指定字体族*/
                szFont[i]  //字体名
            );
        }

        hStatic = CreateWindow(
            TEXT("static"), //静态文本框的类名
            TEXT("我其实是一个静态文本框"),  //控件的文本
            WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/ | SS_CENTER /*水平居中*/ | SS_CENTERIMAGE /*垂直居中*/,
            20 /*X坐标*/, 20 /*Y坐标*/, 400 /*宽度*/, 300 /*高度*/,
            hWnd,  //父窗口句柄
            (HMENU)1,  //为控件指定一个唯一标识符
            hInst,  //当前程序实例句柄
            NULL
        );
        break;
    case WM_CTLCOLORSTATIC:
        hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(0, 0, 255));  //蓝色
        //SetBkColor(hdcStatic, RGB(0x41, 0x96, 0x4F));  //设置字体背景为翠绿色
        SetBkMode(hdcStatic, TRANSPARENT);  //透明背景
        //return (INT_PTR)hBrush; //这里必须返回画刷句柄
        return (INT_PTR)GetStockObject(NULL_BRUSH);  //无颜色画刷
         

    case WM_PAINT://窗口绘画:点
    {
        //int x, xLast;
        HDC hdc = BeginPaint(hWnd, &ps);//函数为指定窗口进行绘画作准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT 结构中。
        EndPaint(hWnd, &ps);
        return 0;
    }
    case WM_LBUTTONDOWN:  //鼠标左键单击消息
        iClick++;//鼠标点击次数
        //设置控件字体
        n = (iClick) % 6 - 1;//取余减一,
        //更改静态文本框 字体
        SendMessage(
            hStatic,  //欲设置字体的控件句柄
            WM_SETFONT,  //消息名(消息类型)
            (WPARAM)hFont[n],  //取得字体句柄
            NULL  //传空值即可
        );
        StringCchPrintf(szBuffer, 128, TEXT("鼠标左键被单击%d次"), iClick);
        SetWindowText(hStatic, szBuffer);
        break;

    case WM_DESTROY:
        DeleteObject(hBrush);
        DeleteObject(hFont);//删除创建的字体
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

运行效果:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值