《循序漸進學用Visual C++ 6.0》讀書筆記(七)
l 題設:畫一個對話方塊MyDlg , 一個List Box(IDC_LB) ,
一個靜態文本(IDC_STEXT),同時為list box建立空件型成員變數
m_ctlListBox和字串型成員變數m_strListBox.
今日我們要學習字型控制,但是我們必須瞭解一些必備知識。
l LogFont結構
這個結構的成員變數多得要死,瞭解就okey了,有需要的時候查msdn.
typedef struct tagLOGFONT {
LONG lfHeight; //高度
LONG lfWidth; //寬度
LONG lfEscapement; //列印角度,900垂直列印,0水平列印。
LONG lfOrientation; //字型列印角度,1800上下倒置,900左右倒置。
LONG lfWeight; //字型粗細,預設是0,還常用400,700
BYTE lfItalic; //斜體字,預設0非斜體,1斜體。
BYTE lfUnderline; //底線,預設0無。
BYTE lfStrikeOut; //字型被直線穿過,預設0無。
BYTE lfCharSet; //字元集,如宋體字。一般設定為DEFAUL_CHARSET.
BYTE lfOutPrecision; //符合度,看不明白?一般設定為OUT_DEFAUL_
PRECIS。
BYTE lfClipPrecision; //不懂,一般設定為CLIP_DEAFAUL_PRECIS
BYTE lfQuality; //字型圖形品質,不管,設為DEFAUL_QUALITY
BYTE lfPitchAndFamily; //字間距,不管,設為DEFAUL_PITCH+FF_DON
TCARE
TCHAR lfFaceName[LF_FACESIZE]; //所有字型式樣數組,
供字型回呼函數調用。
} LOGFONT;
例如:
LogFont lf ; //聲明一個LogFont結構變數
lf.lfCharSet=DEFUAL_CHARSET; //設定為宋體字
lf.lfPitchAndFamily=0 ; //這裡0是DEFAUL_QUALITY
lf.lfFaceName[]=NULL; //動態數組的字元式樣集合,初始化清空
//////////////////////////////////////////////////////////////////////////////////////////////////
l EnumFontFamFamiliesEX()請求可用字型列表函數。
看到以EX結尾,我們就知道這是一個API函數,看函數原形:
E…..EX(“裝置情境” ,LogFont結構指標 ,字型回呼函數地址,
LPARAM, 0 )
//畫布上次講過了,畫布就是其中一個裝置情境,
建立畫布如:CClientDC dc(this)
//回呼函數上次也講過了,但呆會再討論。
//LPARAM是給回呼函數使用的,上次也講過了。
//最後一個永遠是0 ,據說是給以後擴充的時候使用的。
例如:
CClientDC dc(thist);
LogFont lf;
….. // lf的初始化如上例。
::EnumFontFamFamiliesEX( (HDC) dc , // 強制轉化成HDC類型
&lf , (FONTENUMPROC) EnumFontFamProc //強制轉化成字型回呼函數
(LPARAM)this , 0 ) //強轉當前表單指標為LPARAM接收回呼函數使用方式。
////////////////////////////////////////////////////////////////////////////////////////////////////
l 如何建立字型回呼函數?
看一個經典的字型回呼函數例子:
int CALLBACK EnumFontFamProc( LPENUMLOGFONT lpelf ,
LPNEWTEXTMETRIC lpntm , DWORD nFontType ,
Long lParam )
{
MyDlg * pWnd = (MyDlg *) lParam ;
pWnd ->m_ctlListBox.AddString (lpelf->elfLogFont.lfFaceName)
return ture ;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
這個回呼函數是我們建立的,頭3個參數看似很深懊,其實是LogFont結構
的分解版,第一個參數是ENUMLOGFONT的結構指標,這種結構用來設定
字型的粗斜底線,第二個參數是NEWTEXTMETRIC的結構指標,這種結
構卻用來設定字型的高寬大小,第三個參數則用來設定字型顯示風格,如
TureType, 而最後一個參數是回呼函數必需有的,它似呼有某些隱藏操作,
不用我們管。
第一個語句是為對話方塊MyDlg設定指標,它等於lParam.
第二個語句是MyDlg下的List Box空件添加項目,項目名稱等於那個結構的
式樣名字。
第三個語句回呼函數必須的。
l CFont類
CFont類可以看作LogFont結構的擴充,他們的成員變數完全一樣,不過類
是有成員函數的,如:CreatFont方法與SetFont方法
看例:
CFont m_fFont ; //建立一字型執行個體;
m_fFont.CreatFont (12, 0,0,…..LogFont的參數一模一樣,詳見上面….);
l 在MyDlg.h標頭檔,加入回呼函數聲明。
int CALLBACK EnumFontProc( LPENUMLOGFONT lpnlf ,
LPNEWTEXTMETRIC lpntm ,DWORD nFontType , long LPARAM);
l 在MyDlg.cpp檔案,寫下自己的字型回呼函數。
這裡可以照抄上例。
l 為MyDlg類建立成員函數FillFont();
由於這個函數並不為什麼訊息而建立的,是我們自己建立用
來整合一系列操作的函數。
在View面版,點MyDlg類,右點添加,輸入名字等建立它。
代碼清單:
void MyDlg::FillFont();
{
LogFont lf;
lf.SetChar=DEFUALT_CHARSET;
strcpy( lf.lfFaceName , “”);
m_ctlListBox.ResetContext() ;
CClientDC dc(this);
::EnumFontFamilesEX((HDC) dc ,&lf ,
(FontEnumProc) EnumFontProc,(LPARAM) this,0);
}
//strcpy(目標,源)是字串複製函數。
這裡初始化。要注意就是lf.lfFaceName是字串數組。
//List Box 有個方法ResetContext()是清空下拉式清單。
//下面幾句上面講過,請求字型列表。
l 把FillFont()加入MyDlg的裝載函數裡。
Void MyDlg::InitDialog()
{
…..
FillFont();
….
}
l Edit Box的EN_CHANGE訊息與List Box的LBN_SELCHANGE訊息。
當Edit Box內容被使用者改變就會激發EN_CHANGE訊息.
當List Box被使用者下拉選擇項目時會激發LBN_SELCHANG訊息。
這兩個訊息都容易被理解,書上正是為此兩種訊息做字型選擇的
例子。這裡不再詳述了