因爲TextOut是不能使用/n進行多行輸出的,它的每一個行的位置都是由座標決定的,所以要實現多行輸出就要自己算每行的位置,所以就要知道每行的高度(在不考慮會超出右邊界的情況下)。
程序取得行高的方法是從hdc句柄中得到每個字的高度。使用函數如下:
tm是一個TEXTMETRIC結構,需要自己定義。調用這個函數需要hdc句柄而計算行高之類的操作一般在程序創建的時候進行,所以用GetDC取得句柄。
TEXTMETRIC之中包含來很多信息,不過不用擔心記不住,在VC++中,當輸入完tm.之後,後面的所有屬性都會顯示出來,只要記得前面幾個字母就可以立即輸入完畢了。這個也是VC++看起來很難,要記的東西很多的原因吧:)有用的有這麼幾個:
{
LONG tmHeight ; //文字高度
LONG tmAscent ; //文字上部高度
LONG tmDescent ; //文字下部高度
LONG tmInternalLeading ; //重音符號出現的地方
LONG tmExternalLeading ; //行間距
LONG tmAveCharWidth ; //文字平均寬度
LONG tmMaxCharWidth ;
其它結構字段
}
TEXTMETRIC, * PTEXTMETRIC ;
只要對照這張圖看看就知道了,上面標註了一個字母各個部分的高度是怎麼劃分的:
另外,大寫字母寬度一般是tmAveCharWidth的1.5倍。所以文字寬度一般就是tmAveCharWidth,高度就是tmHeight+tmExternalLeading
所以,一般的初始化代碼就是這樣的(來自MSDN[Platform SDK>MSDN Library>用戶界面的設計和開發>Windows Controls>Individual Control Information>Scroll Bars>Using Scroll Bars]的示例)
// Get the handle to the client area's device context.
hdc = GetDC (hwnd);
// Extract font dimensions from the text metrics.
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
// Free the device context.
ReleaseDC (hwnd, hdc);
// Set an arbitrary maximum width for client area.
// (xClientMax is the sum of the widths of 48 average
// lowercase letters and 12 uppercase letters.)
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
MSDN地址:ms-help://MS.MSDNQTR.2003FEB.2052/shellcc/platform/commctls/scrollbars/usingscrollbars.htm
然後,每一行就是這樣子的:
x,y是指第x各字符和第y行。使用wsprintf函數的好處是,它的返回值就是字符串的長度,而且在裏面用了TEXT就可以使用%i之類的東東進行格式化了。說白了wsprintf就是在預格式化到了szBuffer這個緩衝區。不過記得先定義szBuffer就是了(TCHAR szBuffer [40] ;)
-----------------------------------------------------------
好了,終於可以動手了,這回要弄點東西進行輸出了:
顯示可以從GetSystemMetrics呼叫中取得的信息!這個函數時這麼用的:
GetSystemMetrics (「索引」),所謂的索引呢,就是一個整數,告訴這個函數我們要知道什麼。因爲這個函數索引衆多(廢話,不多怎麼練習我們的多行輸出),所以定義了一個.h的文件,直接調用這個結構就可以了。具體程序就不列出來了,書上有,建議除了SYSMETS.H外,其他部分自己寫(注意書上的有點小錯誤哦)
下面是這個示例的工程打包(其實就是昨天那個,把那個MessageBox函數去掉就行了):
http://dl2.csdn.net/down4/20070706/06104222215.rar
到這裏你會發現有些東西沒有顯示出來。這就要用到滾動條了。。。。。。