WINCE6下自绘EDITWord下载.docx
- 文档编号:19213723
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:11
- 大小:25.73KB
WINCE6下自绘EDITWord下载.docx
《WINCE6下自绘EDITWord下载.docx》由会员分享,可在线阅读,更多相关《WINCE6下自绘EDITWord下载.docx(11页珍藏版)》请在冰豆网上搜索。
classCCEEdit:
publicCCECWnd
2.1.成员变量
private:
CCEMemDCm_memDC;
//内存DC,就是简单的封装了一下CDC和CBitmap的使用。
CRectm_ClientRect;
BOOLm_bSetCur;
BOOLm_bCareShow;
intm_nCharPosition;
//开始画字符位置
intm_nStartTypeCharPosition;
//输入字符的位置
intm_nMaxChar;
BOOLm_bOnlyNumber;
2.2.成员函数
2.2.1VidDrawBoder()
任何一个控件都必须完成边框的绘制,以便有一个区域。
我这个也不例外,当初始化完成后,将根据m_rect在父对话框的背景上画EDIT的边框。
CRectrct(0,0,m_rect.Width(),m_rect.Height());
m_memDC->
FillSolidRect(rct,RGB(255,2555,255));
Draw3dRect(rct,RGB(0,0,255),RGB(0,0,255));
//输入字符的位置
2.2.2voidDrawNewCaption()
在边框内写文字,暂时设定文字为白底蓝字,每次有新的输入、删除、字符显示的开始位置变化,都要重新输出文字内容。
intnCount=0;
for(inti=1;
i<
=m_strCaption.GetLength()-m_nCharPosition;
i++)
{
CSizesize=m_memDC->
GetTextExtent
(m_strCaption.Mid(m_nCharPosition,i));
intnRes=m_rect.left+size.cx;
if(nRes>
m_rect.right)
{
break;
}
else
nCount++;
}
m_memDC->
DrawText(m_strCaption.Mid(m_nCharPosition,nCount),
m_ClientRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
采用FOR主要是不能让写入的文字超出绘定的矩形框,因为场景中的文字不是等比例的字体,所以“l”和“国”是不可能等宽的。
所以只能一个个的字符判断,当然可以按一个中间字来估算,然后前移或后移,会提高效率,但我没有做这个优化。
如果不进行这个算法,就会显示半个字符,可你会发现MS的EDIT没有这种情况。
2.2.3需要处理的消息
1.来自父窗口的On_Paint消息
我在对话框中放了一个链表,用来记录所有加入的控件,在背景被刷新时,当循环发送给所有的控件,并带着无效区域,各控件按区域是否包含自己来判断自己是否需要重画。
如下代码在控件的OnPaint里
if(rect!
=NULL)
CRectrr;
if(rr.IntersectRect(&
m_rect,rect)==FALSE)
{
return;
}
pDes->
BitBlt(m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height(),m_memDC,0,0,SRCCOPY);
if(m_bFocus)//如果焦点发生变化,则应该对光标进行处理。
if(m_bCareShow==FALSE)
{
m_bCareShow=TRUE;
if(m_pParent)
{
m_pParent->
SetEditCare(this);
}
}
if(m_bCareShow)
m_bCareShow=FALSE;
RemoveEditCare(this);
2.BOOLOnLButtonDown(UINTnFlags,CPointpoint)
当有左键按下时,此时应该把光标闪烁的位置,进行移动,同时如果获得焦点,应该告知父对话框,刚才有焦点那个控件,应该失去。
if(nFlags==1)
if(m_rect.PtInRect(point))
if(m_bFocus==FALSE)//显示光标并处理位置
m_bFocus=TRUE;
UnFocus(this);
intnLeft=CalculatePosition(point);
:
:
SetCaretPos(nLeft,m_rect.top+(m_rect.Height()-14)/2);
ShowCaret(m_pParent->
m_hWnd);
m_bCareShow=TRUE;
else//处理光标位置
if(m_bCareShow)
returnTRUE;
}/**/
returnFALSE;
3.CalculatePosition(CPoint)
这个函数用来计算,当前鼠标在第几个字符后面,应该在哪里闪烁。
intnRes=0;
intOldRes=0;
m_nStartTypeCharPosition=m_nCharPosition;
//一个为字符的输入位置,一个是显示开始位置
for(inti=0;
GetTextExtent(m_strCaption.Mid(m_nCharPosition,i));
m_nStartTypeCharPosition=m_nCharPosition+i;
//因为显示的不一定是第一个字符
nRes=m_rect.left+size.cx;
pt.x||nRes>
m_rect.right)//如果这个字符在鼠标后面,或是到了边框最右边
if(nRes-(nRes-OldRes)/2>
pt.x)//是否超过了1/2字符如果超过,就向后,如果没有向前
nRes=OldRes;
m_nStartTypeCharPosition-=1;
if(m_nStartTypeCharPosition<
0)
m_nStartTypeCharPosition=0;
returnnRes;
OldRes=nRes;
m_CaretCxOld=nRes;
returnnRes;
4.BOOLOnLButtonUp(UINTnFlags,CPointpoint)
主要是发出控件被单击的消息,以便产生单击事件,同时进行一些状态的更新,本控件没有状态的任何改变。
if(m_rect.PtInRect(point))
if(m_pParent)
m_pParent->
InvalidateRect(m_rect);
OnControlClick();
returnFALSE;
5.BOOLOnMouseMove(UINTnFlags,CPointpoint)
这个移动,应该分两种情况,一种是按着鼠标左键的时候,一种是没有。
按着左键应该处理选择的长度问题,因为我没有选择区故这种情况没有处理。
我只是做了鼠标指针的变化,也就是把箭头形状变为输入光标。
if(m_rect.PtInRect(point))
if(m_bSetCur==FALSE)
SetCursor(AfxGetApp()->
LoadStandardCursor(IDC_IBEAM));
m_bSetCur=TRUE;
returnTRUE;
else
if(m_bSetCur)
LoadStandardCursor(IDC_ARROW));
m_bSetCur=FALSE;
6.字符的输入
EDIT最重要的就要是输入字符,所以处理onChar就是必不可少的,输入时要从输入光标处开始输入,同时又要判断输入的字符,因为OnChar这个消息来自对话框,所以一定要在有焦点时才处理输入,这个很重要。
BOOLOnChar(UINTnChar,UINTnRepCnt,UINTnFlags)
{
if(m_bFocus)
BOOLbAllowType=FALSE;
if(m_bOnlyNumber)//只允许输入数字时,需要判断是否是0-9和小数点
if(nChar>
=48&
&
nChar<
=57)//48="
0"
57="
9"
bAllowType=TRUE;
elseif(nChar==46)//46"
."
if(m_strCaption.Find(nChar)==-1)
bAllowType=TRUE;
if(nChar!
=8)//如果是退格,不应该进行输入处理
bAllowType=TRUE;
}
if(bAllowType&
m_strCaption.GetLength()<
m_nMaxChar)
CStringstr;
str.Format(L"
%s%c%s"
m_strCaption.Mid(0,m_nStartTypeCharPosition),
nChar,m_strCaption.Mid(m_nStartTypeCharPosition));
m_strCaption=str;
m_nStartTypeCharPosition++;
CSizesize=m_memDC->
GetTextExtent(m_strCaption.Mid(m_nCharPosition,
m_nStartTypeCharPosition-m_nCharPosition));
if(m_rect.right<
(m_rect.left+size.cx))//确保输入光标不超过最右边
intnCount=m_strCaption.GetLength()-m_nStartTypeCharPosition;
if(nCount==0)
nCount=1;
m_nCharPosition+=nCount;
size=m_memDC->
GetTextExtent(m_strCaption.Mid(m_nCharPosition
m_nStartTypeCharPosition-m_nCharPosition));
:
SetCaretPos(m_rect.left+1+size.cx,m_rect.top+(m_rect.Height()-14)/2);
DrawNewCaption();
if(nChar==8)//8<
-
%s%s"
m_strCaption.Mid(0,m_nStartTypeCharPosition-1)
m_strCaption.Mid(m_nStartTypeCharPosition));
m_nStartTypeCharPosition--;
GetTextExtent(m_strCaption.Mid(m_nCharPosition));
//如果字符长度原先大于矩形
if(m_nCharPosition>
0&
(m_rect.left+size.cx)<
m_rect.right)
m_nCharPosition--;
size=m_memDC->
if(m_nStartTypeCharPosition<
m_nStartTypeCharPosition=0;
returnTRUE;
}
7.BOOLOnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)
KeyDown主要是处理左右键,以便移动输入的光标,并且左右显示编辑框中的内容。
if(nChar==37)//向左的键头
if(m_nStartTypeCharPosition>
m_nStartTypeCharPosition--;
if(m_nCharPosition>
m_nCharPosition>
=m_nStartTypeCharPosition)
m_nCharPosition--;
:
DrawNewCaption();
m_pParent->
elseif(nChar==39)
if(m_nStartTypeCharPosition<
m_strCaption.GetLength())
if(m_rect.right<
(m_rect.left+size.cx))
m_nCharPosition++;
8.创建控件并初始化DC
voidintEditAndDC(CRectrect,CDC*pParentDC,CCEDialog*pParent,
CStringstrCaption)这个主要用来创建控件,相当于CEdit的Create,但也稍有区别,这个的调用时需要父窗口的内存DC已经创建。
当然窗口什么时候创建,或是用DISPLSYDC也可以,但我建议在对话框初始化完成时,因为这更符合MFC的习惯。
m_strCaption=strCaption;
//按纽名称
m_rect=rect;
m_pParent=pParent;
if(m_bInitializationed==FALSE)
m_bInitializationed=TRUE;
m_memDC.CreateDC(pParentDC,m_rect);
CRectrct(0,0,m_rect.Width(),m_rect.Height());
m_memDC->
SetBkMode(TRANSPARENT);
SelectObject(&
m_TextFont);
SetTextColor(m_TextColor);
m_ClientRect=rct;
AddControl((CCECWnd*)this);
as_mhy@
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WINCE6 EDIT