在文字处理中插入符处于插入的位置

5 篇文章 0 订阅
2 篇文章 0 订阅

关于在文档输入时准确的将插入符设置在两个文字中间

1、通过m_ptWriteCaret的坐标判断是否输入了文字

if(m_ptWriteCaret.x==0&&m_ptWriteCaret.y==0)
		pt=CPoint(0,0);
若未输入文字,直接将插入符设置在(0,0)处;

2、判断鼠标点击的纵坐标位置是否超过了文字输入的位置

else
	{
		
		//光标位置超过了输入字符的情况
		if(point.y>(m_ptWriteCaret.y+tm.tmHeight))
			pt=m_ptWriteCaret;//将字符创放在输入文字的末尾;

3、获取字体的信息

CDC *dc;
	dc=GetDC();
	TEXTMETRIC tm;
	dc->GetTextMetrics(&tm);//获取字体信息

4、利用字体的信息利用point.y除以字体高得到应处于哪一行,point.x除以自体的平均宽度判断处于那一列,从而得到插入符的大约位置;(注意这里只是个大约的位置,只是判断在哪个字之间插入,并不是要确定具体的坐标)
		//光标位置超过了输入字符的情况
		if(point.y>(m_ptWriteCaret.y+tm.tmHeight))
			pt=m_ptWriteCaret;//将字符创放在输入文字的末尾;

		//插入符纵坐标在输入纵坐标之内
		else 
		{
			iHeight=point.y/tm.tmHeight;//判断插入符在第几行;
			strLine=m_strAarray.GetAt(iHeight);//从集合类中获取改行字符串;
			CSize sz=dc->GetTextExtent(strLine);//获取改行字符串的长度
			iNum=point.x/tm.tmAveCharWidth;     //获取改行字符串的第几个位置插入
			//在每行已输入字里
			if(point.x<sz.cx)
			{
				//点击首行的情况
				if(iHeight==0)
				{
					//首行首列(第一个字母)
					if(iNum==0)
						ptPoint.x=0;
					//首行其他列时
					else
						ptPoint.x=(dc->GetTextExtent(strLine.Left(iNum))).cx;//插入符的横坐标;
					ptPoint.y=0;
					pt=ptPoint;
				}
				//非首行时
				else
				{
					//首列的情况
					if(iNum==0)
						ptPoint.x=0;
					else
					{
						ptPoint.x=(dc->GetTextExtent(strLine.Left(iNum))).cx;//插入符的横坐标;
					}
					ptPoint.y=iHeight*tm.tmHeight;
					pt=ptPoint;
				}
			}
			//在每行横坐标已输入文字外
			else
			{
				ptPoint.y=iHeight*tm.tmHeight;
				ptPoint.x=sz.cx;
				pt=ptPoint;
			}

4、因为自体的高度是tmHeight的位置是一定的,因此得到的结果能准确的判定插入符在第几行,但由于用于判断横坐标是用的是自体的平均宽度(tmAveWidth)因此若以其作为横坐标就会出现插入符在原有自体上显示的问题。因此,我们利用就近的原则,得到它在哪两个字之间,再获取左右两边的字符串的距离(GetTextExtent)获取准确的插入符横坐标位置。

CString strLeft;//光标左边的字符
			strLeft=strLine.Left(iNum);
			dc->TextOutA(0,pt.y,strLeft);//输出光标左边的字符
			CString strRight;
			strRight=strLine.Right(strLine.GetLength()-iNum);//获取光标右边的字符;
			dc->TextOut(dc->GetTextExtent(strLine.Left(iNum)).cx,pt.y,strRight);
		}
		//保存插入符的实时位置
		m_ptCaret=pt;	
		SetCaretPos(pt);

上述的方式避免了,将插入符显示在字符上的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值