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

📄 4.输出文字.txt

📁 本书介绍了在Microsoft Windows 98、Microsoft Windows NT 4.0和Windows NT 5.0下程序写作的方法
💻 TXT
📖 第 1 页 / 共 5 页
字号:
字符大小


要用TextOut显示多行文字,就必须确定字体的字符大小,可以根据字符的高度来定位字符的后续行,以及根据字符的宽度来定位字符的后续列。

系统字体的字符高度和平均宽度是多少?这个问题取决于视讯显示器的图素大小。Windows需要的最小显示大小是640×480,但是许多使用者更喜欢800×600或1024×768的显示大小。另外,对于这些较大的显示尺寸,Windows允许使用者选择不同大小的系统字体。

程序可以呼叫GetSystemMetrics函数以取使用者接口上各类视觉组件大小的信息,呼叫GetTextMetrics取得字体大小。GetTextMetrics传回设备内容中目前选取的字体信息,因此它需要设备内容句柄。Windows将文字大小的不同值复制到在WINGDI.H中定义的TEXTMETRIC型态的结构中。TEXTMETRIC结构有20个字段,我们只使用前七个:

typedef struct tagTEXTMETRIC
        
{
        
    LONG tmHeight ;
        
    LONG tmAscent ;
        
    LONG tmDescent ;
        
    LONG tmInternalLeading ;
        
    LONG tmExternalLeading ;
        
    LONG tmAveCharWidth ;
        
   LONG tmMaxCharWidth ;
        
           其它结构字段
        
}
        
TEXTMETRIC, * PTEXTMETRIC ;
        
这些字段值的单位取决于选定的设备内容映像方式。在内定设备内容下,映像方式是MM_TEXT,因此值的大小是以图素为单位。

要使用GetTextMetrics函数,需要先定义一个结构变量(通常称为tm):

TEXTMETRIC tm ;
        
在需要确定文字大小时,先取得设备内容句柄,再呼叫GetTextMetrics:

hdc = GetDC (hwnd) ;
        
GetTextMetrics (hdc, &tm) ;
        
ReleaseDC (hwnd, hdc) ;
        
此后,您就可以查看文字尺寸结构中的值,并有可能保存其中的一些以备将来使用。

文字大小:细节


TEXTMETRIC结构提供了关于目前设备内容中选用的字体的丰富信息。但是,字体的纵向大小只由5个值确定,其中4个值如图4-3所示。


 



图4-3 定义字体中纵向字符大小的4个值
 

最重要的值是tmHeight,它是tmAscent和tmDescent的和。这两个值表示了基准在线下字符的最大纵向高度。「间距」(leading)指打印机在两行文字间插入的空间。在TEXTMETRIC结构中,内部的间距包括在tmAscent中(因此也在tmHeight中),并且它经常是重音符号出现的地方。tmInternalLeading字段可被设成0,在这种情况下,加重音的字母会稍稍缩短以便容纳重音符号。

TEXTMETRIC结构还包括一个不包含在tmHeight值中的字段tmExternalLeading。它是字体设计者建议加在横向字符之间的空间大小。在安排文字行之间的空隙时,您可以接受设计者建议的值,也可以拒绝它。在系统字体中tmExternalLeading可以为0,因此我没有在图4-3中显示它。(尽管我不想告诉你们,图4-3确实就是Windows在640×480的显示分辨率中使用的系统字体。)

TEXTMETRICS结构包含有描述字符宽度的两个字段,即tmAveCharWidth(小写字母加权平均宽度)和tmMaxCharWidth(字体中最宽字符的宽度)。对于定宽字体,这两个值是相等的(图4-3中这些值分别为7和14)。

本章的范例程序还需要另一种字符宽度,即大写字母的平均宽度,这可以用tmAveCharWidth乘以150%大致计算出来。

必须认识到,系统字体的大小取决于Windows所执行的视讯显示器的分辨率,在某些情况下,取决于使用者选取的系统字体的大小。Windows提供了一个与设备无关的图形接口,但程序写作者还是有事情要处理的。不要想当然耳地猜测字体大小来写作Windows程序,也不要把值定死,您可以使用GetTextMetrics函数取得这一信息。

格式化文字


Windows启动后,系统字体的大小就不会发生改变,所以在程序执行过程中,程序写作者只需要呼叫一次GetTexMetrics。最好是在窗口消息处理程序中处理WM_CREATE消息时进行此呼叫,WM_CREATE消息是窗口消息处理程序接收的第一个消息。在WinMain中呼叫CreateWindow时,Windows会以一个WM_CREATE消息呼叫窗口消息处理程序。

假设要编写一个Windows程序,在显示区域显示几行文字,这需要先取得字符宽度和高度。您可以在窗口消息处理程序内定义两个变量来保存平均字符宽度(cxChar)和总的字符高度(cyChar):

static int cxChar, cyChar ;
        
变量名的前缀c代表「count」,在这里指图素数,与x和y结合,分别指宽和高。这些变量定义为static静态变量,因为它们在窗口消息处理程序中处理其它消息(如WM_PAINT)时也应该是有效的。如果变量在函数外面定义,则不需要定义为static。

下面是取得系统字体的字符宽度和高度的WM_CREATE程序代码:

case WM_CREATE:
        
    hdc = GetDC (hwnd) ;
        
    GetTextMetrics (hdc, &tm) ;
        
    cxChar = tm.tmAveCharWidth ;
        
    cyChar = tm.tmHeight + tm.tmExternalLeading ;
        

    ReleaseDC (hwnd, hdc) ;
        
    return 0 ;
        
注意我在计算cyChar时包括了tmExternalLeading字段,虽然该字段在系统字体中为0,但是因为它使得文字的可读性更好,所以还是应该把它包括进去。沿着窗口向下每隔cyChar图素就会显示一行文字。

您会发现常常需要显示格式化的数字跟简单的字符串。我在第二章讲到过,您不能使惯用的工具(可爱的printf函数)来完成这项工作,但是可以使用sprintf和Windows版的sprintf-wsprintf。这些函数与printf相似,只是把格式化字符串放到字符串中。然后,可以用TextOut将字符串输出到显示器上。非常方便的是,从sprintf和wsprintf传回的值就是字符串的长度。您可以将这个值传递给TextOut作为iLength参数。下面的程序代码显示了wsprintf与TextOut的典型组合:

int  iLength ;
        
TCHAR szBuffer [40] ;
        
其它行程序
        
iLength = wsprintf (szBuffer, TEXT ("The sum of %i and %i is %i"),
        
                        iA, iB, iA + iB) ;
        
TextOut (hdc, x, y, szBuffer, iLength) ;
        
对于这样简单的情况,可以将nLength的定义值与TextOut放在同一条叙述中,从而无需定义iLength:

TextOut (hdc, x, y, szBuffer,
        
  wsprintf (szBuffer, TEXT ("The sum of %i and %i is %i"),
        
                    iA, iB, iA + iB)) ;
        
虽然这样子写起来不好看,但是功能与前者是一样的。

综合使用


现在,我们似乎已经具备了在屏幕上显示多行文字所需要的所有知识。我们知道如何在WM_PAINT消息处理期间取得一个设备内容句柄,如何使用TextOut函数以及如何根据字符大小来安排字距,剩下的就是显示一点有意义的东西了。

在前一章里,我们大概知道从Windows的GetSystemMetrics函数中取得的信息是很有意义的,该函数传回Windows中不同视觉组件的大小信息,如图标、光标、标题列和滚动条等。它们的大小因显示卡和驱动程序的不同而有所不同。GetSystemMetrics是在程序中完成与设备无关图形输出的重要函数。

该函数需要一个参数,叫做「索引」,在Windows表头文件定义了75个整数索引标识符(标识符的数量随着每个版本的Windows的发布而不断地增加,在Windows 1.0的程序写作者文件中仅列出了26个)。GetSystemMetrics传回一个整数,这个整数通常就是参数中指定的图形组件大小。

让我们来编写一个程序,显示一些可以从GetSystemMetrics呼叫中取得的信息,显示格式为每种视觉组件一行。如果我们建立一个表头文件,在表头文件中定义一个结构数组,此结构包含GetSystemMetrics索引对应的Windows表头文件标识符和呼叫所传回的每个值对应的字符串,这样处理起来要容易一些。表头文件名为SYSMETS.H,如程序4-1所示。

程序4-1 SYSMETS.H 
        
/*---------------------------------------------------------
        
SYSMETS.H -- System metrics display structure
        
-----------------------------------------------------------*/
        
#define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
        
struct
        
{
        
    int    Index ;
        
    TCHAR *       szLabel ;
        
   TCHAR *       szDesc ;
        
}
        
sysmetrics [] =
        
{
        
  SM_CXSCREEN,    TEXT ("SM_CXSCREEN"),            
        
                  TEXT ("Screen width in pixels"),
        
    SM_CYSCREEN, TEXT ("SM_CYSCREEN"),            
        
                         TEXT ("Screen height in pixels"),
        
    SM_CXVSCROLL, TEXT ("SM_CXVSCROLL"),           
        
                          TEXT ("Vertical scroll width"),
        
    SM_CYHSCROLL,  TEXT ("SM_CYHSCROLL"),           
        
                          TEXT ("Horizontal scroll height"),
        
    SM_CYCAPTION, TEXT ("SM_CYCAPTION"),           
        
                             TEXT ("Caption bar height"),
        
    SM_CXBORDER, TEXT ("SM_CXBORDER"),            
        
                          TEXT ("Window border width"),
        
    SM_CYBORDER,  TEXT ("SM_CYBORDER"),            
        
                          TEXT ("Window border height"),
        
    SM_CXFIXEDFRAME,TEXT ("SM_CXFIXEDFRAME"),        
        
                          TEXT ("Dialog window frame width"),
        
    SM_CYFIXEDFRAME,TEXT ("SM_CYFIXEDFRAME"),        
        
                          TEXT ("Dialog window frame height"),
        
    SM_CYVTHUMB,  TEXT ("SM_CYVTHUMB"),            
        
                         TEXT ("Vertical scroll thumb height"),
        
    SM_CXHTHUMB,    TEXT ("SM_CXHTHUMB"),            
        
                             TEXT ("Horizontal scroll thumb width"),
        
    SM_CXICON,       TEXT ("SM_CXICON"),             
        
                          TEXT ("Icon width"),
        
    SM_CYICON,       TEXT ("SM_CYICON"),              
        
                        TEXT ("Icon height"),
        
    SM_CXCURSOR,  TEXT ("SM_CXCURSOR"),            
        
                          TEXT ("Cursor width"),
        
    SM_CYCURSOR,    TEXT ("SM_CYCURSOR"),           
        
                          TEXT ("Cursor height"),
        
    SM_CYMENU,       TEXT ("SM_CYMENU"),              
        
                          TEXT ("Menu bar height"),
        
    SM_CXFULLSCREEN,TEXT ("SM_CXFULLSCREEN"),        
        
                          TEXT ("Full screen client area width"),
        
    SM_CYFULLSCREEN,TEXT ("SM_CYFULLSCREEN"),        
        
                          TEXT ("Full screen client area height"),
        
    SM_CYKANJIWINDOW,TEXT ("SM_CYKANJIWINDOW"),       
        
                           TEXT ("Kanji window height"),
        
    SM_MOUSEPRESENT, TEXT ("SM_MOUSEPRESENT"),        
        
                           TEXT ("Mouse present flag"),
        
    SM_CYVSCROLL,TEXT ("SM_CYVSCROLL"),           
        
                           TEXT ("Vertical scroll arrow height"),
        
    SM_CXHSCROLL,TEXT ("SM_CXHSCROLL"),           
        
                          TEXT ("Horizontal scroll arrow width"),

⌨️ 快捷键说明

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