当 static 控件或具有
ES_READONLY
风格的 edit 控件被绘制时,会向父窗口发送
WM_CTLCOLORSTATIC
消息。如果我们在窗口过程中处理该消息,就必须返回一个画刷句柄,Windows 会使用该画刷来绘制控件背景(子窗口背景)。
也就是说,改变 static 控件的背景颜色只有这一种方式,就是处理
WM_CTLCOLORSTATIC
消息。
WM_CTLCOLORSTATIC
消息就是用来设置背景画刷的。
改变 static 控件的背景颜色:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
static TCHAR szClassName[] = TEXT("HelloWin"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; // 窗口类
hInst = hInstance;
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadIcon(NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景画刷
wndclass.lpszMenuName = NULL; //窗口菜单
wndclass.lpszClassName = szClassName; // 窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口类的名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
//显示窗口
ShowWindow(hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow(hwnd);
/**********第③步:消息循环**********/
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
/**********第④步:窗口过程**********/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
HDC hdc; //设备环境句柄
PAINTSTRUCT ps; //存储绘图环境的相关信息
static HFONT hFont; //逻辑字体
static HWND hStatic; //静态文本框控件
static HBRUSH hBrush; //画刷
switch (message)
case WM_CREATE:
//创建画刷
hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F)); //翠绿色
//创建逻辑字体
hFont = CreateFont(
-14/*高*/, -7/*宽*/, 0, 0, 400 /*一般这个值设为400*/,
FALSE/*斜体?*/, FALSE/*下划线?*/, FALSE/*删除线?*/, DEFAULT_CHARSET,
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
FF_DONTCARE, TEXT("微软雅黑")
//创建静态文本框控件
hStatic = CreateWindow(TEXT("static"), TEXT("欢迎来到中国!"),
WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_CENTER,
20 /*x坐标*/, 20 /*y坐标*/, 240 /*宽度*/, 60 /*高度*/,
hWnd /*父窗口句柄*/, (HMENU)1 /*控件ID*/, hInst /*当前程序实例句柄*/, NULL
//设置控件的字体
SendMessage(hStatic, WM_SETFONT, (WPARAM)hFont, NULL);
break;
case WM_CTLCOLORSTATIC:
return (INT_PTR)hBrush; //这里必须返回画刷句柄
case WM_PAINT: //窗口绘制消息
hdc = BeginPaint(hWnd, &ps); //开始绘图并返回环境句柄
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps); //结束绘图并释放环境句柄
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 表示控件句柄)。
下面的代码会修改文本的背景色和前景色:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
static TCHAR szClassName[] = TEXT("HelloWin"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; // 窗口类
hInst = hInstance;
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadIcon(NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //窗口背景画刷
wndclass.lpszMenuName = NULL; //窗口菜单
wndclass.lpszClassName = szClassName; // 窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口类的名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
//显示窗口
ShowWindow(hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow(hwnd);
/**********第③步:消息循环**********/
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
/**********第④步:窗口过程**********/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
PAINTSTRUCT ps; //存储绘图环境的相关信息
HDC hdcWnd;
HDC hdcStatic;
static HFONT hFont; //逻辑字体
static HWND hStatic; //静态文本框控件
static HBRUSH hBrush; //画刷
switch (message)
case WM_CREATE:
//创建画刷
hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F)); //翠绿色
//创建逻辑字体
hFont = CreateFont(
-14/*高*/, -7/*宽*/, 0, 0, 400 /*一般这个值设为400*/,
FALSE/*斜体?*/, FALSE/*下划线?*/, FALSE/*删除线?*/, DEFAULT_CHARSET,
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY,
FF_DONTCARE, TEXT("微软雅黑")
//创建静态文本框控件
hStatic = CreateWindow(TEXT("static"), TEXT("欢迎来到中国!"),
WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE | SS_CENTER,
20 /*x坐标*/, 20 /*y坐标*/, 240 /*宽度*/, 60 /*高度*/,
hWnd /*父窗口句柄*/, (HMENU)1 /*控件ID*/, hInst /*当前程序实例句柄*/, NULL
//设置控件的字体
SendMessage(hStatic, WM_SETFONT, (WPARAM)hFont, 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: //窗口绘制消息
hdcWnd = BeginPaint(hWnd, &ps); //开始绘图并返回环境句柄
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps); //结束绘图并释放环境句柄
break;
case WM_DESTROY: //窗口销毁消息
DeleteObject(hBrush);
DeleteObject(hFont); //删除创建的字体
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
运行结果:
所以要想达到修改背景颜色的目的,除了修改static 控件的背景颜色,还要修改文本的背景颜色。
实现透明背景需要设置文本背景颜色透明,同时返回没有颜色的画刷。
-
SetBkMode
函数可以用来设置文本的背景模式,它的原型为:
int SetBkMode(
HDC hdc, //设备环境句柄
int iBkMode //背景模式
iBkMode 有下面两种取值:
-
GetStockObject (NULL_BRUSH);
语句可以返回没有颜色的画刷。
示例代码:
case WM_CTLCOLORSTATIC:
hdcStatic = (HDC)wParam;
SetTextColor( hdcStatic, RGB(0x41, 0x96, 0x4F) ); //翠绿色
SetBkMode(hdcStatic, TRANSPARENT); //透明背景
return (INT_PTR)GetStockObject(NULL_BRUSH); //无颜色画刷
运行效果:
当 static 控件或具有 ES_READONLY 风格的 edit 控件被绘制时,会向父窗口发送 WM_CTLCOLORSTATIC 消息。如果我们在窗口过程中处理该消息,就必须返回一个画刷句柄,Windows 会使用该画刷来绘制控件背景(子窗口背景)。
也就是说,改变 static 控件的背景颜色只有这一种方式,就是处理 WM_CTLCOLORSTATIC 消息。WM_CTLCOLOR
当 static 控件或具有 ES_READONLY 风格的 edit 控件被绘制时,会向父窗口发送 WM_CTLCOLORSTATIC 消息。如果我们在窗口过程中处理该消息,就必须返回一个画刷句柄,Windows 会使用该画刷来绘制控件背景(子窗口背景)。
也就是说,改变 static 控件的背景颜色只有这一种方式,就是处理 WM_CTLCOLORSTATIC 消息。WM_CTLCOLORSTATIC 消息就是用来设置背景画刷的。
改变 static 控件的背景颜色
LRESULT CALLBACK Wn
通过MSG_WM_CTLCOLORSTATIC消息修改static控件背景色模式为透明
HBRUSH CTestView::OnCtlColorStatic(CDCHandle dc, CStatic wndStatic) {
// 修改背景色模式为透明
WNDPROC OldProc = NULL;
LRESULT CALLBACK StaticControlProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (msg == WM_PAINT)
PAINTSTRUCT ps = { 0 };...
VS2017创建Windows程序过程及错误 error LNK2019: 无法解析的外部符号 _main,该符号在函数 “int __cdecl invoke_main(void)” (?invok
11906