⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 17. 文字和字体.txt

📁 本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序写作的方法
💻 TXT
📖 第 1 页 / 共 2 页
字号:
文字和字体
 智能中国——游戏组  整理编译   
 

--------------------------------------------------------------------------------

显示文字是本书所要解决的首要问题,现在我们来研究Microsoft Windows中各种有效字体和字体大小的使用方法以及调整文字的方式。

Windows 3.1发表的TrueType使程序写作者和使用者以灵活的方式处理文字的能力大幅增强。TrueType是轮廓字体技术,由Apple Computer公司和Microsoft公司开发,并被许多字体制造商支持。由于TrueType字体能够连续缩放,并能应用于视讯显示器和打印机,现在能够在Windows下实作真的WYSIWYG(what you see is what you get:所见即所得)。TrueType也便于制作「奇妙」字体,例如旋转的字母、内部填充图案的字母或将它们用于剪裁区域,在本章我将展示它们。

简单的文字输出


让我们先来看看Windows为文字输出、影响文字的设备内容属性以及备用字体提供的各种函数。

文字输出函数


我已经在许多范例程序中使用过最常用的文字输出函数:

TextOut (hdc, xStart, yStart, pString, iCount) ;
        
参数xStart和yStart是逻辑坐标上字符串的起始点。通常,这是Windows开始绘制的第一个字母的左上角。TextOut需要指向字符串的指针和字符串的长度,这个函数不能识别以NULL终止的字符串。

TextOut函数的xStart和yStart参数的含义可由SetTextAlign函数改变。TA_LEFT、TA_RIGHT和TA_CENTER旗标影响使用xStart在水平方向上定位字符串的方式。默认值是TA_LEFT。如果在SetTextAlign函数中指定了TA_RIGHT,则后面的TextOut呼叫会将字符串的最后一个字符定位于xStart,如果指定了TA_CENTER,则字符串的中心位于xStart。

类似地,TA_TOP、TA_BOTTOM和TA_BASELINE旗标影响字符串的垂直位置。TA_TOP是默认值,它意味着字符串的字母顶端位于yStart,使用TA_BOTTOM意味着字符串位于yStart之上。可以使用TA_BASELINE定位字符串,使基准线位于yStart。基准线是如小写字母p、q、y等字母下部的线。

如果您使用TA_UPDATECP旗标呼叫SetTextAlign,Windows就会忽略TextOut的xStart和yStart参数,而使用由MoveToEx、LineTo或更改目前位置的另一个函数设定的位置。TA_UPDATECP旗标也使TextOut函数将目前位置更新为字符串的结尾(TA_LEFT)或字符串的开头(TA_RIGHT)。这在使用多个TextOut呼叫显示一行文字时非常有用。当水平位置是TA_CENTER时,在TextOut呼叫后,目前位置不变。

您应该还记得,第四章的一系列SYSMETS程序显示几列文字时,对每一列都需要呼叫一个TextOut,其替代函数是TabbedTextOut函数:

TabbedTextOut (    hdc, xStart, yStart, pString, iCount,
        
                                                 iNumTabs, piTabStops, xTabOrigin) ;
        
如果文字字符串中含有嵌入的制表符(‘\t’或0x09),则TabbedTextOut会根据传递给它的整数数组将制表符扩展为空格。

TabbedTextOut的前五个参数与TextOut相同,第六个参数是跳位间隔数,第七个是以图素为单位的跳位间隔数组。例如,如果平均字符宽度是8个图素,而您希望每5个字符加一个跳位间隔,则这个数组将包含40、80、120,按递增顺序依此类推。

如果第六个和第七个参数是0或NULL,则跳位间隔按每八个平均字符宽度设定。如果第六个参数是1,则第七个参数指向一个整数,表示跳位间隔重复增大的倍数(例如,如果第六个参数是1,并且第七个参数指向值为30的变量,则跳位间隔设定在30、60、90…图素处)。最后一个参数给出了从跳位间隔开始测量的逻辑x坐标,它与字符串的起始位置可能相同也可能不同。

另一个进阶的文字输出函数是ExtTextOut(前缀Ext表示它是扩展的):

ExtTextOut (hdc, xStart, yStart, iOptions, &rect,
        
                                                 pString, iCount, pxDistance) ;
        
第五个参数是指向矩形结构的指针,在iOptions设定为ETO_CLIPPED时,该结构为剪裁矩形,在iOptions设定为ETO_OPAQUE时,该结构为用目前背景色填充的背景矩形。这两种选择您可以都采用,也可以都不采用。

最后一个参数是整数数组,它指定了字符串中连续字符的间隔。程序可以使用它使字符间距变窄或变宽,因为有时需要在较窄的列中调整单个文字。该参数可以设定为NULL来使用内定的字符间距。

用于写文字的高级函数是DrawText,我们第一次遇到它是在第三章讨论HELLOWIN程序时,它不指定坐标的起始位置,而是通过RECT结构型态定义希望显示文字的区域:

DrawText (hdc, pString, iCount, &rect, iFormat) ;
        
和其它文字输出函数一样,DrawText需要指向字符串的指针和字符串的长度。然而,如果在DrawText中使用以NULL结尾的字符串,就可以将iCount设定为-1,Windows会自动计算字符串的长度。

当iFormat设定为0时,Windows会将文字解释为一系列由carriage return字符(‘\r’或0x0D)或linefeed字符(‘\n’或0x0A)分隔的行。文字从矩形的左上角开始,carriage return字符或linefeed字符被解释为换行字符,因此Windows会结束目前行而开始新的一行。新的一行从矩形的左侧开始,在上一行的下面空开一个字符的高度(没有外部间隔)。包含字母的任何文字都应该显示在所剪裁矩形底部的右边或下边。

您可以使用iFormat参数更改DrawText的内定操作,iFormat由一个或多个旗标组成。DT_LEFT旗标(默认值)指定了左对齐的行,DT_RIGHT指定了向右对齐的行,而DT_CENTER指定了位于矩形左边和右边中间的行。因为DT_LEFT的值是0,所以如果只需要左对齐,就不需要包含标识符。

如果您不希望将carriage return字符或linefeed字符解释为换行字符,则可以包括标识符DT_SINGLELINE。然后,Windows会把carriage return字符和linefeed字符解释为可显示的字符,而不是控制字符。在使用DT_SINGLELINE时,还可以将行指定为位于矩形的顶端(DT_TOP)、底端(DT_BOTTOM)或者中间(DT_VCETER,V表示垂直)。

在显示多行文字时,Windows通常只在carriage return字符或linefeed字符处换行。然而,如果行的长度超出了矩形的宽度,则可以使用DT_WORDBREAK旗标,它使Windows在行内字的末尾换行。对于单行或多行文字的显示,Windows会把超出矩形的文字部分截去,可以使用DT_NOCLIP跳过这个操作,这个旗标还加快了函数的速度。当Windows确定多行文字的行距时,它通常使用不带外部间距的字符高度,如果您想在行距中加入外部间距,就可以使用旗标DT_EXTERNALLEADING。

如果文字中包含制表符(‘\t’或0x09),则您需要包括旗标DT_EXPANDTABS。在内定情况下,跳位间隔设定于每八个字符的位置。通过使用旗标DT_TABSTOP,您可以指定不同的跳位间隔,在这种情况下,iFormat的高字节包含了每个新跳位间隔的字符位置数值。不过我建议您避免使用DT_TABSTOP,因为iFormat的高字节也用于其它旗标。

DT_TABSTOP旗标存在的问题,可以由新的函数DrawTextEx来解决,它含有一个额外的参数:

DrawTextEx (hdc, pString, iCount, &rect, iFormat, &drawtextparams) ;
        
最后一个参数是指向DRAWTEXTPARAMS结构的指针,它的定义如下:

typedef struct tagDRAWTEXTPARAMS
        
{
        
  UINT   cbSize ;                             // size of structure
        
   int    iTabLength ;                  // size of each tab stop
        
   int    iLeftMargin ;                 // left margin
        
   int    iRightMargin ;                // right margin
        
   UINT   uiLengthDrawn ;               // receives number of characters processed
        
} DRAWTEXTPARAMS, * LPDRAWTEXTPARAMS ;
        
中间的三个字段是以平均字符的增量为单位的。

文字的设备内容属性


除了上面讨论的SerTextAlign外,其它几个设备内容属性也对文字产生了影响。在内定的设备内容下,文字颜色是黑色,但您可以用下面的叙述进行更改:

SetTextColor (hdc, rgbColor) ;
        
使用画笔的颜色和画刷的颜色,Windows把rgbColor的值转换为纯色,您可以通过呼叫GetTextColor取得目前文字的颜色。

Windows在矩形的背景区域中显示文字,它可能根据背景模式的设定进行着色,也可能不这样做。您可以使用

SetBkMode (hdc, iMode) ;
        
更改背景模式,其中iMode的值为OPAQUE或TRANSPARENT。内定的背景模式为OPAQUE,它表示Windows使用背景颜色来填充矩形的背景。您可以使用

SetBkColor (hdc, rgbColor) ;
        
来改变背景颜色。rgbColor的值是转换为纯色的值。内定背景色是白色。

如果两行文字靠得太近,其中一个的背景矩形就会遮盖另一个的文字。由于这种原因,我通常希望内定的背景模式是TRANSPARENT。在背景模式为TRANSPARENT的情况下,Windows会忽略背景色,也不对矩形背景区域着色。Windows也使用背景模式和背景色对点和虚线之间的空隙及阴影刷中阴影间的区域着色,就像第五章所讨论的那样。

许多Windows程序将WHITE_BRUSH指定为Windows用于擦出窗口背景的画刷,画刷在窗口类别结构中指定。然而,您可能希望您程序的窗口背景与使用者在「控制台」中设定的系统颜色保持一致,在这种情况下,可以在WNDCLASS结构中指定背景颜色的这种方式:

wndclass.hbrBackground = COLOR_WINDOW + 1 ;
        
当您想要在显示区域书写文字时,可以使用目前系统颜色设定文字色和背景色:

SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;
        
SetBkColor (hdc, GetSysColor (COLOR_WINDOW)) ;
        
完成这些以后,就可以使您的程序随系统颜色的更改而变化:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -