?? 05.1.1 創(chuàng)建文本插入符.txt
字號:
5.1.1 創(chuàng)建文本插入符
在程序中想要創(chuàng)建插入符,可以利用 CWnd類的 CreateSolidCaretO函數來完成,該函數的原型聲明如下:
void CreateSolidCaret( int nWidth, int nHeight );
該函數各個參數的含義如下所述:
. nWidth
指定插入符的寬度(邏輯單位)。如果該參數的值為 0,那么系統(tǒng)將其設置為系統(tǒng)定義的窗口邊界的寬度。
. nHeight
指定插入符的高度(邏輯單位〉。如果該參數的值為 0,那么系統(tǒng)將其設置為系統(tǒng)定義的窗口邊界的高度。下面我們利用這個函數在程序窗口中創(chuàng)建一個插入符,首先請讀者按照第 3章介紹的步驟創(chuàng)建一個單文檔類型的 MFCAppWizard (exe)工程,取名為 Text。
插入符需要在窗口上創(chuàng)建,單文檔類型的工程有兩個窗口,即框架類窗口和視類窗口,我們應該選擇哪一個窗口來創(chuàng)建插入符呢?第4章曾介紹過,視類窗口始終位于框架類窗口之上,對窗口客戶區(qū)的鼠標和鍵盤操作實際上都是在視類窗口上進行的,因此應該在視類窗口上創(chuàng)建插入符。
插入符的創(chuàng)建應該在窗口創(chuàng)建之后進行,可以在 WM_CREATE消息的響應函數 OnCreate中 (在創(chuàng)建窗口的代碼之后)添加創(chuàng)建插入符的代碼。MFC AppWizard所生成的 CTextView類中沒有OnCreate函數,我們需要手動添加。為CTextView類添加WM CREATE 消息的響應函數OnCreate.然后在此函數中創(chuàng)建一個寬度為20、高度為 100的插入符,代碼如例5-1所示。
int CTextView: :OnCreate(LPCREATESTRUCT lpCreateStruct)
i f (CView: :OnCreate(lpCreateStruct) -1) return -1;
// TODO: Add your special工zed creation code here
CreateSolidCaret(20 , 100) ;
return 0 ;
Build并運行Text程序,發(fā)現程序窗口中并沒有出現剛才我們創(chuàng)建的插入符。這是為什么呢?實際上. CreateSolidCaret函數創(chuàng)建插入符以后,該插入符初始時是隱藏的,必須調用ShowCaret函數來顯示它。因此,在上述例子1所示代碼中調用CreateSolidCaret函數之后,應再添加下面這句代碼:
ShowCaret() ;
Build并運行Text程序,創(chuàng)建的插入符終于顯示在程序窗口中了,程序運行結果如圖
5.1所示。
圖 5.1插入符顯示結果
顯然,這個插入符看起來不太正常,太高也太寬了。我們使用Word時,都有這樣的經驗,插入符的大小會根據當前所選的字號來變化,如果選擇了比較大的字號,例如三號,那么插入符也會相應的增大。對Text程序來說,如何才能夠讓插入符適合于當前字體的大小呢?首先我們需要得到設備描述表中當前字體的信息,也就是文本的信息,然后根據宇
體的信息來調整插入符的大小。調用CDC類的GetTextMetrics成員函數可以得到設備描述表中當前字體的度量信息。該函數的原型聲明如下所示:
BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;
可以看到,該函數的參數要求是一個TEXTMETRIC結構體的指針,也就是說,我們可以定義一個TEXTMETRIC結構體類型的變量,然后將該變量的地址傳遞給這個參數。通過GetTextMe國cs這個函數調用,它會用設備描述表中當前字體的信息來填充這個結構體。
TEXTMETRIC結構體的定義如下:
typedef struct tagTEXTMETRIC 1* tm *1
int t mHeight;
int tmAscent;
, int tmDescent;
int tmInternalLeading; ì
int tmExternalLeading;
int tmAveCharWidth;
int tmMaxCharWidth;
int tmWeight;
BYTE tmltalic ;
BYTE tmUnderlined;
BYTE tmStruCkOut ;
BYTE tmFirstChar;
BYTE tmLastChar;
BYTE tmDefaultChar ;
BYTE t mBreakChar;
BYTE tmPitchAndFamilY;
BYTE tmCharSet ;
int tmOverhang;
int tmDigitizedAspectX;
int tmDigitizedAspectY;
TEXTMETRIC;
可以發(fā)現TEXTMETRIC這個結構體的信息比較多,但實際上常用的只有幾個。為了更好地理解TEXTMETRIC結構體中 tmAscent和 tmDescent成員的含義,先來看看圖5.2所示的字體信息示意圖。
tmAscent tmDescent
…........... ...1……μ … base line
圖 5.2字體信息示意圖
從圖 5.2中可以看到,對英文字符來說, g和 h的高度明顯是不一樣的。每一種字體
都有一條基線 ( base line ),基線以上到圖中 h字符最高點之間的高度稱為升序高度 ( trnAscent),基線以下到圖中 g字符最底點之間的高度稱為降序高度 (tmDescent)。升序高度加上降序高度就是字體的高度 (tmHeight)。這樣,當我們在文本程序窗口中輸入文字時,下一行的文字才不會覆蓋上-行的文字部分。
和字符的高度一樣,英文字符的寬度也是不同的。讀者可以在任意文本處理程序中輸入一個w和i字符,將會很明顯地看到這兩個字符的寬度是不一樣的,顯然w要比i寬。因此,字體并沒有一個具體的寬度值,只有一個平均寬度 ( tmAveCharWidth)。另外, TEXTMETRIC結構體中還定義了宇體的最大字符寬度 (trnMaxCharWidth)。
得到了字體的信息,我們就可以利用字體的高度和平均寬度來計算插入符的高度和寬度。例5-2是具體的實現代碼:
int CTextView : :OnCreate(LPCREATESTRUCT lpCreateStruct) {
、
if (CView : :OnCreate(lpCreateStruct) -1)
return -1;
//創(chuàng)建設備描述表
CClientDC dc(this) ;
//定義文本信息結構體變量
TEXTMETRIC tm;
//獲得設備描述表中的文本信息
dc . GetTextMetrics(&tm) ;
//根據字體大小,創(chuàng)建合適的插入符
CreateSolidCaret(tm.tmAveCharWidth/8, tm . tmH eight) ;
//顯示插入符
ShowCaret() ;
return 0 ;
讀者可能要提出這樣的疑問,為什么上述例5-2所示代碼在創(chuàng)建插入符時,要將字體平均寬度除以8呢?這是-個經驗值,讀者可以試試其他數值,看看結果是否符合自己的需要。
Build并運行Text程序,這時在應用程序窗口的左上角就出現了一條閃爍的豎線,而且其大小也比較符合常規(guī)。程序運行結果如圖5.3所示。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -