Windows
系統中經常使用
GDI
進行文本輸出,從某種意義上來說,圖形和文本并沒有本質上的界限,很多時候
windows
把文本也當作圖形對待。在
windows
編程中,文本操作首先要獲得文本句柄,此外,還要設置字體,字符大小,字符顏色等有關屬性,并將它們選入設備環境。
???????????
設置文本的設備環境
1.????????
自定義字體
可以使用函數
CreateFont
自定義字體
HFONT hFont = HFONT CreateFont(
? int nHeight,? int nWidth,???????????????? //
字體高,寬
? int nEscapement,?????????? //
文字相對于頁底的角度
? int nOrientation,??????? //
每個文字相對于頁底的角度
? int fnWeight,???????? //
字體粗細,范圍
0~1000
,
400
為正常字體,
700
為黑體
? DWORD fdwItalic,?????????? //
取非零值則為斜體
? DWORD fdwUnderline,??????? //
取非零值則下劃線
? DWORD fdwStrikeOut,??????? //
取非零值則中劃線
? DWORD fdwCharSet,????????? //
字體所屬字符集
? DWORD fdwOutputPrecision,? //
輸出精度(一般取默認值)
? DWORD fdwClipPrecision,??? //
剪裁精度(一般取默認值)
? DWORD fdwQuality,????????? //
輸出質量(一般取默認值)
? DWORD fdwPitchAndFamily,?? //
字體間距及字體系列(一般取默認值)
? LPCTSTR lpszFace?????????? //
字體名
);
這個這個......以后這樣建字體還不累死才怪咧!而且貌似
API
里帶這么多惡心參數的方法還不少,了解一下就行了。一般情況下使用系統默認提供的字體就可以了。
2.????????
字體句柄
windows
系統提供了七種基本字體:
ANSI_FIXED_FONT
,
DEFAULT_GUI_FONT
,
ANSI_VAR_FONT
DEVICE_DEFAULT_FONT
,
SYSTEM_FIXED_FONT
,
SYSTEM_FONT
(系統默認字體)
調用函數
GetStockObject
()即可獲得系統默認字體
獲得字體之后,有時候還需要設置字體顏色和背景色,可以使用下面兩個函數:
SetTextColor????????? //
設置字體顏色
SetBkColor??????????? //
設置背景顏色
?
???????????
文本輸出過程
設置了字體句柄,字體及字體顏色之后就可以把設置字體輸入到相應的設備上。
Windows
系統在文本輸出上有點小小的偷懶,把很多事情都丟給了程序員來做,應用程序必須自己管理換行,后續字符的位置等輸出格式。雖提供了編程的自由,但是程序員的工作量也變的非常大。
文本輸出過程包括獲取字體信息,格式化文本,調用函數輸出文本等過程。
1.????????
獲取字體信息
應用程序在輸出字體之前必須先獲取當前字體的有關信息,在
windows
程序中通過調用
GetTextMetrics
函數來獲取當前字體的信息。其形式為:
GetTextMetrics(hdc, &tm);????????? //tm
為
TEXTMETRIC
結構
TEXTMETRIC
結構也非常復雜,其結構定義如下:
typedef struct tagTEXTMETRIC {
? LONG tmHeight;
? LONG tmAscent;
? LONG tmDescent;
? LONG tmInternalLeading;
? LONG tmExternalLeading;
? LONG tmAveCharWidth;
? LONG tmMaxCharWidth;
? LONG tmWeight;
? LONG tmOverhang;
? LONG tmDigitizedAspectX;
? LONG tmDigitizedAspectY;
? TCHAR tmFirstChar;
? TCHAR tmLastChar;
? TCHAR tmDefaultChar;
? TCHAR tmBreakChar;
? BYTE tmItalic;
? BYTE tmUnderlined;
? BYTE tmStruckOut;
? BYTE tmPitchAndFamily;
? BYTE tmCharSet;
} TEXTMETRIC, *PTEXTMETRIC;
具體各屬性不解釋,需要時可以查詢
MSDN
。
2.????????
格式化文本
格式化處理一般針對兩種情況,一是文本行中確定后續文本的坐標,二是在換行時確定下一行的坐標。
(1)?????
確定后續文本坐標
應先獲取當前字符的寬度,通過計算字符串起始坐標與字符串寬度之和即可得到后續文本的起始坐標。
這里要使用到函數:
BOOL GetTextExtentPoint32
(
?????? HDC hdc,
?????? LPCTSTR lpsxString,??? //
指定的字符串
?????? int nLength,????????????????? //
字符串中字符數
?????? LPSIZE lpSize??????? //
字符串寬度及高度的
SIZE
數據結構
)
(2)?????
確定換行時文本坐標
通過計算當前文本行字符的高度與行間隔之和,即可得到換行時文本的起始坐標,而上述兩個數值均可通過獲取當前字體信息得到。
3.????????
文本輸出
最常用的文本輸出函數就是
TextOut
,其原型如下:
BOOL TextOut
(
?????? HDC hdc,
?????? int x, int y,
?????? LPCTSTR lpString,
?????? int nCount
??????
)
???????????
文本操作實例
因為代碼太長,全部貼出來頁面不好看。故只給出WndProc函數的實現,程序其它部分可以參考以前的筆記。
LRESULT?CALLBACK?WndProc(HWND?hWnd,?UINT?iMsg,?
?????????????????????????UINT?wParam,?
?????????????????????????LONG?lParam)
{
????HDC?hdc;
????HFONT?hFont;????//字體句柄
????PAINTSTRUCT?ps;
????TEXTMETRIC?tm;
????char?lpszTx1[]?=?"紅色的SYSTEM字體:好好學習,天天向上!";
????char?lpszTx2[]?=?"綠色自定義字體:保護眼睛,注意休息!";
????char?lpszTx3[]?=?"藍色大號斜體并帶有下劃線!";
????char?lpszTx4[]?=?"兩行文本輸出到同一行里!";
????char?lpszTx5[]?=?"今天的學習就到這里,祝你成功!";
????int?x?=?0,?y?=?0;
????SIZE?size;
????switch(iMsg)
????{
????case?WM_PAINT:
????????????hdc?=?BeginPaint(hWnd,?&ps);
????????????SetTextColor(hdc,?RGB(255,?0,?0));//文本為紅色
????????????TextOut(hdc,?x,?y,?lpszTx1,?strlen(lpszTx1));//字體輸出
????????????GetTextMetrics(hdc,?&tm);????//獲取系統當前字體
????????????y?=?y?+?tm.tmHeight?+?tm.tmExternalLeading;//計算下一行坐標
????????????hFont?=?CreateFont
????????????????????????(
????????????????????????????20,0,????//高度20,?寬取0表示由系統選擇最佳值
????????????????????????????0,?0,????//文本傾斜,與字體傾斜都為0
????????????????????????????FW_HEAVY,????//粗體
????????????????????????????0,0,0,????????//非斜體,無下劃線,無中劃線
????????????????????????????GB2312_CHARSET,????//字符集
????????????????????????????OUT_DEFAULT_PRECIS,????????
????????????????????????????CLIP_DEFAULT_PRECIS,????????
????????????????????????????DEFAULT_QUALITY,????????//一系列的默認值
????????????????????????????DEFAULT_PITCH?|?FF_DONTCARE,????
????????????????????????????"自定義字體"????//字體名稱
????????????????????????);
????????????SetTextColor(hdc,?RGB(0,?255,?0));
????????????SelectObject(hdc,?hFont);
????????????TextOut(hdc,?x,?y,?lpszTx2,?strlen(lpszTx2));
????????????GetTextMetrics(hdc,?&tm);????//將當前字體信息選入tm結構中
????????????y?=?y?+?tm.tmHeight?+?15?*?tm.tmExternalLeading;//5倍行間距
????????????hFont?=?CreateFont
????????????????????????(
????????????????????????????40,0,????//高度40,?寬取0表示由系統選擇最佳值
????????????????????????????0,?0,????//文本傾斜,與字體傾斜都為0
????????????????????????????FW_NORMAL,????
????????????????????????????1,1,0,????????//斜體,下劃線,無中劃線
????????????????????????????GB2312_CHARSET,????//字符集
????????????????????????????OUT_DEFAULT_PRECIS,????
????????????????????????????CLIP_DEFAULT_PRECIS,????
????????????????????????????DEFAULT_QUALITY,????????//一系列的默認值
????????????????????????????DEFAULT_PITCH?|?FF_DONTCARE,????
????????????????????????????"大號字體"????//字體名稱
????????????????????????);
????????????SetTextColor(hdc,?RGB(0,?0,?255));
????????????SetBkColor(hdc,?RGB(160,?160,?160));//設置背景顏色
????????????SelectObject(hdc,?hFont);
????????????TextOut(hdc,?x,?y,?lpszTx3,?strlen(lpszTx3));
????????????//獲取系統提供的字體
????????????hFont?=?(HFONT)GetStockObject(SYSTEM_FIXED_FONT);
????????????y?=?y?+?tm.tmHeight?+?25?*?tm.tmExternalLeading;
????????????SetTextColor(hdc,?RGB(0,?0,?0));
????????????SetBkColor(hdc,?RGB(255,?255,?255));
????????????SelectObject(hdc,?hFont);
????????????TextOut(hdc,?x,?y,?lpszTx4,?strlen(lpszTx4));
????????????GetTextExtentPoint32(hdc,?lpszTx4,?strlen(lpszTx4),?&size);//計算高寬
????????????x?=?x?+?size.cx;
????????????TextOut(hdc,?x?,?y?,lpszTx5,?strlen(lpszTx5));
????????????EndPaint(hWnd,?&ps);
????????????DeleteObject(hFont);
????????????break;
????case?WM_DESTROY:
????????PostQuitMessage(0);
????????break;
????default:
????????return?DefWindowProc(hWnd,?iMsg,?wParam,?lParam);
????}
????return?0;
}