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