再上一篇:3.2 简单的文本显示
上一篇:3.3 滚动条的应用
主页
下一篇:4.1 图形设备接口
再下一篇:4.2 设备描述表
文章列表

3.4 关于文本显示的更多内容

《Windows 下的 C/C++高级编程》讲述Windows环境下调用Win32 API函数程序设计

前面几节已经讲述了一般的Windows应用程序中输出文本时需要解决的问题,这一节再讲述一些关于文本输出的高级内容。

#第65页~ Windows下的C/C++高级编程

3.4.1 更多的文本输出函数

前面的程序中已经使用了一些文本输出函数,主要是TextOut函数,但是并没有详细解释。这一部分来完成这项工作,并介绍一些其他的文本输出函数。

首先,需要介绍SetTextAlign函数,该函数的作用是设置文本输出时的对齐方式,定义如下:

UINT SetTextAlign(

HDC hdc, // 显示设备句柄

UINT fMode // 文本对齐模式

);

其中,参数fMode即所设置的文本对齐模式,其各种取值定义见表3-7。

表3-7 文本对齐模式取值表

取值 意义

TA_LEFT X方向文本对齐模式:左对齐

TA_RIGHT X方向文本对齐模式:右对齐

TA_CENTER X方向文本对齐模式:水平中间对齐

TA_BASELINE X方向文本对齐模式:以水平基线为基础对齐

TA_BOTTOM Y方向文本对齐模式:底端对齐(仅适用于单行文本)

TA_TOP Y方向文本对齐模式:项端对齐(仅适用于单行文本)

VTA_CENTER Y方向文本对齐模式:垂直中间对齐(仅适用于单行文本)VTA_BASELINE Y方向文本对齐模式:以垂直基线为基础对齐(仅适用于单行文本)TA_NOUPDATECP 使用文本输出函数(如TextOut)中指定的X、Y坐标输出文本TA_UPDATECP 忽略文本输出函数所指定的坐标,使用定位函数(如MoveTo)设定的

坐标输出文本

TA_RTLREADING 文本输出方式为从右向左,仅用于希伯来语和阿拉伯语

其中,TA_LEFT、TA_TOP和TA_NOUPDATECP 为缺省值。下面将要介绍TextOut、TabbedTextOut和ExtTextOut函数,它们文本定位方式定义均同上。

TextOut函数。定义如下:

BOOL TextOut(

HDC hdc, // 显示设备句柄

int nXStart, // 起始点的X坐标

int nYStart, // 起始点的Y坐标

LPCTSTR lpString, // 需要显示的字符串

int cbString // 需要显示的字符串的长度

);

其中,参数 nXStart 和 nYStart 分别为起始点的横坐标和纵坐标。在缺省情况下(TA_LEFT),这是所显示的第一个字符的左上角。

参数cbString是需要显示的字符串的长度。需要注意的是,对于ANSI字符串,该值以 #第66页~

第3章 文本显示字节(Byte)计;对于Unicode字符串,该值以字(WORD)计。

TabbedTextOut函数。如果需要显示的字符串中含有制表符(‘\t’或0x09),则TextOut

函数处理起来比较困难,这就需要用到TabbedTextOut函数,其定义如下:

LONG TabbedTextOut(

HDC hDC, // 显示设备句柄

int X, // 起始点的X坐标

int Y, // 起始点的Y坐标

LPCTSTR lpString, // 需要显示的字符串

int nCount, // 需要显示的字符串的长度

int nTabPositions, // 制表符停止位置数组大小

CONST LPINT lpnTabStopPositions, // 制表符停止位置数组指针

int nTabOrigin // 扩展制表符停止位置数组起始点

);

其中,前5个参数与TextOut函数的参数相同。第7个参数lpnTabStopPositions是一个指向整数数组的指针,该数组用于存放制表符的停止位置,以像素为单位。例如,如果平均字符宽度为8个像素,每4个字符一个制表位,则该数组中应存放32、64、96、128等。第6 个参数 nCount 指定了该数组的大小。如果 nCount 的值为 1,则制表符停止位置为lpnTabStopPosition所指向整数的1倍、2倍、3倍……如果nCount值为0而lpnTabStopPositions为NULL,则制表位按缺省的每8个平均字符宽度增加。需要强调的是,制表符停止位置必须是逐渐增大的。

如果将DisplayWithScrollBarV2.c中的读取字符并加以显示的部分换为:

if( (fp=fopen("DisplayWithScrollBarV2.c", "r")) != NULL )

{

for( nCurrentLineNumber=0; nCurrentLineNumber<=nLastLine; nCurrentLineNumber++ )

{

int j=0;

char ch;

if( nCurrentLineNumber < nFirstLine )

while( (ch=fgetc(fp)) != '\n' && ch != EOF )

;

else

while( (ch=fgetc(fp)) != '\n' && ch != EOF )

szBuff[j++] = ch; // 保留制表符

// 使用TabbedTextOut函数以显示制表符,这里使用默认的每8个字符一个制表位

TabbedTextOut( hdc, cxChar*(-nHScrollPos), cyChar*(nCurrentLineNumber-nVScrollPos), szBuff, j, 0,NULL, 0 );

}

}

则显示效果如图3-12所示。

#第67页~ Windows下的C/C++高级编程

图3-12 DisplayWithScrollBarV2.c使用TabbedTextOut输出的效果图

ExtTextOut函数。定义如下:

BOOL ExtTextOut(

HDC hdc, // 显示设备句柄

int X, / 起始点的X坐标

int Y, // 起始点的Y坐标

UINT fuOptions, // 文本显示选项

CONST RECT *lprc, // 矩形结构指针

LPCTSTR lpString, // 需要显示的字符串

UINT cbCount, // 需要显示的字符串的长度

CONST INT *lpDx // 字符间距参数列表指针

);

其中,参数lprc用于指定需要重绘的矩形区域,如果其值为NULL,则表示重绘整个用户区。参数fnOptions通常的选择有ETO_CLIPPED和ETO_OPAQUE,前者表示lprc所指定的矩形是一个剪取矩形,后者表示显示文本前,先用当前背景色填充lprc所指定的矩形。可以两者都不选(设置fuOptions的值为0)或者两者都选(以位或操作符连接)。

参数 lpDx指定了一个整数数组,用以指定需要显示的字符串中相应字符之间的间距,当显示变宽字体的字符串时可能需要使用。如果设置lpDx为NULL,则使用默认的字符间距。

下面的例子说明了该函数的用法:

TCHAR TextToShow[] = TEXT("HelloWindows98!");

int SpaceValue[] = {5,10,15,20,25,30,35,40,35,30,25,20,15,10};

ExtTextOut( hdc, 10, 20, 0, NULL, TextToShow, strlen(TextToShow), SpaceValue );

其显示效果如图3-13所示。

图3-13 ExtTextOut函数显示效果图

#第68页~

第3章 文本显示

DrawText函数。是比较高级的文本输出函数,它提供了对文本进行格式化的能力,并可以识别制表符。其定义如下:

int DrawText(

HDC hDC, // 显示设备句柄

LPCTSTR lpString, // 需要显示的字符串

int nCount, // 需要显示的字符串的长度

LPRECT lpRect, // 显示文本的矩形区域

UINT uFormat // 文本显示选项

);

其中参数lpString和nCount的含义与前面的函数相同。如果,lpString所指向的字符串是以‘\ 0’结尾的,则可以将nCount设置为-1,Windows会自动计算字符串的长度。

参数uFormat用于指定文本显示格式,其各种取值定义见表3-8。

表3-8 DrawText函数中uFormat参数取值定义表

取值 意义

DT_LEFT X方向文本对齐模式:左对齐

DT_RIGHT X方向文本对齐模式:右对齐

DT_CENTER X方向文本对齐模式:水平中间对齐

DT_BOTTOM Y方向文本对齐模式:顶端对齐(仅适用于单行文本)

DT_TOP Y方向文本对齐模式:底端对齐(仅适用于单行文本)

DT_VCENTER Y方向文本对齐模式:垂直中间对齐(仅适用于单行文本)

DT_SIGNLELINE 所有文本在一行内输出,回车符和换行符将被解释为可显示的字符,而

不再作为格式控制字符

DT_NOCLIP 显示文本时不做裁剪(有时可以提高显示效率)

DT_WORDBREAK 如果某一行文本的长度超出了lpRect参数所指定的矩形宽度,该行将在

矩形可以容纳的最大位置处被打断

DT_EXTERNALLEADING 在行距中加入字符的外部行间距(ExternalLeading),如果不设置该标志,

那么在缺省情况下是不包括该值的

计算显示所有文本所需矩形的高度和宽度。如果文本有多行,则DrawTextDT_CALCRECT 将使用lpRect参数所指定的矩形的宽度,而扩展该矩形的底边,以容纳

文本的最后一行。该选项使DrawText计算所需数据,而不执行显示文本

的操作

关闭对“&”字符特殊含义的处理。在默认情况下,DrawText函数将“&”DT_NOPREFIX 字符解释为给紧随其后的字符添加下划线,而将“&&”字符解释为单个

字符“&”

DT_EXPANDTABS 扩展制表符。在缺省情况下,每8个字符一个制表符。通过设置该标志,

表明可以更改默认的制表符大小

DT_TABSTOP 在设置了DT_EXPANDTABS标志后,指定不同的制表符大小,该值存

放在uFrmat参数的高字节中

#第69页~ Windows下的C/C++高级编程

GrayString函数。该函数用于显示一行灰色的文本。在Windows的菜单和对话框中,无效命令就以灰色显示,通常可以使用该函数。该函数比较复杂,这里只是举个例子来简单说明,具体参见MSDN/Platform SDK/Graphics and Multimedia Services/Windows GDI/ Paintingand Drawing Reference/Painting and Drawing Functions/GrayString。示例如下:

TCHAR TextToShow[] = TEXT("This is a gray string.");

GrayString( hdc, GetStockObject(BLACK_BRUSH),

NULL, (DWORD)(LPSTR)TextToShow,

strlen(TextToShow), 10, 10, 0, 0 );

显示效果如图3-14所示。

图3-14 GrayString函数显示效果图

3.4.2 Windows中的字体

Windows中有3种不同的字体技术显示文本。分别为光栅字体、矢量字体和TrueType字体。

光栅字体

是以位图形式存储的,故又称位图字体。光栅字体是为具有特定分辨率的输出设备设计的,所以每一种光栅字体都有特定长宽比和特定的字符大小。由Windows负责为光栅字体合成粗体、斜体和带下划线等效果以及对光栅字体的缩放。但是,这种合成和放大的效果并不理想,而且,只能以整数倍放大。光栅字体的主要优点是显示速度比较快,字体比较清晰,可读性比较好。

矢量字体

通过提取点与点间线段的信息来定义字体。同样,由Windows负责为矢量字体合成粗体、斜体和带下划线等效果以及对矢量字体的缩放。与光栅字体不同,矢量字体可以连续的缩放,可以供具有任意分辨率的输出设备使用。但是,生成矢量字体的开销很大,而且矢量字体的可读性也不是很好,所以一般不使用。矢量字体特别适合于像绘图仪这样的设备,故有时也称为绘图仪字体。

TrueType字体

使用确定字符轮廓的直线和曲线的编码集合来定义字体。TrueType字体中还存储了一些算法信息,用以改善缩放后的字体外观。

自Windows 3.1开始引入TrueType字体。TrueType字体最吸引人的地方在于可以被任意缩放和旋转,并且由于有足够的信息用于改善缩放后的字体外观,所以TrueType字体在任意尺寸时都很漂亮。而且,TrueType字体还有一个非常不错的特性,就是使用TrueType字体,在显示器上显示出来的字和在打印机上打印出来的字是完全一样的。

#第70页~

第3章 文本显示

与前两种字体不同,TrueType字体的粗体、斜体和带下划线等效果不是由Windows负责合成的,而是每种效果单独设为一种字体。例如,Times New Roman 字体是一种常用的TrueType字体,而Times New Roman Bold、Times New Roman Italic、Times New Roman BoldItalic等也分别是一种TrueType字体。

3.4.3 逻辑字体

由于各种设备提供的字体种类不同,因此通常同一文本在不同设备上的显示结果并不完全相同。为了实现设备无关性,通常采取的办法是首先创建逻辑对象,然后再确定相应的物理对象,这里也是如此。为了使字体与设备无关,应用程序在使用字体时,应当首先创建逻辑字体,Windows会自动从特定的设备中选择一种与该逻辑字体匹配得最好的物理字体。逻辑字体是一种GDI对象,描述了字体的各种属性,如字符高度、字符宽度、字符集和字样等。

Windows提供了两个函数来创建逻辑字体,分别为CreateFont和CreateFontIndirect。两者的区别在于CreateFontIndirect函数使用一个LOGFONT结构对象作为参数,该结构有14个域,用以指定所要创建的逻辑字体的信息,而CreateFont函数则直接将这14个域作为参数。为编程方便起见,通常使用CreateFontIndirect函数来创建逻辑字体。该函数定义如下:

HFONT CreateFontIndirect(

CONST LOGFONT *lplf // 指向字符属性结构体(LOGFONT)的指针

);

其中,LOGFONT结构定义如下:

typedef struct tagLOGFONT {

LONG lfHeight; // 设定字符高度

LONG lfWidth; // 设定平均字符宽度

LONG lfEscapement; // 连续字符水平方向逆时针旋转角度值×10

LONG lfOrientation; // 单个字符水平方向逆时针旋转角度值×10

LONG lfWeight; // 字符的粗细

BYTE lfItalic; // 是否斜体

BYTE lfUnderline; // 是否带下划线

BYTE lfStrikeOut; // 是否字体上有横线

BYTE lfCharSet; // 指定所属字体字符集

BYTE lfOutPrecision; // 输出精度

BYTE lfClipPrecision; // 指定如何裁剪位于裁剪区之外的字符

BYTE lfQuality; // 指定匹配程度

BYTE lfPitchAndFamily; // 定义字符间距

TCHAR lfFaceName[LF_FACESIZE]; // 字样名

} LOGFONT;

其中,各个域的含义如下:

lfHeight

以逻辑单位给出所期望的字符高度。具体含义见表3-9。

#第71页~ Windows下的C/C++高级编程

表3-9 lfHeight域取值定义表

取值 意义

> 0 设置其值为所期望的字符高度,对应于TEXTMETRIC结构中的tmHeight域= 0 使用默认值

< 0 设置其绝对值为字符高度(TEXTMETRIC结构中的tmHeight域)——字符内部

间距(TEXTMETRIC结构中的tmInternalLeading域)

lfWidth

以逻辑单位给出所期望的平均字符宽度。如果其值为0,则由Windows根据所设lfHeight的值自动选择一个合理的平均字宽。对应于TEXTMETRIC结构中的tmWidth域。

lfEscapement

显示连续的字符时,后继字符相对于前驱字符在水平方向上逆时针旋转的角度值。需要注意的是,该值以0.1度为单位。也就是说,如果该值为900,其实代表逆时针旋转90度,也就是自下向上显示。其默认值为0,即自左向右显示。

lfOrientation

单个字符自身在水平方向上逆时针旋转的角度值。同样,该值以0.1度为单位,如果设置该值为1800,则字符会颠倒显示。其默认值为0,即正常显示。

lfEscapement域和lfOrientation域作用的区别在于,前者影响的是字符与字符之间的相对位置关系,而后者影响的是单个字符自身的显示角度。

lfWeight

用于指定字体的粗细。取值范围为0到1000。例如,通常字体的取值为400,而对于粗体而言,该值为700。如果该值为0,则使用默认值。

表3-10列举了Windows中定义的一些常用的lfWeight值。

表3-10 lfWeight域取值定义表

常量 取值

FW_DONTCARE 0

FW_THIN 100

FW_EXTRALIGHT 200

FW_ULTRALIGHT 200

FW_LIGHT 300

FW_NORMAL 400

FW_REGULAR 400

FW_MEDIUM 500

FW_SEMIBOLD 600

FW_DEMIBOLD 600

FW_BOLD 700

FW_EXTRABOLD 800

#第72页~

第3章 文本显示

续表

常量 取值

FW_ULTRABOLD 800

FW_HEAVY 900

FW_BLACK 900

lfItalic

用于指定是否为斜体。非零值表示为斜体,零值表示非斜体。

lfUnderline

用于指定是否带下划线。非零值表示带下划线,零值表示不带。

lfStrikeOut

用于指定字符上是否有一条横线穿过。非零值表示有,零值表示没有。

lfCharSet

用于定义字符集。表3-11列举了Windows中定义的一些常用值。

表3-11 lfCharSet域取值定义表

常量 取值

ANSI_CHARSET 0

DEFAULT_CHARSET(默认值) 1

SYMBOL_CHARSET 2

SHIFTJIS_CHARSET 128

OEM_CHARSET 255

lfOutPrecision

用于定义所期望的字体输出精度。输出精度定义了输出与所需字体的高度、宽度、字符间距等的匹配程度。例如,使用OUT_TT_ONLY_PRECIS标志可以指定只使用TrueType字体。该字段比较复杂,一般不大使用。

lfClipPrecision

用于指定如何裁剪位于裁剪区以外的字符。该字段比较复杂,一般不大使用。

lfQuality

用于指定期望字体与实际字体的匹配程度。只影响光栅字体,而不影响TrueType字体。该域常用的取值见表3-12。

表3-12 lfQuality域取值定义表

常量 意义

DEFAULT_QUALITY 字体的外观并不重要

字体的外观比逻辑字体属性的精确匹配更重要。不对光栅字体进行缩PROOF_QUALITY 放,而选择尺寸上最匹配的字体。如果有必要,则合成粗体、斜体、

带下划线或带横线的效果

DRAFT_QUALITY 字体的外观比PROOF_QUALITY稍差。可以对光栅字体进行缩放。

如果有必要,则合成粗体、斜体、带下划线或带横线的效果

#第73页~ Windows下的C/C++高级编程

lfPitchAndFamily

用于确定字符间距和字族。该域为一个字节。其中低两位用于指定字符间距,定义见表3-13。

表3-13 lfPitchAndFamily域低两位取值定义表

取值 意义

0 DEFAULT_PITCH(缺省值)

1 FIXED_PITCH(等宽字体)

2 VARIABLE_PITCH(变宽字体)

高4位用于指定字族,定义见表3-14。

表3-14 lfPitchAndFamily域低两位取值定义表

取值 意义

0x00 FW_DONTCARE(不重要或未知)

0x10 FF_ROMAN(变宽,MS Serifs)

0x20 FF_SWISS(变宽,非MS Serifs)

0x30 FF_MODERN(固定间距)

0x40 FF_SCRIPT(模仿手写)

0x50 FF_DECORATIVE(装饰字体)

lfFanceName

是一个大小为LF_FACESIZE的字符数组,用于存放字体的字样名。

LOGFONT结构几乎所有的域都以0为缺省值,可以在程序中定义一个静态的LOGFONT结构变量(静态变量将被自动初始化为0),这样就不必去设置该结构的每一个域,而只需更改需要改动的域就可以了。也正是因为这个原因,通常使用CreateFontIndirect函数来创建逻辑字体,而不用CreateFont函数。

创建和使用逻辑字体,需要做以下工作。

1. 设置 LOGFONT 结构变量成员的值,通过调用 CreateFontIndirect 函数(也可以用CreateFont函数)来创建逻辑字体,该函数将返回一个HFONT类型的逻辑字体句柄;

2. 调用SelectObject函数将创建的逻辑字体选入设备描述表中,Windows会自动选择与之最匹配的物理字体;

3. 调用DeleteObject函数删除不再使用的逻辑字体。

下面通过一个简单的例子来说明逻辑字体的创建与使用见程序3-5。

程序3-5 CreateFontIndirect.c

#include

#include

#include

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

#第74页~

第3章 文本显示int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpcmdLine, int nCmdShow)

{

static TCHAR szAppName[] = TEXT("LOGFONT");

static TCHAR szClassName[] = TEXT("LogFontClass");

HWND hwnd;

MSG msg;

WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );

wndclass.hCursor = LoadCursor( NULL,IDC_ARROW );

wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );

wndclass.lpszMenuName = NULL;

wndclass.lpszClassName = szClassName;

if ( !RegisterClass( &wndclass ) )

{

MessageBox( NULL, TEXT("This program requires Windows NT!"),

szAppName, MB_ICONERROR );

return 0;

}

hwnd = CreateWindow( szClassName,

TEXT("CreateFontIndirect Program"),

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL );

#第75页~ Windows下的C/C++高级编程

ShowWindow( hwnd, nCmdShow );

UpdateWindow( hwnd );

while ( GetMessage( &msg, NULL, 0, 0 ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static LOGFONT lf;

static HFONT hOldFont,hLeftFont,hTopFont,hRightFont,hBottomFont;

TCHAR TextToShow[]= TEXT("Hello Windows98!");

HDC hdc;

PAINTSTRUCT ps;

switch( message )

{

case WM_CREATE:

lf.lfHeight = 40; // 设置字体高度

lf.lfWidth = 20; // 设置平均字符宽度

lf.lfEscapement = 900; // 设置连续字符为自下往上显示

lf.lfOrientation = 900; // 设置单个字符为左转90度显示

lf.lfWeight = FW_THIN; // 设置字体的粗细为FW_THIN

lf.lfItalic = 1; // 设置字体的斜体属性

lf.lfCharSet = OEM_CHARSET; // 设置字符集为OEM_CHARSET

lf.lfPitchAndFamily = FF_ROMAN; // 设置字符间距和字族

// 创建逻辑字体hLeftFont

hLeftFont = CreateFontIndirect( &lf );

lf.lfEscapement = 0; // 设置连续字符为从左向右显示

lf.lfOrientation = 0; // 设置单个字符为正常显示

lf.lfWeight = FW_ULTRALIGHT; // 设置字体的粗细为FW_ULTRALIGHT

lf.lfItalic = 0; // 去除字体的斜体属性

lf.lfUnderline = 1; // 设置字体的带下划线属性

// 创建逻辑字体hTopFont

hTopFont = CreateFontIndirect( &lf );

#第76页~

第3章 文本显示

lf.lfEscapement = 2700; // 设置连续字符为从上往下显示

lf.lfOrientation = 2700; // 设置单个字符为右转90度显示

lf.lfWeight = FW_NORMAL; // 设置字体的粗细为FW_NORMAL

lf.lfUnderline = 0; // 去除字体的带下划线属性

lf.lfStrikeOut = 1; // 设置字体的带横线属性

// 创建逻辑字体hRightFont

hRightFont = CreateFontIndirect( &lf );

lf.lfEscapement = 1800; // 设置连续字符为从右向左显示

lf.lfOrientation = 1800; // 设置单个字符为颠倒显示

lf.lfWeight = FW_ULTRABOLD; // 设置字体的粗细为FW_ULTRABOLD

lf.lfStrikeOut = 0; // 去除字体的带横线属性

lf.lfCharSet = SYMBOL_CHARSET; // 设置字符集为SYMBOL_CHARSET

// 创建逻辑字体hBottomFont

hBottomFont = CreateFontIndirect( &lf );

return 0;

case WM_PAINT:

hdc = BeginPaint( hwnd, &ps );

// 选择逻辑字体hLeftFont

hOldFont = SelectObject( hdc, hLeftFont );

TextOut( hdc, 40, 355, TextToShow, strlen(TextToShow) );

// 选择逻辑字体hTopFont

SelectObject( hdc, hTopFont );

TextOut( hdc, 100, 20, TextToShow, strlen(TextToShow) );

// 选择逻辑字体hRightFont

SelectObject( hdc, hRightFont );

TextOut( hdc, 465, 50, TextToShow, strlen(TextToShow) );

// 选择逻辑字体hBottomFont

SelectObject( hdc, hBottomFont );

TextOut( hdc, 405, 390, TextToShow, strlen(TextToShow) );

/********* 还原原先的字体 *********/

SelectObject( hdc, hOldFont );

EndPaint( hwnd, &ps );

return 0;

case WM_DESTROY:

#第77页~ Windows下的C/C++高级编程

// 删除不再使用的逻辑字体

DeleteObject( hLeftFont );

DeleteObject( hTopFont );

DeleteObject( hRightFont );

DeleteObject( hBottomFont );

PostQuitMessage( 0 );

return 0;

}

return DefWindowProc( hwnd, message, wParam, lParam );

}

该程序的显示效果如图3-15所示。

图3-15 CreateFontIndirect.c显示效果图

#第78页~

第4章 图形显示

在字符界面的操作系统占据绝对优势的时代,人们就对几乎一成不变的“黑纸白字”日渐厌倦。图形界面操作系统自问世以来,深受人们喜爱。从中不难看出,直观、形象、方便的图形界面对于普通用户所具有的强大吸引力。

是的,Windows的成功,其形象、易用的图形界面特性绝对功不可没。本章就为大家介绍Windows下的图形显示。