字符串的显示
文本字符在窗口中显示一般有2种方法,一是在指定位置显示文本使用TextOut()函数,在指定区域显示文字使用上一章讲的DrawText()函数功能比较强大,能自动回行、显示快捷键上下左右对齐等。另外本章还要介绍如何设置文本的前景背景。
一、DrawText()函数的格式
DrawText()函数的原型上一章已经说明,这里仅解释最后一个参数:格式输出。
- DT_LEFT、DT_CENTER、DT_RIGHT横向对齐的三种方式
- DT_TOP、DT_VCENTER、DT_BOTTON纵向对齐的三种方式
- DT_WORDBREAK一行写不下时自动回行
- DT_END_ELLIPSIS、DT_WORD_ELLIPSIS、DT_PATH_ELLIPSIS 一行写不下时用省略号代替。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hdc;//设备文本句柄
PAINTSTRUCT ps;//窗口客户区结构体
TCHAR szHello[] = "My first GDI is so easy and cool!";//显示的文字
switch(message) {
case WM_PAINT://重绘消息
hdc = BeginPaint(hWnd, &ps);//开始描画
//定义四个区域,初始值为窗口有效区
RECT rc1, rc2, rc3, rc4;//定义客户区变量
GetClientRect(hWnd, &rc1);//获取窗口有效区域
rc4 = rc3 = rc2 = rc1;
//设置rc1为窗口有效区的上面四分之一
rc1.bottom /= 4;
rc2.top = rc1.bottom;
//设置rc2为窗口有效区的中上四分之一
rc2.bottom /= 2;
rc3.top = rc2.bottom;
//设置rc3为窗口有效区的中下四分之一
rc3.bottom -= rc1.bottom;
//舍子rc4为窗口有效区的下面四分之一
rc4.top = rc3.bottom;
//当文字在窗口中显示不下时的四中情况的比较
DrawText(hdc, szHello, (int)strlen(szHello), &rc1, DT_END_ELLIPSIS);
DrawText(hdc, szHello, (int)strlen(szHello), &rc2, DT_WORD_ELLIPSIS);
DrawText(hdc, szHello, (int)strlen(szHello), &rc3, DT_WORD_ELLIPSIS);
DrawText(hdc, szHello, (int)strlen(szHello), &rc4, DT_WORDBREAK);
EndPaint(hWnd, &ps);//结束描画
break;
二、改变文字颜色SetTextColor()函数
Windows中颜色类型是COLORREF,实际上就是DWORD类型(即32位无符号整形),共4字节,高位的一个字节保留为00,其他三个字节表示红绿蓝三基色,用16进制即是0x000000FF表示“红色“
//当文字在窗口中显示不下时的四中情况的比较
SetTextColor(hdc, 0x0000FF);//设置颜色
DrawText(hdc, szHello, (int)strlen(szHello), &rc1, DT_END_ELLIPSIS);
SetTextColor( hdc, RGB(0,255,0) );
DrawText(hdc, szHello, (int)strlen(szHello), &rc2, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xF00000);
DrawText(hdc, szHello, (int)strlen(szHello), &rc3, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xFF00F0);
DrawText(hdc, szHello, (int)strlen(szHello), &rc4, DT_WORDBREAK);
三、改变文字背景色SetBkColor()函数
设置文字背景用SetBkColor()函数,该函数如果成功,则返回前一背景色,否则返回CLR_INVALID。如果不需要文字有背景,可以通过SetBkMode()函数来实现背景透明或不透明。
//当文字在窗口中显示不下时的四中情况的比较
SetTextColor(hdc, 0x0000FF);//设置文字颜色
SetBkColor(hdc, 0xCDFAFF);//设置文字背景
DrawText(hdc, szHello, (int)strlen(szHello), &rc1, DT_END_ELLIPSIS);
SetTextColor( hdc, RGB(0,256,0) );
SetBkColor(hdc, 0xFFFFE0);
DrawText(hdc, szHello, (int)strlen(szHello), &rc2, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xF00000);
SetBkMode(hdc, TRANSPARENT); //设置文字背景为透明
DrawText(hdc, szHello, (int)strlen(szHello), &rc3, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xFF00F0);
SetBkMode(hdc, OPAQUE); //设置文字背景不透明
DrawText(hdc, szHello, (int)strlen(szHello), &rc4, DT_WORDBREAK);
EndPaint(hWnd, &ps);//结束描画
break;
本节完整代码
#include <windows.h>
TCHAR szWindowClass[] = "My first window's name";
TCHAR szTitle[] = "My first window";
ATOM MyRegisterClass(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {
MSG msg;
MyRegisterClass(hInstance);
if ( !InitInstance(hInstance, nShowCmd) ) {
return FALSE;
}
while ( GetMessage(&msg, NULL, 0, 0) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance) {
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(hInstance, IDC_SIZEALL);
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szWindowClass;
wc.hIconSm = LoadIcon(wc.hInstance, IDI_APPLICATION);
return RegisterClassEx(&wc);
}
BOOL InitInstance(HINSTANCE hInstance, int ncmdshow) {
HWND hWnd;
hWnd = CreateWindow(szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
120,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd) {
return FALSE;
}
ShowWindow(hWnd, ncmdshow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hdc;//设备文本句柄
PAINTSTRUCT ps;//窗口客户区结构体
TCHAR szHello[] = "My first GDI is so easy and cool!";//显示的文字
switch(message) {
case WM_PAINT://重绘消息
hdc = BeginPaint(hWnd, &ps);//开始描画
//定义四个区域,初始值为窗口有效区
RECT rc1, rc2, rc3, rc4;//定义客户区变量
GetClientRect(hWnd, &rc1);//获取窗口有效区域
rc4 = rc3 = rc2 = rc1;
//设置rc1为窗口有效区的上面四分之一
rc1.bottom /= 4;
rc2.top = rc1.bottom;
//设置rc2为窗口有效区的中上四分之一
rc2.bottom /= 2;
rc3.top = rc2.bottom;
//设置rc3为窗口有效区的中下四分之一
rc3.bottom -= rc1.bottom;
//舍子rc4为窗口有效区的下面四分之一
rc4.top = rc3.bottom;
//当文字在窗口中显示不下时的四中情况的比较
SetTextColor(hdc, 0x0000FF);//设置文字颜色
SetBkColor(hdc, 0xCDFAFF);//设置文字背景
DrawText(hdc, szHello, (int)strlen(szHello), &rc1, DT_END_ELLIPSIS);
SetTextColor( hdc, RGB(0,256,0) );
SetBkColor(hdc, 0xFFFFE0);
DrawText(hdc, szHello, (int)strlen(szHello), &rc2, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xF00000);
SetBkMode(hdc, TRANSPARENT); //设置文字背景为透明
DrawText(hdc, szHello, (int)strlen(szHello), &rc3, DT_WORD_ELLIPSIS);
SetTextColor(hdc, 0xFF00F0);
SetBkMode(hdc, OPAQUE); //设置文字背景不透明
DrawText(hdc, szHello, (int)strlen(szHello), &rc4, DT_WORDBREAK);
EndPaint(hWnd, &ps);//结束描画
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}