用VC實現豎寫漢字的方法
中國人自古就有自右至左、從上到下書寫漢字的習慣。而當我們在自己所編寫的應用程序中使用輸出函數輸出的總是自左至右的橫排文字。有沒有可能在我們的應用程序中實現豎寫漢字的效果呢?筆者偶然發現了一種利用VC實現豎寫漢字效果的方法,現在就把它介紹給大家。
Windows系統內置了許多名稱以“@”開頭的字集,這些字集有一個共同的特點,即其所包含的文字全都是平躺著的(字頭朝左,字底朝右)。如果我們能將這些字逆時針旋轉270度后再顯示出來,就可以達到實現豎寫漢字效果的目的了。
要使文字發生旋轉,我們只需創建一個邏輯字體并設定該邏輯字體的顯示角度,再設定其字體名稱為一個以“@”開頭的字集的名稱即可。我們可以采用兩種方式創建邏輯字體。
其一,用CFont類的成員函數CreateFont直接創建邏輯字體。CreateFont的參數定義如下:
BOOL CreateFont(
int nHeight, //字體的高度
int nWidth, //字體的寬度
int nEscapement, //字體顯示的角度
int nOrientation, //字體的角度
int nWeight, //字體的磅數
BYTE bItalic, //斜體字體
BYTE bUnderline, //帶下劃線的字體
BYTE cStrikeOut, //帶刪除線的字體
BYTE nCharSet, //所需的字符集
BYTE nOutPrecision, //輸出的精度
BYTE nClipPrecision, //裁減的精度
BYTE nQuality, //邏輯字體與輸出設備的實際
//字體之間的精度
BYTE nPitchAndFamily, //字體間距和字體集
LPCTSTR lpszFacename //字體名稱
);
其中nEscapement單位為0.1角度,方向為逆時針,所以為了使平躺的字立起來應設定其值為2700,lpszFacename則賦以“@”開頭的字集的名稱,如“@system”。
其二,利用LOGFONT結構,將該結構作為參數調用CFont類的成員函數CreateFontIndirect創建邏輯字體。LOGFONT結構通常被用來描述一種邏輯字體,結構內的各變量分別代表邏輯字體的各個屬性,這些變量與函數CreateFont的參數相同。其結構如下:
typedef struct tagLOGFONT { // lf
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;
下面我們就以一個示例來說明豎寫漢字的實現方法:
1.建立一個MFC AppWizard(exe)應用工程CHNfont。在MFC AppWizard向導的第一步中選擇Single Document,再點擊按鍵Finish->OK完成工程的建立。
2.在CMainFrame::OnCreate函數中添加如下代碼,使窗體最大化。AfxGetMainWnd()->ShowWindow(SW_SHOWMAXIMIZED);
3.添加如下代碼實現豎寫功能。
void CChildView::OnPaint()
{
CPaintDC dc(this);// device context for painting
/////// 利用CFont::CreateFont(...)函數實現豎寫漢字////////
CFont myFont; //創建字體對象
//創建邏輯字體
myFont.CreateFont(
56, //字體高度(旋轉后的字體寬度)=56
20, //字體寬度(旋轉后的字體高度)=20
2700, //字體顯示角度=270°
0, //nOrientation=0
10, //字體磅數=10
FALSE, //非斜體
FALSE, //無下劃線
FALSE, //無刪除線
DEFAULT_CHARSET, //使用缺省字符集
OUT_DEFAULT_PRECIS, //缺省輸出精度
CLIP_DEFAULT_PRECIS,//缺省裁減精度
DEFAULT_QUALITY, //nQuality=缺省值
DEFAULT_PITCH, //nPitchAndFamily=缺省值
"@system"); //字體名=@system
CFont *pOldFont=dc.SelectObject(&myFont);//選入設備描述表
CRect rtClient;
GetClientRect(rtClient); //獲取客戶區尺寸、位置信息
//在客戶區適當位置輸出文字
dc.TextOut(rtClient.Width()/2+30,rtClient.Height()/8,
"無邊落木蕭蕭下");
dc.SelectObject(pOldFont); //將myFont從設備環境中分離
myFont.DeleteObject(); //刪除myFont對象
/////////// 利用LOGFONT結構實現豎寫漢字//////////////
LOGFONT lf; //定義字體結構
lf.lfWeight=10; //字體磅數=10
lf.lfHeight=56; //字體高度(旋轉后的字體寬度)=56
lf.lfWidth=20; //字體寬度(旋轉后的字體高度)=20
lf.lfUnderline=FALSE; //無下劃線
lf.lfStrikeOut=FALSE; //無刪除線
lf.lfItalic=FALSE; //非斜體
lf.lfEscapement=2700; //字體顯示角度=270°
lf.lfCharSet=DEFAULT_CHARSET; //使用缺省字符集
strcpy(lf.lfFaceName,"@system"); //字體名=@system
CFont myLogFont; //定義字體對象
myLogFont.CreateFontIndirect(&lf); //創建邏輯字體
pOldFont=dc.SelectObject(&myLogFont);//選入設備描述表
//在客戶區適當位置輸出文字
dc.TextOut(rtClient.Width()/2-30,rtClient.Height()/8,
"不盡長江滾滾來");
dc.SelectObject(pOldFont); //將myFont從設備環境中分離
myLogFont.DeleteObject(); //刪除myLogFont對象
}
4.編譯連接,運行。
以上實例在Windows98下,以VC++6.0編譯通過。