CFont詳解:
Windows提供了多種與裝置無關的不同尺寸的字型。有效地使用這些Windows字型,不用在程式設計時下很大功夫,就可以明顯地增強各種應用程式的功能。字型是Windows GDI必要的組成部分,這意味字型的使用與其他GDI對象一樣。它們可以縮放和剪切,可以像選取畫筆或者畫刷一樣選取裝置環境。所有關于撤消選中和删除的GDI規則都适用于字型。
字型由CFont類進行管理,建立CFont類必須使用CFont類的成員函數,這點與CPen和CBrush有所不同。
1.CFont提供的建立字型的成員函數
利用CFont建立字型的方法有兩種,它們是:
(1)BOOL CreateFontIndirect(const LOGFONT* lpLogFont )
該對象通過LOGFONT結建構立字型,LOGFONT結構的定義如下:
typedef struct tagLOGFONT {
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
LOGFONT結構中各個成員的含義如下:
lfHeight:設定字型的高度。
lfWidth:設定字型的平均寬度。
LfEscapement:設定字元串底線與水準線的夾角,夾角是以0.1度為機關。
lfOrientation:設定每一個字元的底線與水準線的夾角,夾角是以0.1度為機關。
lfWeight:設定字型的粗細,其取值範圍為0~1000,通常400為正常粗細,700為粗,如果取值為0,則選擇預設粗細。
lfItalic:如果為TRUE,則字型為斜體。
lfUnderline:如果為TRUE,則字型帶下劃線。
lfStrikeOut:如果為TRUE,則字型帶删除線。
lfCharSet:指定字元集。
LfOutPrecision:指定輸出時字型的精度。
lfClipPrecision:指定輸出時字型被裁剪的精度。
lfQuality:指定輸出品質。
lfPitchAndFamily:設定字型的斜度和字型類型。
lfFaceName[LF_FACESIZE]:設定字型字樣。
(2)CreateFont()成員函數
CreateFont()成員函數的原型:
BOOL CreateFont(
int nHeight, //以邏輯機關方式指定字型的寬度
int nWidth, //以邏輯機關方式指定字型中字元的平均寬度
int nEscapement, //指定偏離垂線和X軸在顯示面上的夾角(機關:0.1度)
int nOrientation, //指定符串基線和X軸之間的夾角(機關:0.1度)
int nWeight, //指定字型鎊數
BYTE bItalic, //指定字型是否為斜體
BYTE bUnderline, //指定字型是否帶下劃線
BYTE cStrikeOut, //指定是否是字型字元突出
BYTE nCharSet, //指定字型的字元集
BYTE nOutPrecision, //指定所需的輸出精度
BYTE nClipPrecision, //指定所需的剪貼精度
BYTE nQuality, //訓示字型的輸出品質
BYTE nPitchAndFamily, //指定字型的間距和家族
LPCTSTR lpszFacename //指定字型字樣的名稱
)
參數說明:
nHeight:其取值範圍可以大于0、等于0或小于0。nHeight以邏輯機關方式指定字型的高度,字型的高度可任選下列值。
² 大于0:此時高度被轉化為裝置機關,與可用字型的網格高度做比較。
² 等于0:使用合理的預設大小。
² 小于0:此時高度被轉化為裝置機關,而絕對值與可用字型的字元高度做比較。
注意:nHeight絕對值在轉化後不可超過16384裝置機關。
nEscapement:指定偏離垂線與X軸在顯示面上的夾角。偏離垂線是從一行中開始到最後一個字元的線,此角從x軸逆時針方向度量。
nOrientation:指定字元基線和X軸之間的夾角。此度數在坐标軸中由X軸逆時針方向度量時坐标系中Y軸向下,順時針方向從X軸旋轉時,Y軸向上。
用法舉例:
(一)顯示傾斜的文字
上文中的圖一顯示了通過顯示一系列的傾斜字元串來實作環繞顯示的效果,下面來詳細說明如何實作這個效果。
實作上述的效果其實很容易,隻要使用CFONT類和LOGFONT結構來靈活的建立字型,設定字型的屬性,就可以實作傾斜文字的效果。LOGFONT結構中包含了所要建立的字型中的全部資訊,其中的ifEscapement 成員制定了所建立的字型與水準方向所傾斜的角度,需要讀者注意的是該成員變量角度的機關是十分之一度而不是度,例如,如果ifEscapement定義為 450,它表示字型的傾斜角度為45度。為了保證所有的字型按照一個方向旋轉,一定要設定ifEscapenent的CLIP_LH_ANGLES位,否則字型有可能向反方向旋轉。
如同使用其它GDI(圖形使用者界面接口)對象一樣,在使用你定義的字型以前,必須要将建立的字型選入DC中(裝置上下文)。
(二)實作3D文字
計算機螢幕是平面二維的,我們之是以能欣賞到真如實物般的三維圖像,是因為顯示在計算機螢幕上時色彩灰階的不同而使人眼産生視覺上的錯覺,而将二維的計算機螢幕感覺為三維圖像。基于色彩學的有關知識,三維物體邊緣的凸出部分一般顯高亮度色,而凹下去的部分由于受光線的遮擋而顯暗色。這一認識被廣泛應用于網頁或其他應用中對按鈕、3D線條的繪制。對于本文所要繪制的3D文字同樣也适用,即在原始位置顯示高亮度顔色,而在左下或右上等位置用低亮度顔色勾勒出其輪廓,這樣在視覺上便會産生3D文字的效果。具體實作時,可用完全一樣的字型在不同的位置分别繪制兩個不同顔色的2D文字,隻要使兩個文字的坐标合适,就完全可以在視覺上産生出不同效果的3D文字。
具體實作的思想是通過CDC::SetTextColor()分别設定文字的顔色為高亮(3DHILIGHT)和陰影(3DSHADOW)的狀态下顯示文字;同時注意在兩次顯示文字時要錯開幾個像素,這樣才能達到預期的效果。實作的效果上文的圖二所示。
(三)文字的漸變效果
為了實作文字的漸變效果,需要設定一個定時器(使用SetTimer()函數),在定時器響應函數處理過程中,通過調用CDC: SetTextColor()函數不斷改變裝置上下文中文本的顯示顔色,進而實作文字的漸變效果。文本的顔色是通過RGB(紅、綠、蘭)三種基本顔色的混合所形成的最終結果,RGB三基色的變化範圍都是(0,255),R=G=B時,顔色的效果是灰色的,所謂灰色,就是在純白和純黑之間的一種過渡色,當R =G=B=0時,顔色為黑色,當R=G=B=255時,顔色為純白色,可以定義一個修正變量,不斷的對該三基色進行遞增或遞減,進而實作文字的漸變顯示。這裡僅僅給出實作的思路,讀者自己可以很容易的實作代碼。
(四)其它
另外,還可以通過設定路徑對象來對普通的文字進行輪廓勾勒,使之具備特殊的效果。路徑是Win32中新增的一個GDI對象,下面先從概念上談起。
1)路徑的概念
在Windows 95/NT 這樣的Win32作業系統中,除了已有的位圖,畫筆,畫刷,字型,調色闆和區域之外,還增加了一個新的GDI對象:路徑。路徑是可以被填充,畫出輪廓或同時被畫出輪廓并填充的一個或多個圖形。路徑的引入,大大地豐富了Windows的圖形功能,使得應用程式可以友善地建立複雜區域,繪制和填充不規則圖形。這裡說的不規則圖形是指由直線和貝塞爾曲線組成的圖形(相對于矩形,多邊形,橢圓等規則圖形)。
2)路徑的使用
與其它原有的GDI對象不同的是,MFC類庫沒有專門用一個C++類來封裝路徑對象(或許在以後的版本中會得到支援)。有關路徑的定義和使用等各種操作都必須通過調用API函數(或CDC類中對應的成員函數)來實作。路徑的使用過程大緻如下:
(1)調用BeginPath()函數開始路徑定義;
(2)調用GDI繪圖函數來定義路徑;在Win32中,可以用于定義路徑的GDI繪圖函數包括:AngleArc()、 Arc()、 ArcToChord()、Ellipse ()、LineTo()、TextOut()等函數;
(3)調用EndPath()函數結束路徑定義;
完成路徑定義後,所定義的路徑即被同時選進裝置描述表,裝置描述表中原有的路徑對象在調用BeginPath()函數開始路徑定義時即被廢棄。
(4)使用路徑對象。
完成路徑定義工作之後,應用程式便可以利用有關GDI函數來使用路徑,這些函數包括繪制路徑輪廓StrokePath(),填充路徑FillPath (),繪制輪廓并填充StrokeAndFillPath(),把路徑轉換成區域PathToRegion(),把路徑直線化FlattenPath (),提取路徑資料GetPath(),加寬路徑WidenPath()和設定裁剪路徑SelectClipPath()等。這些函數的具體使用方法可參閱有關的SDK文檔。
下面的代碼示範了如何實作字型的空心效果
// 應用程式主視窗的重繪函數
void CMyWnd::OnPaint()
{
// 獲得視窗的客戶區裝置上下文句柄
CPaintDC dc(this); // 更改目前字型
LOGFONT lf;
dc.GetCurrentFont()- >GetLogFont(&lf);
CFont font;
CFont *pOldFont; // 儲存裝置上下文最初使用的字型對象
lf.lfCharSet=;
lf.lfHeight=-;
lf.lfHeight=-;
lf.lfWidth=;
strcpy(lf.lfFaceName, "隸書");
font.CreateFontIndirect( &lf);
pOldFont=dc.SelectObject( &font);
dc.SetBkMode(TRANSPARENT); // 更改目前畫筆
CPen pen(PS_SOLID, , RGB(, , ));
CPen *pOldPen;
pOldPen=dc.SelectObject( &pen); // 開始一個路徑
dc.BeginPath();
dc.TextOut(, , "空心字");
dc.EndPath(); // 繪制路徑
dc.StrokePath();
//可以用dc.StrokeAndFillPath()函數來代替,不過該函數會使用目前刷子填充路徑的内部。
dc.SelectObject(pOldFont);
dc.SelectObject(pOldPen);
}
轉載自:http://www.cnblogs.com/yizhizaiYI/articles/5192753.html