现在我们对GDI的基础概念有了一定的了解,下面我们将对GDI一些常用的函数进行学习。
TextOut函数
TextOut函数的作用是把指定的字符串输出在我们指定的屏幕位置上。
函数原型:
BOOL TextOut(XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
HDC PerlINK '''">hdc, // 设备描述表句柄
int nXStart, // 输出的x轴水平位置
int nYStart, // 输出的y轴垂直位置
LPCTSTR lpString, // 指向要输出字符串的长指针
int cbString // 字符串长度
);
第一参数是设备描述表句柄,它既可以是通过BeginPaint函数获得的,也可以是通过GetDC函数获得的,需要提一下的是,设备描述表中的属性控制了显示的字符串的一些细节特征,比如字体、字体颜色、文字背景等,但要注意的是保存在设备描述表属性中的文字背景颜色和WNDCLASS结构中的屏幕背景是有区别的,文字背景指的是紧靠字符周围的矩形空间,又叫做字符框。而窗口背景则是一个画刷,Windows用它来擦除显示区域,它不是设备描述表结构中的一部分。
第二和第三个参数定义了显示区域内字符串的开始位置,x是水平位置,y是垂直位置,字符串第一个字符位于坐标点(x,y),在设备描述表属性中,原点(x,y)均为为0,是显示区域的左上角,对于坐标来说,坐标的映射方式的不同决定了单位的不同,在通常情况下传递给函数的坐标被称为逻辑坐标,Windows有许多坐标映射方式,它们是用来控制GDI函数指定的逻辑坐标转换为显示器的实际像素坐标的方式。映射方式在设备描述表的属性中定义,默认的映射方式是MM_TEXT,我们可以在WinGdi.h头文件中找到。在MM_TEXT映射模式下,逻辑单位于实际单位都相同,都是像素,对于坐标来说,x的值从左向右递增,y的值则从上向下递增(见下图),MM_TEXT坐标系与Windows在PAINTSTURCT结构中定义的无效矩形所使用的坐标系相同。
第四个参数是指向要输出字符串的长指针。
第五个参数是要输出的字符串的实际长度。
在Windows下输出文字并不如我们所想象的那么容易,在前面我们已经知道输出文字和坐标有关,我们为了精确的输出文字,就必须对系统的字体和字符大小有进一步的认识。
系统字体
对于输出字符串的函数TextOut来说,在默认情况下设备描述表属性中使用的是系统字体(SYSTEM_FONT),系统字体是Windows用来在标题栏,功能表和对话框中显示字符串所使用的默认字体。
但值得注意的是,字体如果按宽度来区分的话,大致可以分为两类:
1. 等宽字体
2. 变宽字体
等宽字体意味着所有的字符宽度都是一致的,但随着计算技术的不断发展和推广,这种等宽字体就不再能够满足需要,于是变宽字体出现了,变宽字体不同的字符宽度都不一定相同。
系统字体是一种点阵字体,字体被定义成了一个个的像素点,字体的确切大小取决于显示器的大小(分辨率的大小)。
字符大小
如果要使用TextOut函数显示多行文字,那么就必须确定字体字符的大小,字体的高度确定了下一行字符的显示位置,字体的宽度确定了下一列的显示位置。
屏幕的分辨率和字符大小是确定如何显示字符的主要依据,为了获得当前系统上各种与视觉属性相关的信息,我们可以调用GetSystemMetrics函数获取,调用GetTextMetrics函数可以获取字体大小。
以下是这两个函数的原形以及参数的详细定义:
int GetSystemMetrics(
int PerlINK '''">nIndex // 索引
);
GetSystemMetrics函数是完成Windows图形输出的重要函数,它返回Windows中各种与视觉属性相关的信息,该函数需要只需要一个参数,它是一个索引,这些索引是在Windows头文件中定义的一些常量,这些常量分别指定了不同的与视觉相关的设备属性,这些索引的多少取决与Windows的版本。
BOOL GetTextMetrics(
HDC PerlINK '''">hdc, // 当前的设备描述表句柄
LPTEXTMETRIC lptm // 指向TEXTMETRICS结构对象的指针
);
GetTextMetrics函数利用当前选择字体的各种度量值来填充由lptm参数所指向的缓冲区,函数如果运行成功则返回TURE,失败则返回FALSE。
TEXTMETRIC结构定义在WinGdi.h头文件中。
结构如下:
typedef struct tagTEXTMETRICA
{
LONG tmHeight;
LONG tmAscent;
LONG tmDescent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedASPectX;
LONG tmDigitizedAspectY;
BYTE tmFirstChar;
BYTE tmLastChar;
BYTE tmDefaultChar;
BYTE tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRICA, *PTEXTMETRICA, NEAR *NPTEXTMETRICA, FAR *LPTEXTMETRICA;
typedef struct tagTEXTMETRICW
{
LONG tmHeight;
LONG tmAscent;
LONG tmDescent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
WCHAR tmFirstChar;
WCHAR tmLastChar;
WCHAR tmDefaultChar;
WCHAR tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRICW, *PTEXTMETRICW, NEAR *NPTEXTMETRICW, FAR *LPTEXTMETRICW;
该结构拥有大约20个属性,这些属性的值的单位取决于设备描述表的映射方式,默认情况下是MM_TEXT,对于TextOut输出来说我们只需要用到前7个,他们的单位是像素。
LONG tmHeight; // 字符基准线上下最大纵向高度,是tmAscent与tmDescent之和。
LONG tmAscent; // 字符基准线以上所占的高度。
LONG tmDescent; // 字符基准线以下所占的高度。
LONG tmInternalLeading; // 内部间距,也是重音符号出现的地方。
LONG tmExternalLeading; // 行距。
LONG tmAveCharWidth; // 小写字母的加权平均宽度,对于大写字母来说可以用小写字母的加权平均宽度乘以150%计算出来。
LONG tmMaxCharWidth; // 字符中字宽字符的宽度。
字符的纵向大小是由TEXTMETRIC结构的前五个属性决定的。
具体情况见下图:
字体的大小是取决于当前屏幕的分辨率或是所选字体本身的默认大小的,在编写应用程序的时候不要把字体的大小以猜想的方式固定了,因为字体的大小是可变化的,利用GetTextMetrics函数动态的获取它们才是正确的。
|