如何控制文本的输出方式
问题――
在文本编辑器中,我们可以轻易地实现对输出文本的控制,比如字体大小,颜色设置,对齐方式等。但是,如果我们要在画布(canvas)上直接输出文本,而且要全面地控制这些输出文本的属性,比如设置字符的颜色,大小,背景模式,对齐方式,字符间距等,我们又该怎么办呢?
――程序运行界面图――
解决思路――
我们的问题已经很明了了,只要挨个解决这些问题,就可以全面地控制文本的输出属性,生成漂亮的输出方式了。我们的解决方式是通过调用windows API函数来实现的。下面是相关的函数的具体介绍:SetTextColor(DC: HDC; Color: COLORREF)设置文本输出的颜色,DC是指向设备的句柄,Color则表示要设置的文本颜色;
1.SetBkMode(DC: HDC; BkMode: Integer)
设置设备的背景模式,DC是指向设备的句柄,BKMode则是要设置的背景模式,有两个值可选:OPAQUE表示背景为填充方式,而TRANSPARENT则表示背景为透明方式;
2.SetTextCharacterExtra(DC: HDC; CharExtra: Integer)
设置输出文本的字符间距,DC指向设备句柄,CharExtra表示字符间的象素距离;
3.SetBkColor(DC: HDC; Color: COLORREF)
设置文本输出的背景颜色,DC指向设备句柄,Color则表示要设置的背景颜色;
4.SetTextAlign(DC: HDC; Flags: UINT)
设置输出文本对齐方式。DC是指向设备的句柄,Flags则是设置的对齐方式,具体的对齐方式的参数如下:
a).如果文本是以水平形式输出,则Flags可以从下列值中选取
TA_BASELINE: 基线对齐;
TA_BOTTOM: 底端对齐;
TA_TOP: 顶端对齐;
TA_CENTER: 中间对齐;
TA_LEFT: 左端对齐(默认方式);
TA_RIGHT: 右端对齐;
TA_NOUPDATECP:对齐点在文本输出的过程中不更新;
TA_RTLREADING:只适用于windows 9x以上版本,从右至左对齐方式;
TA_UPDATECP: 对齐点再文本输出的过程中更新;
b).如果文本是以竖直形式输出,则Flags可以从下列中选取
VTA_BASELINE:基线对齐;
VTA_CENTER: 中间对齐;
一般情况下,默认的对齐方式是TA_LEFT,TA_TOP和TA_NOUPDATECP。该函数设置了文本对齐方式之后,TextOut和ExtTextOut函数作用的文本输出方式就确定了。
5.TextOut是文本输出函数,它有两种形式(注意该例中他们的不同点)
a).TextOut(DC: HDC; X, Y: Integer; Str: PChar; Count: Integer)
在指定设备上输出文本,DC指向设备句柄,X,Y表示文本输出的位置,Str代表要输出的文本,Count则指定要输出的字符个数;
b).TextOut(X, Y: Integer; const Text: string)
在指定设备上输出文本,X,Y表示输出文本的位置,Text则表示要输出的文本;
6.DrawText(hDC: HDC; lpString: PChar; nCount: Integer; var lpRect: TRect; uFormat: UINT)
说明:在指定矩形内绘制一格式化文本;
参数说明:hDC--设备描述表句柄;
lpString--指向要绘制的文本字符串;
nCount--文本的长度(字符长度),如果整个字符串都要绘制,则把该参数设为-1;
lpRect--供绘制操作使用的格式化矩形;
uFormat--指定文本绘制方式.它的值可以从下列值中选取:
1.DT_BOTTOM:必须同时指定DT_SINGLELINE,它将使文本设置为与格式化矩形底部对齐;
2.DT_CALCRECT:按下列方式指定矩形的宽度和高度:如果进行多行文本绘制时,扩展矩形的底部直到能框住文本;当只绘制一行文本时,扩展矩形的右侧直到能框住文本.这里文本并不绘制出来,只是将lpRect参数指定的矩形按计算的尺寸装入;
3.DT_CENTER :设置文本在格式化矩形中水平居中;
4.DT_EDITCONTROL:绘制正文和扩充制表符号.制表符的默认间隔是八个字符,但这个间隔可以通过DT_TABSTOP标志来改变;
5.DT_EXPANDTABS :扩展制表符,默认值是每个制表符占八位;
6.DT_END_ELLIPSIS或DT_PATH_ELLIPSIS:如果可能的话,用椭圆替换给定的字符串,使文本适应指定的矩形,给定的字符串不能被修改,除非使用了DT_MODIFYSTRING标记.可以指定DT_END_ELLIPSIS在字符串的尾部替换字符,或用DT_PATH_ELLIPSIS替换字符串中间的字符.如果字符串中含有"/",DT_PATH_ELLIPSIS会尽可能地保留"/"后的字符;
7.DT_EXTERNALLEADING :包括字体外部引线行高度.一般地,外部引线没有包含在文本的行高中.
8.DT_LEFT :文本左对起,这是文本的默认方式;
9.DT_MODIFYSTRING:修改给定的字符串以便与显示方式相匹配,如果设置了DT_END_ELLIPSIS和DT_PATH_ELLIPSIS标记,则这个参数无效;
10.DT_NOCLIP:无裁剪方式绘制文本,如果设置了这个参数,则会加快DrawText()的速度;
11.DT_NOPREFIX :关闭前缀字符处理.一般地,DrawText()会解释记忆功能的前缀"&",用它指示下画线;把"&&"指示输出一个单独的"&".如果指定DT_NOPREFIX,就停止这些处理;
12.DT_RIGHT :设置文本为右对起方式;
13.DT_RTLREADING:如果被选进hdc的字体是Hebrew和Arabic,则设置文本对齐方式为从右至左,默认方式都是从左至右;
14.DT_SINGLELINE:单行显示文本;
15.DT_TABSTOP:设置制表符终止.uFormat参数低字的高位(8-15位)为每个制表符指定字符数,默认每个制表符的字符数是8位;
16.DT_TOP:设置文本为顶端对齐方式;
17.DT_VCENTER::设置文本为垂直中心对齐方式;
18.DT_WORDBREAK :中断字.如果一个字超过了由lpRect指定的矩形边框,则行会自动增加.
注意:DT_CALCRECT,DT_EXTERNALLEADING,DT_INTERNAL,DT_NOCLIP和DT_NOPREFIX值不能和DT_TABSTOP联合使用;
具体实现――
1.界面布局及控件属性
界面的布局中重要的控件属性值设置如下:
combobox1的items和combobox2的items的属性设置如图所示;
trackbar1的max为30,min为0,position为0;
shape2的brush.color是clBlack;
2.主要的源代码及注释如下:
procedure TForm1.Button1Click(Sender: TObject);
var _rect:TRect;
begin
_rect:=rect(40,160,100,200); //设置drawtext函数中文本输出的矩形;
refresh;
//一定要放在输出文本的代码前面;
with form1.Canvas do
begin
case combobox1.Items.IndexOf(combobox1.text) of
//设置输出文本的对齐风格,该代码段的位置一定要靠前,否则可能不会有预期的效果;
0: settextalign(handle,TA_CENTER);
1: settextalign(handle,TA_RIGHT);
2: settextalign(handle,TA_BASELINE);
3: settextalign(handle,TA_LEFT);
end;
if checkbox1.Checked then
setbkmode(handle,transparent); //设置背景模式;
SetTextCharacterExtra(handle,trackbar1.position); //设置字符间距;
settextcolor(handle,shape1.brush.color); //设置字体颜色;
setbkcolor(handle,shape2.Brush.color); //设置背景颜色;
font.size:=15; //设置字体大小;
textout(40,40,'无限制的输出效果!'); //textout函数方式一输出文本;
end;
//textout函数方式二输出文本;
textout(form1.canvas.handle,40,80,'有限制的输出效果!',strtoint(edit1.text));
case combobox2.Items.IndexOf(combobox2.text) of
// DrawText函数按指定方式输出文本;
0: drawtext(form1.canvas.handle,'hello,你好',10,_rect,DT_BOTTOM);
1: drawtext(form1.canvas.handle,'hello,你好',10,_rect,DT_CENTER);
2: drawtext(form1.canvas.handle,'hello,你好',10,_rect,DT_NOCLIP);
3: drawtext(form1.canvas.handle,'hello,你好',10,_rect,DT_SINGLELINE);
end;
end;
procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if colordialog1.Execute then //设置输出文本颜色;
shape1.Brush.Color:=colordialog1.Color;
end;
procedure TForm1.Shape2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if colordialog2.Execute then //设置文本背景颜色;
shape2.Brush.Color:=colordialog2.Color;
end;