邹雪峰,张 翔
刘琳琳
(辽河油田曙光技术处作业一大队,辽宁 盘锦 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