这章总结下文本操作,先上一个简单的文本输出程序:
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)
{
static long nXChar,nCaps,nYChar;
HDC hDC; //定义指向设备上下文的句柄
short x;
TEXTMETRIC tm;
short LnCount=6;
PAINTSTRUCT PtStr; //定义指向包含绘图信息的结构体变量
static char *textbuf[]=
{
"This is the first line",
"This is the second line",
"This is the third line",
"This is the fourth line",
"This is the fifth line",
"This is the sixth line"
};
switch(iMessage) //处理消息
{
case WM_CREATE: //处理窗口创建消息
hDC=GetDC(hWnd) ; //获取当前设备表句柄
GetTextMetrics(hDC,&tm); //获取字体信息
nXChar=tm.tmAveCharWidth; //获取字符宽度
nYChar=tm.tmHeight+tm.tmExternalLeading;
ReleaseDC(hWnd,hDC); //释放当前设备句柄
return 0;
case WM_PAINT: //处理重画消息
hDC=BeginPaint(hWnd,&PtStr); //开始绘画
for(x=0;x<LnCount;x=x+1)
TextOut(hDC,nXChar,nYChar *(1+x),textbuf[x],lstrlen(textbuf[x]));
EndPaint(hWnd,&PtStr);
return 0;
case WM_DESTROY: //结束应用程序
PostQuitMessage(0);
return 0;
default://其他消息处理程序
return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ;
}
}
文本输出有一个重要的结构体是 TEXTMETRIC,它的定义如下:
typedef struct tagTEXTMETRIC { // tm
LONG tmHeight; //字符高度
TEXTMETRIC结构字段的图示
TEXTMETRIC结构字段的图示
LONG tmAscent; //字符上部高度(基线以上)
LONG tmDescent; //字符下部高度(基线以下)
LONG tmInternalLeading, //由tmHeight定义的字符高度的顶部空间数目
LONG tmExternalLeading, //夹在两行之间的空间数目
LONG tmAveCharWidth, //平均字符宽度
LONG tmMaxCharWidth, //最宽字符的宽度
LONG tmWeight; //字体的粗细轻重程度
LONG tmOverhang, //加入某些拼接字体上的附加高度
LONG tmDigitizedAspectX, //字体设计所针对的设备水平方向
LONG tmDigitizedAspectY, //字体设计所针对的设备垂直方向
BCHAR tmFirstChar; //为字体定义的第一个字符
BCHAR tmLastChar; //为字体定义的最后一个字符
BCHAR tmDefaultChar; //字体中所没有字符的替代字符
BCHAR tmBreakChar; //用于拆字的字符
BYTE tmItalic, //字体为斜体时非零
BYTE tmUnderlined, //字体为下划线时非零
BYTE tmStruckOut, //字体被删去时非零
BYTE tmPitchAndFamily, //字体间距(低4位)和族(高4位)
BYTE tmCharSet; //字体的字符集
} TEXTMETRIC;
利用这个结构体我们可以在输出前调用GetTextMetrics(hDC,&tm)先获取到当前的文本信息,根据此计算出下一行的位置,当然在此之前要先调用hDC=GetDC(hWnd)获取当前设备环境。
接下来是textout函数,一行一行输出。
BOOL TextOut(
HDC hdc, // 设备描述表句柄
int nXStart, // 字符串的开始位置 x坐标
int nYStart, // 字符串的开始位置 y坐标
LPCTSTR lpString, // 字符串
int cbString // 字符串中字符的个数
);
再看一个文本输出程序,它的winproc函数如下:
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
HFONT hF_black,hF_big; //定义两种字体句柄
PAINTSTRUCT ps;
TEXTMETRIC tm; //定义一个TEXTMETRIC结构,用以记录字体信息
char lpsz_1[]="这是一行红色的、字体为SYSTEM_FONT的文字,红色代表未来";
char lpsz_2[]="现在显示的是自定义绿色字体,绿色代表生机勃勃";
char lpsz_3[]="这一行是蓝色的粗体字,蓝色代表广阔的海洋和天空";
char lpsz_4[]="这是大号、斜体并带有下划线的文字";
char lpsz_5[]="您掌握了字体的操作了吗?";
char lpsz_6[]="祝您成功!";
int X=0,Y=0;
SIZE size; //定义一个SIZE类型的结构
switch(message)
{
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
SetTextColor(hdc,RGB(255,0,0)); //设置文本颜色为红色
GetTextMetrics(hdc,&tm); //获取缺省字体,写入tm结构中
TextOut(hdc,X,Y,lpsz_1,strlen(lpsz_1)); //使用当前字体输出文本
Y=Y+tm.tmHeight+tm.tmExternalLeading;//计算换行时下一行文本的输出坐标
hF_black=CreateFont //创建自定义字体
(
20, //字体的高度
0, //由系统根据高宽比选取字体最佳宽度值
0, //文本的倾斜度为0,表示水平
0, //字体的倾斜度为0
FW_HEAVY, //字体的粗度,FW_HEAVY为最粗
0, //非斜体字
0, //无下划线
0, //无删除线
GB2312_CHARSET, //表示所用的字符集为ANSI_CHARSET
OUT_DEFAULT_PRECIS, //输出精度为缺省精度
CLIP_DEFAULT_PRECIS, //剪裁精度为缺省精度
DEFAULT_QUALITY, //输出质量为缺省值
DEFAULT_PITCH|FF_DONTCARE,//字间距和字体系列使用缺省值
"粗体字" //字体名称
);
SetTextColor(hdc,RGB(0,255,0)); //设置文本颜色为绿色
SelectObject(hdc,hF_black); //将自定义字体选入设备环境
GetTextMetrics(hdc,&tm); //获取字体的信息,并写入tm结构中
TextOut(hdc,X,Y,lpsz_2,strlen(lpsz_2));//使用当前字体输出文本
//换行继续输出文本,计算新行的起始Y坐标位置
Y=Y+tm.tmHeight+5*tm.tmExternalLeading;
GetTextExtentPoint32(hdc,lpsz_2,strlen(lpsz_2),&size);
//获取字符串的宽度
SetTextColor(hdc,RGB(0,0,255)); //设置文本颜色为蓝色
TextOut(hdc,X,Y,lpsz_3,strlen(lpsz_3));//用当前字体输出文本
Y=Y+tm.tmHeight+5*tm.tmExternalLeading;
hF_big=CreateFont //引入新字体
(
30, //字体高度
0,
0,
0,
FW_NORMAL,
1, //定义斜体
1, //定义输出时带下划线
0,
GB2312_CHARSET, //所使用的字符集
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
"大号字"
);
SelectObject(hdc,hF_big); //将第二种自定义字体选入设备环境
SetTextColor(hdc,RGB(155,155,155)); //设置文本颜色为灰色
Y=Y+tm.tmHeight+5*tm.tmExternalLeading;
TextOut(hdc,X,Y,lpsz_4,strlen(lpsz_4));//以当前字体输出文本
SetTextColor(hdc,RGB(255,0,0)); //设置文本颜色为红色
Y=Y+tm.tmHeight+10*tm.tmExternalLeading;
TextOut(hdc,X,Y,lpsz_5,strlen(lpsz_5)); //输出文本
//在该行继续输出文本
GetTextExtentPoint32(hdc,lpsz_5,strlen(lpsz_5),&size);
//获取字符串的宽度
X=X+size.cx; //获取起始坐标
TextOut(hdc,X+5,Y,lpsz_6,strlen(lpsz_6)); //输出文本
EndPaint(hwnd,&ps);
DeleteObject(hF_black); //删除自定义字体句柄
DeleteObject(hF_big);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
这个函数我们用settextcolor自定义文字颜色,另外我们还用了GetTextExtentPoint32获取指定文字的信息以及创建自己的字体。