vc++字體類CFont詳解及用法實例《轉》


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=134;
  lf.lfHeight=-150;
  lf.lfHeight=-150;
  lf.lfWidth=0;
  strcpy(lf.lfFaceName, "隸書");
  font.CreateFontIndirect( &lf);
  pOldFont=dc.SelectObject( &font);
  dc.SetBkMode(TRANSPARENT); // 更改當前畫筆
  CPen pen(PS_SOLID, 1, RGB(255, 0, 0));
  CPen *pOldPen;
  pOldPen=dc.SelectObject( &pen); // 開始一個路徑
  dc.BeginPath();
  dc.TextOut(10, 10, "空心字");
  dc.EndPath(); // 繪制路徑
  dc.StrokePath();
  //可以用dc.StrokeAndFillPath()函數來代替,不過該函數會使用當前刷子填充路徑的內部。
  dc.SelectObject(pOldFont);
  dc.SelectObject(pOldPen);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM