WINCE6下自绘EDIT.docx

上传人:b****5 文档编号:6208924 上传时间:2023-01-04 格式:DOCX 页数:11 大小:25.73KB
下载 相关 举报
WINCE6下自绘EDIT.docx_第1页
第1页 / 共11页
WINCE6下自绘EDIT.docx_第2页
第2页 / 共11页
WINCE6下自绘EDIT.docx_第3页
第3页 / 共11页
WINCE6下自绘EDIT.docx_第4页
第4页 / 共11页
WINCE6下自绘EDIT.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

WINCE6下自绘EDIT.docx

《WINCE6下自绘EDIT.docx》由会员分享,可在线阅读,更多相关《WINCE6下自绘EDIT.docx(11页珍藏版)》请在冰豆网上搜索。

WINCE6下自绘EDIT.docx

WINCE6下自绘EDIT

WINCE6.0中自画EDIT

SUNNY.MAN

本人在此郑重声明,写这个EDIT绝不是为了好看或是哗众取宠。

我的ARM主频是400M的,当我一次性放了超过30个EDIT时,显示这个对话框时,刷新时居然是一行行的刷出来的EDIT。

所以自己在对话框的界面上,自已画了这个EDIT,其实只是在对话框上完成固定资产区域的输入,顺便把画的过程中容易出现的一些问题也了下来,这就是本文的由来…

一、EDIT外观图

图中所示的红色区域内的就是EDIT控件,这个控件其实只是对话框上的一个区域。

下面我将粗略的讲一下我的开发过程。

首先把这个控件命名为CCEEditBox公共继承自CCECwnd.这个CCECwnd是我自定义的一个c++类,只为了以后控件的虚拟化,给所有的控件人为的制造一个父类。

它不是来自CWnd类,它只是一个c++类。

它的成员变量有如下几个:

BOOLm_bFocus;//是否获得焦点

intm_nControlType;//控件类型

CStringm_strCaption;//内容

CRectm_rect;//自己的RECT所在位置

CDialog*m_pParent;

BOOLm_bInitializationed;//是否内存DC已经初始化

COLORREFm_TextColor;

CFontm_TextFont;

BOOLm_bVisible;

二.控件的定义

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));

m_memDC->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);

}

}

}

else

{

if(m_bCareShow)

{

m_bCareShow=FALSE;

if(m_pParent)

{

m_pParent->RemoveEditCare(this);

}

}

}

2.BOOLOnLButtonDown(UINTnFlags,CPointpoint)

当有左键按下时,此时应该把光标闪烁的位置,进行移动,同时如果获得焦点,应该告知父对话框,刚才有焦点那个控件,应该失去。

if(nFlags==1)

{

if(m_rect.PtInRect(point))

{

if(m_bFocus==FALSE)//显示光标并处理位置

{

m_bFocus=TRUE;

if(m_pParent)

{

m_pParent->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)

{

intnLeft=CalculatePosition(point);

:

:

SetCaretPos(nLeft,m_rect.top+(m_rect.Height()-14)/2);

}

}

returnTRUE;

}/**/

returnFALSE;

}

3.CalculatePosition(CPoint)

这个函数用来计算,当前鼠标在第几个字符后面,应该在哪里闪烁。

intnRes=0;

intOldRes=0;

m_nStartTypeCharPosition=m_nCharPosition;//一个为字符的输入位置,一个是显示开始位置

for(inti=0;i<=m_strCaption.GetLength()-m_nCharPosition;i++)

{

CSizesize=m_memDC->GetTextExtent(m_strCaption.Mid(m_nCharPosition,i));

m_nStartTypeCharPosition=m_nCharPosition+i;//因为显示的不一定是第一个字符

nRes=m_rect.left+size.cx;

if(nRes>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();

returnTRUE;

}

}

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)

{

SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));

m_bSetCur=FALSE;

}

}

returnFALSE;

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;

}

}

}

else

{

if(nChar!

=8)//如果是退格,不应该进行输入处理

bAllowType=TRUE;

}

if(bAllowType&&m_strCaption.GetLength()

{

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();

m_pParent->InvalidateRect(m_rect);

}

if(nChar==8)//8<-

{

CStringstr;

str.Format(L"%s%s",m_strCaption.Mid(0,m_nStartTypeCharPosition-1)

m_strCaption.Mid(m_nStartTypeCharPosition));

m_strCaption=str;

m_nStartTypeCharPosition--;

CSizesize=m_memDC->GetTextExtent(m_strCaption.Mid(m_nCharPosition));

//如果字符长度原先大于矩形

if(m_nCharPosition>0&&(m_rect.left+size.cx)

{

m_nCharPosition--;

}

size=m_memDC->GetTextExtent(m_strCaption.Mid(m_nCharPosition,

m_nStartTypeCharPosition-m_nCharPosition));

if(m_nStartTypeCharPosition<0)

m_nStartTypeCharPosition=0;

:

:

SetCaretPos(m_rect.left+1+size.cx,m_rect.top+(m_rect.Height()-14)/2);

DrawNewCaption();

m_pParent->InvalidateRect(m_rect);

}

}

returnTRUE;

}

7.BOOLOnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)

KeyDown主要是处理左右键,以便移动输入的光标,并且左右显示编辑框中的内容。

if(nChar==37)//向左的键头

{

if(m_nStartTypeCharPosition>0)

m_nStartTypeCharPosition--;

if(m_nCharPosition>0&&m_nCharPosition>=m_nStartTypeCharPosition)

{

m_nCharPosition--;

}

CSizesize=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();

m_pParent->InvalidateRect(m_rect);

}

elseif(nChar==39)

{

if(m_nStartTypeCharPosition

m_nStartTypeCharPosition++;

CSizesize=m_memDC->GetTextExtent(m_strCaption.Mid(m_nCharPosition,

m_nStartTypeCharPosition-m_nCharPosition));

if(m_rect.right<(m_rect.left+size.cx))

{

m_nCharPosition++;

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();

m_pParent->InvalidateRect(m_rect);

}

returnTRUE;

 

8.创建控件并初始化DC

voidintEditAndDC(CRectrect,CDC*pParentDC,CCEDialog*pParent,

CStringstrCaption)这个主要用来创建控件,相当于CEdit的Create,但也稍有区别,这个的调用时需要父窗口的内存DC已经创建。

当然窗口什么时候创建,或是用DISPLSYDC也可以,但我建议在对话框初始化完成时,因为这更符合MFC的习惯。

m_strCaption=strCaption;//按纽名称

m_rect=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);

m_memDC->SelectObject(&m_TextFont);

m_memDC->SetTextColor(m_TextColor);

m_ClientRect=rct;

DrawNewCaption();

m_pParent->AddControl((CCECWnd*)this);

}

 

as_mhy@

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1