鄒雪峰,張 翔
劉琳琳
(遼河油田曙光技術處作業一大隊,遼寧 盤錦 124109)
VC插入漢字文本塊的編程方法
鄒雪峰,張 翔

劉琳琳
(遼河油田曙光技術處作業一大隊,遼寧 盤錦 124109)
一般的繪圖軟件如Surfer、Graph等只支持英文和數字的文本輸出,給圖形資料解釋說明帶來不方便。采用VC編程實現了對漢字文本塊輸出,并設計了相應的獨立文本類CText,對漢字雙字節作了校正處理,杜絕了斷字和亂碼的出現。同時,該類實現了位置、顏色、大小等屬性設置功能,在實際的矢量繪圖軟件中,應用效果良好。
文本框;文本塊;矢量繪圖;字符串繪制;鼠標交互
常用的矢量繪制圖形的軟件中,圖形的文字介紹和說明具有相當重要的意義,如繪圖曲線類型說明、繪圖標題以及坐標單位等描述在圖形繪制中是必須具備的[1]。因此,矢量繪圖軟件的開發過程中,大部分開發人員直接采用字符串輸出功能。但是,這些文本塊實現的功能只在通用的英文和數字等單字節字符文本有效,缺乏對中文這種雙字節字符的文本功能實現。為此,筆者針對實際工作中的需求,在單字節字符文本的基礎上,采用VC編程解決了雙字節字符文本繪制功能,設計了獨立文本類CText,實現了對文本功能的完善和開發[2-3]。
將文本塊當作軟件繪圖的對象,并在視圖中繪制出來,無論是各種圖形或者是很熟悉的文字,都是用畫筆畫出來的,在視圖中嵌入文本塊,要求在視圖中畫出一個有效矩形框(矩形框的寬度和高度要超過一定的大小),實現在有效矩形中畫出一個個的文字,據此可把所要執行的功能列出如下[4]:①在視圖中繪制一個有效的文本矩形框,同時就生成一個文本塊對象;②在當前的文本矩形框中繪制閃爍的光標,使文本塊處于等待文字輸入的狀態;③每次輸入一個字符,判斷該字符是單字節還是雙字節,同時把剛輸入一個字符輸出在視圖中,光標隨著文字走動,處于輸出字符的后面,然后再輸入下一個字符;④當文本塊中輸出的文字超過文本矩形框的寬度后,自動換行;⑤文本塊能移動、放大、縮小;⑥文本塊里的文字字體、大小、顏色能設置。
2.1文本矩形框的畫法
文本矩形框的繪制函數為void m_DrawText(CDC*pDC),思路如下:鼠標左鍵點擊,記錄第1次點擊點的邏輯坐標,鼠標處于繪制文本框的狀態,移動鼠標,鼠標左鍵第2次點擊,記錄第2次點擊點的邏輯坐標,調用函數繪制文本矩形框。為保證光標的初始位置顯示在文本框左上頂點,對矩形框繪制做出如下的改進:將這2個點橫縱坐標作比較,橫縱坐標值較小的組成左上頂點,同理橫縱坐標值較大的組成右下頂點,保持在矩形繪圖函數中第1個頂點的橫縱坐標值都要小于第2個點的橫縱坐標值。
2.2光標的畫法
筆者對光標的繪制作了改進,向當前的文本框中插入一個光標形式的字符,并讓字符閃爍,字符輸入后,關閉字符的閃爍,具體作法如下:①得到當前所繪字符的高度,設置插光標字符的長度為所得到字符的高度;②得到要繪制字符邏輯坐標值,設置插入字符的位置;③設置光標字符閃爍;④關閉光標的閃爍。光標繪制的部分代碼如下:
//根據當前字體,設置插入符/光標
pView→LPtoDP(&size);
pView→CreateSolidCaret(2,size.cx);
//設置光標位置
pView→SetCaretPos(caretPos);
//設置閃爍
pView→ShowCaret();
2.3字符的輸入
得到當前文本框的指針后,在視圖中響應系統函數OnChar,對該文本框進行字符的輸入操作,在文本框中的添加字符輸入函數v_Onchar,鍵盤上輸入的字符都是以ansi值輸入,通過ansi值把輸入的字符分成3類,然后對這3類分別處理。具體做法如下:①將輸入的字符分成3種情況,一種是正常的輸入,如“數字、大小寫字母、空格、漢字”;一種是回車鍵的輸入;還有一種是刪除鍵的輸入。②定義用來記輸入字符個數的變量v_i_PointerLoc,用來存儲輸入字符的字符串變量v_TextStr,當正常輸入時,字符串變量就存儲這個字符,字符個數變量加1,回車鍵輸入時,字符串變量記錄一個字符“ ”, 字符個數變量加1,刪除鍵輸入時,字符串變量就刪除一個字符,且字符個數變量減1[5-6]。
2.4字符的輸出
字符串中漢字字符是占2個字節,其他的字符占1個字節,得到存儲在字符串v_TextStr中字符每1個字節的ansi值,與字符的輸入相反的是,如果ansi值是大小寫字母、標點符號、數字,按1個字節讀出當前字符,如果ansi值是漢字的值(ansi>127),按2個字節讀出當前的字符,讀出字符的函數是CString中的Mid(int nFirst,int nCount),nFirst是從字符串中的第幾個字節開始讀取,nCount是讀幾個字節。如ansi>127,nCount的值等于2,因為ansi>127判斷該字節是1個漢字,漢字占2個字節,需要讀取2個字節得到該漢字,所以nCount值取2。具體的步驟如下:①得到整個字符串的字節長度,設定1個無字符型的變量,把讀進來的字符轉化成無字符型的ansi值。②判段ansi值,如果ansi?‘9’ 且ansi?‘0’,說明該字符是數字,就按1個字節得到該字節表示的字符;同理,大小寫字母也按一個字節得到該字節表示的字符;如果是回車鍵,不需要得到字符,把字符串的輸出點的X值歸到文本框最左邊,Y的值加1個字符的高度;如果 ansi>127,說明該字節是漢字,該字節與其后面的1個字節組成1個漢字,Mid函數中的nCount值等于2。③每得到1個字符,調用函數TextOut(x,y,str)來輸出該字符,X的值變化為每輸出1個字符后,加上該字符的寬度,當X的值大于文本矩形最右邊的值后,做自動換行處理,X的值回到文本矩形最左邊的值,Y的值加1個字符的高度。每輸出一個字符后,都記錄輸出后的位置,為繪制光標提供坐標值。部分代碼如下:
unsigned char ansi;
ansi = v_pView→v_Chart.m_CurrentText→v_TextStr[i];
//---------------如果字符是數字小寫字母大寫字母----------------
if ((ansi?‘9’ && ansi ?‘0’)|| (ansi?‘z’ && ansi ?‘a’)|| (ansi?‘Z’ && ansi ?‘A’) )
{
W = v_pView→v_Chart.m_CurrentText→v_TextStr.Mid(i,1);
single.cx = v_pView→v_Chart.m_CurrentText→v_i_FontW;
}
//---------------如果字符是漢字----------------------
else if (ansi > 127)
{
W =v_pView→v_Chart.m_CurrentText→v_TextStr.Mid(i,2);
i++;
single.cx = 2*v_pView→v_Chart.m_CurrentText→v_i_FontW;
}
2.5文本框交互操作

圖1 文本區域劃分圖
文本塊繪制完成后,應用戶的需要,調整框的大小和位置,設計的思路如下:①將文本矩形框劃分成4個矩形,如圖1所示。②分別對文本框的4個矩形建立相應的區域矩形,鼠標左鍵點擊點落在1號區域時,選中文本框,鼠標移動可以拖動文本框改變文本框的位置;鼠標左鍵點擊點落在2號,3號,4號區域時,選中文本框,鼠標移動改變文本框的大小。下面是建立的2號區域部分代碼:
//----------建立文本框水平拉動區域------------------
v_MoveHorz.cy = v_TextRect.Height()-(v_Rgn.cy/2);
v_MoveHorz.cx = v_Rgn.cx;
v_HorzPoint.x = v_TextRect.right-(v_Rgn.cx/2);
v_HorzPoint.y = v_TextRect.top;
CRect HorzText(v_HorzPoint,v_MoveHorz);
CRgn MoveHorz;
pView→LPtoDP(HorzText);
MoveHorz.CreateRectRgnIndirect(HorzText);
③再添加鼠標的移動和左鍵彈起等操作,改變文本框的位置及大小,進行文本塊重畫。
2.6設置文本框屬性對話框

圖2 實例文本框繪制
文本塊作為標題和注釋等解釋時,文本框中字體大小會有所不同,甚至對顏色都有要求,所以設計對話框對文本框中的文字屬性做相應的修改,如字體的大小,字體的顏色。選中要修改的文本塊,選擇字體菜單得到新的字體對象,賦值給文本塊對象,調用視圖的重畫函數。
用VC++6.0 具體實現了在視圖中插入文本塊的編程方法,并應用于項目團隊開發的三維可視化的軟件中,在該軟件中實現了文本塊功能,解決了以往軟件只能輸入英文文本的問題,實現了2個文本框,并實現英文大小寫和漢字和數字輸入、字符換行、字體顏色設置及大小變化等功能(見圖2)。
[1]王永茂,彭維平,王玉琨.用VC++實現矢量圖形的無極縮放[J].福建電腦,2006(6) :182-183.
[2]姜照林.用VC實現Word文檔自動化[J].嘉信學院學報,2007,3(5):68-71.
[3]王姍姍,李海晟.給DIB位圖添加文本的方法[J].電腦編程技巧與維護,2008(4):16-25.
[4]石虎山,裘雪紅.在滾動視圖中嵌入局部文本編輯[J].微機發展,2003,13(9):13-15.
[5]李霞.VC++編程實現“畫”文本[J].編程語言,2006(9):19-22.
[6]李霞.視圖中插入文本塊的編程方法[J].廣州大學學報(自然科學版),2002,13(9):57-59.
[編輯] 洪云飛
10.3969/j.issn.1673-1409(N).2012.12.033
TP391.41
A
1673-1409(2012)12-N102-03