中國人自古就有自右至左、從上到下書寫漢字的習慣。而當我們在自己所編寫的應用程式中使用輸出函數輸出的總是自左至右的橫排文字。有沒有可能在我們的應用程式中實現豎寫漢字的效果呢?筆者偶然發現了一種利用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.編譯串連,運行。
或者
CString m_text;
CSize sz = pdc->GetTextExtent("效");
CRect rtCal; //要輸出字串的矩形地區。其寬度稍大於字元寬度。
rtCal.Width = sz.cx + 2;
int midhei=pDC->DrawText(m_text,&rtCal,flag | DT_CALCRECT |DT_WORDBREAK|DT_NOCLIP);
或者只是簡單的用:
for (i=0;i<m_text.GetLength();i++){
pDC->TextOut(10,y,m_Text.GetAt(i));
y+= sz.cy;
}
程式執行後,如下: