格式化文字
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函式以及如何根据字元大小来安排字距,剩下的就是显示一点有意义的东西了。
在前