重写TEdit文本编辑框

来源:互联网 发布:win7优化系统 编辑:程序博客网 时间:2024/05/30 04:07
重写TEdit文本编辑框,实现功能如下:
1、输入文本/获取文本,设置字体
2、插入/删除中英文
3、键盘方向键移动光标位置
4、鼠标点击定位字符位置
5、自绘画光标位置
难点:
1、通过定时器,自绘光标
2、从中文输入法中读取文字
3、鼠标定位字符位置
未实现的功能:
1、鼠标多选字符
2、复制、粘贴等右键菜单功能
虽然,上面的功能没有,但就已有的功能来说,基本能适用了。
TWinEditControl.hpp代码内容如下:
#ifndef __TWINEDITCONTROL__#define __TWINEDITCONTROL__#include "gdi.h"#include "TTimeControl.hpp"class TWinEditControl :public TCustomControl{   private:      TCanvas * FCanvas;      int m_left,m_top,m_width,m_height;      Graphics::TBitmap * m_background_bmp;     //背景图      TNotifyEvent  FOnChange;                  //定义外部事件      WideString    m_edit_text;                //输入编辑中的文本      bool          m_getFocus;                 //获得焦点      bool          m_mouse_move;               //鼠标滑过编辑框      unsigned  int m_border_color;             //边框颜色      unsigned  int m_mouse_move_border_color;  //鼠标在上面时的颜色      unsigned  int m_getfocus_border_color;    //焦点颜色      TTimeControl * TTimerCursorShow;                //定时器显示光标      void __fastcall OnTimer(TObject * Sender);//定时器函数      int m_cursorPos;                          //光标位置      void DrawCursor();       //画光标      AnsiString m_text;                        //控件的属性text      AnsiString GetText();                     //读文本内容      void SetText(AnsiString value);           //写文本内容      void SetTipText(AnsiString value);        //设置提示内容      bool m_tiptext;                           //初始提示内容      int m_text_width;                         //文字内容的总宽度      int m_single_width;                       //单个文字的宽度      int m_count;                              //容纳文字总数      int m_char_pos;                           //光标所在字符的位置      int TestStrWidth(WideString str);         //测试字符串宽度      void ChCursor(WideString str);            //中文光标处理      WideString SubEditString();               //当文字长度超出范围时,取部分显示      void MouseToCursor(int X);                //通过鼠标点击,获取字符串位置和光标位置      void AddStrToEdit(WideString str);        //增加新字符串      void DeleteStr();                         //删除字符串      void KeyCursor(WORD Key);                 //方向键改变时,光标位置   protected:      void Draw();        //集中绘图函数      void DrawEditText();//显示内部文字      BEGIN_MESSAGE_MAP          VCL_MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, MouseLeave)          VCL_MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, MouseEnter)          VCL_MESSAGE_HANDLER(/*WM_IME_CHAR*/WM_IME_COMPOSITION,TMessage ,InputText)          VCL_MESSAGE_HANDLER(WM_CHAR      ,TMessage ,InputChar)          VCL_MESSAGE_HANDLER(WM_KILLFOCUS,TMessage ,KillFocus)          VCL_MESSAGE_HANDLER(CM_WANTSPECIALKEY,TMessage,DirectKey)      END_MESSAGE_MAP(TCustomControl)      void __fastcall MouseLeave(TMessage & msg);//鼠标离开控件      void __fastcall MouseEnter(TMessage & msg);//鼠标进入控件      void __fastcall InputText(TMessage & msg); //截获文字输入消息      void __fastcall InputChar(TMessage & msg); //输入单个字符      void __fastcall KillFocus(TMessage & msg); //失去焦点      void __fastcall DirectKey(TMessage & msg); //方向键   public:      void SetSize(TRect &r);      //--------------------------------------------------      __fastcall TWinEditControl(TComponent* Owner);      __fastcall ~TWinEditControl();      //--------------------------------------------------父类成员函数      void __fastcall Paint(void);      void __fastcall CreateParams(TCreateParams &Params);      DYNAMIC void __fastcall MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y);      DYNAMIC void __fastcall MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y);      DYNAMIC void __fastcall MouseMove(Classes::TShiftState Shift, int X, int Y);      //DYNAMIC void __fastcall KeyUp(Word &Key, Classes::TShiftState Shift);      //DYNAMIC void __fastcall KeyPress(char &Key);      virtual void __fastcall SetFocus(void);      //属性      __property Graphics::TCanvas* Canvas = {read=FCanvas};      __property Width;      __property Height;      __property Font;      __property AnsiString Text={read = GetText,write=SetText};      __property AnsiString TipText={read=m_text,write=SetTipText};//提示内容      __property TNotifyEvent OnChange={read=FOnChange,write=FOnChange};}; __fastcall  TWinEditControl::TWinEditControl(TComponent* Owner)        : TCustomControl(Owner){     TCustomControl * Win = (TCustomControl *)(Owner);     this->Parent = Win;     m_background_bmp =  new Graphics::TBitmap;     FCanvas = TCustomControl::Canvas;     //--------------------------------------------------     m_border_color = 0xffC7C7C7;            //正常边框颜色     m_mouse_move_border_color = 0xff1583DD ;//鼠标在上面时的边框颜色     m_getfocus_border_color   = 0xff9EC2DF; //鼠标焦点在编辑框中时的颜色     //--------------------------------------------------     //光标定时器     TTimerCursorShow = new TTimeControl(this->Handle,20,1000);     TTimerCursorShow->OnTime = OnTimer;     m_cursorPos = 0;     //--------------------------------------------------     GdiInit();}void __fastcall TWinEditControl::CreateParams(TCreateParams &Params){     TWinControl::CreateParams(Params);}void TWinEditControl::SetSize(TRect &r){    this->Left   = r.left;    this->Top    = r.top;    this->Width  = r.Width();    this->Height = r.Height();    m_left = r.left;    m_top  = r.top;    m_width= r.Width();    m_height=r.Height();    m_background_bmp->Width = m_width;    m_background_bmp->Height= m_height;    //--------------------------------------------    GdiCreateHandle1(m_background_bmp->Canvas->Handle);    GdiFillRectSolidBrush(0xffffffff,0,0,m_width,m_height);    GdiReleaseGraphics();    Draw();    Paint();}void TWinEditControl::Draw(){    GdiCreateHandle1(m_background_bmp->Canvas->Handle);    //---------------------------------------------------    GdiFillRectSolidBrush(0xffffffff,0,0,m_width,m_height);//清空原有内容    //画外边框    if(m_mouse_move == false)    {       GdiPen(m_border_color,1);       GdiDrawRectangle(0,0,m_width-1,m_height-1);    }    else //鼠标在上面时,点亮边框    {       GdiPen(m_mouse_move_border_color,1);       GdiDrawRectangle(0,0,m_width-1,m_height-1);    }    //处理编辑状态时,再绘加粗边框    if(m_getFocus)    {       GdiPen(m_mouse_move_border_color,1);       GdiDrawRectangle(0,0,m_width-1,m_height-1);       GdiPen(m_getfocus_border_color,1);       GdiDrawRectangle(1,1,m_width-3,m_height-3);    }    //显示文字    DrawEditText();    //---------------------------------------------------    GdiReleaseGraphics();    DrawCursor();//画光标}void __fastcall TWinEditControl::Paint(void){   TRect a(0,0,m_width,m_height);   TRect b(0,0,m_width,m_height);   FCanvas->CopyRect(a,m_background_bmp->Canvas,b);}//鼠标进入控件区void __fastcall TWinEditControl::MouseEnter(TMessage & msg){   this->Cursor = crIBeam;   m_mouse_move = true;   Draw();   Paint();}//鼠标离开控件区void __fastcall TWinEditControl::MouseLeave(TMessage & msg){   if(!m_getFocus) //未处于编辑状态   {       m_mouse_move = false;       Draw();       Paint();   }   this->Cursor = crDefault;}void __fastcall TWinEditControl::MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y){}void __fastcall TWinEditControl::MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y){    this->SetFocus();//设置光标    if(m_tiptext)    //清空提示文字    {       m_edit_text = "";       m_text      = "";       m_cursorPos = 0;       m_tiptext = false;//恢复颜色    }    else //文本框中有输入的内容时    {       MouseToCursor(X);    }    Draw();    Paint();}void __fastcall TWinEditControl::MouseMove(Classes::TShiftState Shift, int X, int Y){}__fastcall TWinEditControl::~TWinEditControl(){    delete TTimerCursorShow;    delete m_background_bmp;}//从输入法获取输入的中文void __fastcall TWinEditControl::InputText(TMessage & msg){    HIMC hIMC;    HWND hWnd = this->Handle;    DWORD dwSize;    WCHAR lpWideStr[100];    hIMC = ImmGetContext(hWnd);//获取输入法窗口句柄    if(!hIMC)return;    if(msg.LParam & GCS_RESULTSTR)//判断空格键取字上屏    {      dwSize = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);//读取字数      dwSize =dwSize + sizeof(WCHAR);      memset(lpWideStr, 0, 100);//清空字符区      //再次调用,获得unicode字符串      ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpWideStr, dwSize);      WideString strText(lpWideStr);      if(m_edit_text.Length() < 180)//总长度小于180个字符      {         AddStrToEdit(strText);//添加新内容      }      ImmReleaseContext(hWnd, hIMC);//释放输入法句柄      Draw();      Paint();      //文本框内容改变事件      if(FOnChange)      {         FOnChange(this);      }    }}//显示文字void TWinEditControl::DrawEditText(){    m_background_bmp->Canvas->Font->Assign(Font);    m_background_bmp->Canvas->Brush->Color = clWhite;    m_background_bmp->Canvas->FillRect(TRect(3,3,m_width-4,m_height-4));    m_background_bmp->Canvas->Brush->Style = bsClear;//文字区域透明    if(m_tiptext)//是否为提示内容       m_background_bmp->Canvas->Font->Color  = 0x808080;    else       m_background_bmp->Canvas->Font->Color  = Font->Color;    if(m_edit_text.IsEmpty() == false)    {       m_background_bmp->Canvas->TextOut(3,4,SubEditString().c_bstr());    }}//输入单个字符,字母或数字void __fastcall TWinEditControl::InputChar(TMessage & msg){    int l_inputchar = msg.WParam;    if(l_inputchar == 8)//删除字符    {       DeleteStr();    }    else    {       if(isascii(l_inputchar))       {          if(m_edit_text.Length() < 180)//总长度小于180个字符          {                AddStrToEdit(WideString((wchar_t)msg.WParam));//添加新内容          }       }    }    m_text = m_edit_text;//存到属性中    Draw();    Paint();    if(FOnChange)    {      FOnChange(this);    }}//重载父类的焦点处理函数void __fastcall TWinEditControl::SetFocus(void){   TWinControl::SetFocus();//焦点移到当前控件      m_getFocus = true;   Draw();   Paint();}//失去焦点响应函数void __fastcall TWinEditControl::KillFocus(TMessage & msg){    m_mouse_move = false;    m_getFocus   = false;    Draw();    Paint();}//文字宽度大于控件宽度时,显示部分字符串WideString TWinEditControl::SubEditString(){    if(!m_edit_text.IsEmpty())    {        m_text_width   = TestStrWidth(m_edit_text);               //测试全部文字宽度        m_single_width = TestStrWidth(m_edit_text.SubString(1,1));//单个文字宽度        m_count        = m_width / m_single_width;                                       //控件能显示文字总个数        if(m_edit_text.Length() >= m_count)        {           AnsiString  l_sub_string = m_edit_text.SubString(m_edit_text.Length()-m_count+1,m_count);           m_cursorPos = TestStrWidth(l_sub_string);           return l_sub_string;        }    }    //m_cursorPos = m_background_bmp->Canvas->TextWidth(m_edit_text);//光标位置    return m_edit_text;}void __fastcall TWinEditControl::OnTimer(TObject * Sender){    if(this->Focused())    {      Draw();      Paint();    }}//读文本内容AnsiString TWinEditControl::GetText(){   return m_text;}//写文本内容void TWinEditControl::SetText(AnsiString value){   m_text      = value;   m_edit_text = value;   Draw();   Paint();}//画光标void TWinEditControl::DrawCursor(){    if(this->Focused())    {      m_background_bmp->Canvas->Pen->Mode  = pmNotXor;      if(m_background_bmp->Canvas->Pen->Color == clBlack)        m_background_bmp->Canvas->Pen->Color = clWhite;      else        m_background_bmp->Canvas->Pen->Color = clBlack;              m_background_bmp->Canvas->Pen->Style = psSolid;      m_background_bmp->Canvas->MoveTo(m_cursorPos+3,4);      m_background_bmp->Canvas->Pen->Width = 1;      m_background_bmp->Canvas->LineTo(m_cursorPos+3,18);    }}//设置提示内容void TWinEditControl::SetTipText(AnsiString value){   m_text      = value;   m_edit_text = value;   m_tiptext = true;   Draw();   Paint();}int TWinEditControl::TestStrWidth(WideString str){    int l_width = m_background_bmp->Canvas->TextWidth(str);    return l_width;}//中文光标void TWinEditControl::ChCursor(WideString str){    if(m_edit_text.Length() == 0)    {       m_cursorPos = 0;       m_char_pos  = 0;       m_text_width= 0;    }    if(m_cursorPos == m_text_width)//添加在尾部    {        m_edit_text = m_edit_text + str;        m_text = m_edit_text;        m_char_pos = m_edit_text.Length();    }    else //插入字符串在中间    {        m_edit_text.Insert(str,m_char_pos+1);        m_char_pos++;    }    m_cursorPos = m_cursorPos + TestStrWidth(str);}//拦截方向键void __fastcall TWinEditControl::DirectKey(TMessage & msg){   if(msg.WParam ==37 || msg.WParam ==38 || msg.WParam ==39 || msg.WParam ==40)   {      OutputDebugStringA(AnsiString(msg.WParam).c_str());      KeyCursor(msg.WParam); //光标处理      msg.Result = 1;   }}//通过鼠标点击获取字符在字符串中位置和光标位置//参数为鼠标点击的横坐标void TWinEditControl::MouseToCursor(int X){   int l_totalwidth = TestStrWidth(m_edit_text);//总宽度   if(X >= l_totalwidth)   {      m_cursorPos = l_totalwidth;      m_char_pos  = m_edit_text.Length();//字符串末尾   }   if(X <= 3 )//3为左边矩   {      m_cursorPos = 0;      m_char_pos  = 0;   }   //鼠标在字符串范围内   if(X > 3 && X < l_totalwidth)   {      int i=0;      int l_charwidth = 0;//单个字符宽度累加和      while( i < m_edit_text.Length())      {          l_charwidth += TestStrWidth(m_edit_text.SubString(i,1));          if(l_charwidth > X)          {             m_char_pos = i;//光标所在字符位置(第1个字符,为1)             m_cursorPos=TestStrWidth(m_edit_text.SubString(1,m_char_pos));             break;          }          i++;      }   }}//向编辑框中增加字符void TWinEditControl::AddStrToEdit(WideString str){   int l_strwidth = TestStrWidth(str);   m_edit_text.Insert(str,m_char_pos+1);   m_char_pos  = m_char_pos + str.Length();   m_cursorPos += TestStrWidth(str);      m_text = m_edit_text;//存到属性中,外部调用   }//删除字符串void TWinEditControl::DeleteStr(){    if(m_cursorPos <= 0)    {       m_char_pos = 0;       m_cursorPos= 0;       return;    }    WideString l_char = m_edit_text.SubString(m_char_pos,1);    int l_char_width  = TestStrWidth(l_char);    m_edit_text.Delete(m_char_pos,1);        //删除在符    m_cursorPos = m_cursorPos - l_char_width;//光标位置减少    --m_char_pos;                            //字符位置减少    if(m_edit_text.IsEmpty())    {        m_cursorPos = 0;//光标位置        m_char_pos  = 0;    }    m_text = m_edit_text;//存到属性中,外部调用}//方向键移动时光标位置int flag = 0;//按一次方向键会出现两次消息void TWinEditControl::KeyCursor(WORD Key){   flag++;   if(Key == 37 && flag == 2)//按下左向键   {       if(m_cursorPos <= 0)       {           m_cursorPos = 0;           m_char_pos  = 0;       }       else       {           WideString l_char = m_edit_text.SubString(m_char_pos,1);           int l_char_width  = TestStrWidth(l_char);           m_cursorPos = m_cursorPos - l_char_width;//光标位置减少           m_char_pos--;                            //字符位置减少       }       Draw();       Paint();       flag = 0 ;   }   if(Key == 39 && flag == 2)   {       int l_edit_width = TestStrWidth(m_edit_text);//字符串总宽度       if(m_cursorPos >= l_edit_width)              //大于总宽度       {           m_cursorPos = l_edit_width;           m_char_pos  = m_edit_text.Length();       }       else       {           WideString l_char = m_edit_text.SubString(m_char_pos+1,1);           int l_char_width  = TestStrWidth(l_char);           m_cursorPos = m_cursorPos + l_char_width;//光标位置减少           m_char_pos++;                            //字符位置减少       }       Draw();       Paint();       flag = 0;   }   }#endif
调用方法如下:
头文件中:
#include "TWinEditControl.hpp"TWinEditControl * TEditControl;
.CPP文件如下:
__fastcall TForm1::TForm1(TComponent* Owner)        : TForm(Owner){     TEditControl = new TWinEditControl(this);     TEditControl->SetSize(TRect(130,150,280,173));     TEditControl->TipText = "请输入用户名";     TEditControl->OnChange = OnChange;}//---------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender){   this->Caption = TEditControl->Text;}//---------------------------------------------------------------------------void __fastcall TForm1::OnChange(TObject * Sender){   this->Caption = TEditControl->Text;}void __fastcall TForm1::Button2Click(TObject *Sender){    TEditControl->Font->Color = clGreen;}//---------------------------------------------------------------------------




0 0
原创粉丝点击