jasmine214--love

          只有當(dāng)你的內(nèi)心總是充滿快樂、美好的愿望和寧靜時(shí),你才能擁有強(qiáng)壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          VC++ EDIT控件的SetLimitText()用法

          Posted on 2010-08-12 15:08 幻海藍(lán)夢(mèng) 閱讀(7050) 評(píng)論(0)  編輯  收藏 所屬分類: C++
           原文:http://221.199.150.103/jsj/Html/vc/wen/vcwen10.htm

          用VC++6.0編程的時(shí)候,文本編輯控件Edit Box是一個(gè)經(jīng)常用到的控件。如果你是用它輸入一些簡(jiǎn)單的文字、數(shù)字等信息,直接拿來用就可以了,但如果你用它制作大文本的編輯軟件,就會(huì)覺得不好控制,許多功能無法實(shí)現(xiàn),即便用CEditView,也只會(huì)生成一個(gè)類似于記事本的東西,再想加入些自己編寫的功能也很困難。下面我以CEdit為基類定義了一個(gè)CEditBox類,加入了許多文本編輯時(shí)經(jīng)常要用到的接口函數(shù),用它來控制Edit Box控件就很容易制作出具有較強(qiáng)文本編輯功能的編輯軟件了。

          在這個(gè)擴(kuò)展類中主要增加了以下功能:

          ①增加控件的容量,使它能容納大文本;
          ②可設(shè)置編輯控件文字顏色、背景色和字體;
          ③對(duì)控件內(nèi)的文本和選擇文本的訪問;
          ④直接裝入文件到控件和保存控件內(nèi)容到文件;
          ⑤自定義的右鍵菜單;
          ⑥多重ReDo/UnDo功能。

          這些功能基本上都是獨(dú)立的,實(shí)際使用時(shí)可根據(jù)需要選用所需功能。

          準(zhǔn)備工作:用ClassWizard在工程中加入一個(gè)新類,基類選為CEdit,類名設(shè)置為CEditBox。

          一、設(shè)置控件的容量:

          EditBox控件默認(rèn)情況下只能裝入64K的文本,如果超出,多出部分會(huì)被自動(dòng)截掉。利用CEdit類的SetLimitText()函數(shù)可重新設(shè)置控件容量。

          函數(shù)原型為:

          void SetLimitText(UINT nMax);

          參數(shù)為nMax為控件可接收的文本最大字節(jié)數(shù)。

          設(shè)置方法:用ClassWizard在CEditBox類中添加消息函數(shù)PreSubclassWindow(),把設(shè)置文本容量的語句放在里面即可。

          void CEditBox::PreSubclassWindow()
          {
              SetLimitText( -1 );    
          //設(shè)置編輯控件可接收的最大字節(jié)數(shù)
              CEdit::PreSubclassWindow();
          }

          因?yàn)閚Max為無符號(hào)整型,-1是把它設(shè)置為可以取到的最大值。你也可以根據(jù)需要設(shè)置控件的容量。

          注意:在不同操作系統(tǒng)下,控件可設(shè)置的最大容量也不同。如果是Windows98,這個(gè)值就是64K,無法再增大了,而在Windows2000和WindowsXP下這個(gè)值要大得多,才可以起到增加控件容量的目的。

          二、設(shè)置編輯控件的前景色、背景色和字體:

          在CEditBox的頭文件中加入以下變量定義:

          COLORREF    m_ForeColor;       //文本顏色
          COLORREF    m_BackColor;       
          //背景色
          CBrush      m_BkBrush;         
          //背景刷
          CFont*      p_Font;            
          //字體指針
          int         m_FontSize;        
          //字體大小(1/10點(diǎn))
          CString     m_FontName;        
          //字體名

          在CEditBox的構(gòu)造函數(shù)中設(shè)置它們的初值:

          CEditBox::CEditBox()
          {
              m_ForeColor = RGB(0,0,0);          
          //文字顏色(黑)
              m_BackColor = RGB(255,255,255);    
          //文字背景色(白)
              m_BkBrush.CreateSolidBrush(m_BackColor);   
          //背景刷
              p_Font = NULL;        
          //字體指針
          }

          在CEditBox的析構(gòu)函數(shù)中回收創(chuàng)建的字體資源:

          CEditBox::~CEditBox()
          {
              if( p_Font )
                  delete p_Font;    
          //回收字體資源
          }

          這里只設(shè)置了前景色和背景色的默認(rèn)值,如果想設(shè)置默認(rèn)字體,可在上面的PreSubclassWindow()函數(shù)中進(jìn)行設(shè)置:

          void CEditBox::PreSubclassWindow()
          {
              SetLimitText( -1 );    
          //設(shè)置編輯控件可接收的最大字節(jié)數(shù)
              
              m_FontSize = 100;
              m_FontName = _T("
          宋體");
              p_Font = new CFont;    
          //生成字體對(duì)象
              p_Font->CreatePointFont( m_FontSize, m_FontName );  
          //創(chuàng)建字體
              SetFont( p_Font );     
          //設(shè)置控件默認(rèn)字體

              CEdit::PreSubclassWindow();
          }

          這里使用了比較簡(jiǎn)單的CreatePointFont()函數(shù)創(chuàng)建字體,它只需給出字體尺寸和字體名。如果想創(chuàng)建更復(fù)雜的字體,可以改用CreateFont()函數(shù)。本例中設(shè)置控件的初始字體為尺寸為100(0.1點(diǎn))的“宋體”字。

          如果你想用EditBox本身的默認(rèn)字體作為初始字體,就不要在PreSubclassWindow()函數(shù)中加入這些語句。

          用ClassWizard添加消息反射函數(shù)CtlColor()來修改控件的文本顏色和背景色。

          注意:在ClassWizard下可看到有兩個(gè)很相似的消息,一個(gè)是“=WM_CTLCOLOR”消息,另一個(gè)是“WM_CTLCOLOR”消息,這里必須用“=WM_CTLCOLOR”消息添加函數(shù)。如果誤用了“WM_CTLCOLOR”消息將得不到想要的效果。

          HBRUSH CEditBox::CtlColor(CDC* pDC, UINT nCtlColor)
          {
              pDC->SetTextColor( m_ForeColor );    
          //設(shè)置控件文字顏色
              pDC->SetBkColor( m_BackColor );      
          //設(shè)置文字的背景色
              return (HBRUSH)m_BkBrush.GetSafeHandle();  
          //控件背景刷
          }

          PreSubclassWindow()和CtlColor()函數(shù)都是消息函數(shù),為了設(shè)置控件顏色和字體,還需定義接口函數(shù)在使用時(shí)調(diào)用:

          //設(shè)置文本顏色
          void CEditBox::SetForeColor(COLORREF color)
          {
              m_ForeColor = color;
              Invalidate();
          }

          //獲取文本顏色
          COLORREF CEditBox::GetForeColor()
          {
              return m_ForeColor;
          }

          //設(shè)置背景顏色
          void CEditBox::SetBkColor(COLORREF color)
          {
              m_BackColor = color;
              m_BkBrush.Detach();
              m_BkBrush.CreateSolidBrush( m_BackColor );
              Invalidate();
          }

          //獲取背景色
          COLORREF CEditBox::GetBkColor()
          {
              return m_BackColor;
          }

          //設(shè)置字體
          void CEditBox::SetTextFont(int FontSize,LPCTSTR FontName)
          {
              if ( p_Font )    delete p_Font;
                 p_Font = new CFont;
              p_Font->CreatePointFont( FontSize, FontName );
              SetFont( p_Font );
              m_FontSize = FontSize;
              m_FontName = FontName;
          }

          //獲取字體大小
          int CEditBox::GetFontSize()
          {
              return m_FontSize;
          }

          //獲取字體名
          CString CEditBox::GetFontName()
          {
              return m_FontName;
          }

          至此,用CEditBox類可以定義出可設(shè)置顏色和字體的Edit Box控件了。使用時(shí),先在對(duì)話框中加入一個(gè)Edit Box控件,用ClassWizard為定義一個(gè)控制變量m_Edit,類型設(shè)定為CEditBox。然后用m_Edit.SetForeColor(color)、m_Edit.SetBkColor()和m_Edit.SetTextFont(FontHight,FontName)為控件設(shè)置顏色和字體,這樣就可以作出一個(gè)美觀的文本框了。

          說明:Edit Box控件只能放入純文本,不支持對(duì)文本格式的設(shè)置,也就不能對(duì)局部的文字顏色和字體進(jìn)行設(shè)置,所以,以上設(shè)置都是針對(duì)整個(gè)控件的。

          三、訪問編輯控件的內(nèi)容:

          Edit Box控件已經(jīng)提供了幾種訪問控件內(nèi)容的方法:

          ①定義一個(gè)與控件關(guān)聯(lián)的變量,類型可設(shè)置為CString或其它類型,用UpdateData()函數(shù)來更新控件或變量。

          ②用GetWindowText()獲取控件內(nèi)文本,用SetWindowText()設(shè)置控件文本。

          ③用SetSel()設(shè)置控件內(nèi)的選擇區(qū),用GetSel()獲取控件中選擇文本的位置,用ReplaceSel()替換選擇的文本。

          但只用這幾種方法還是不太方便,所以在CEditBox類中又增加了幾個(gè)訪問接口函數(shù)。

          1、讀取控件文本ReadText()

          int CEditBox::ReadText(CString& str)
          {
              GetWindowText( str );        
          //獲取控件文本
              return str.GetLength();      
          //文本長(zhǎng)度
          }

          參數(shù)str是字符串的引用,用于接收讀取的控件內(nèi)容,返回值是控件中文本字節(jié)數(shù)。

          2、用字符串設(shè)置控件內(nèi)容SetText()

          void CEditBox::SetText(LPCTSTR str)
          {
              SetSel( 0, -1, true );    
          //全選
              ReplaceSel( str );        
          //替換
              SetSel(0);                
          //設(shè)置插入點(diǎn)為起始位置
          }

          參數(shù)str是準(zhǔn)備設(shè)置控件的內(nèi)容,要求是字符串。

          3、讀取當(dāng)前選擇的文本ReadSelText()

          int CEditBox::ReadSelText(CString& str)
          {
              int selStart, selEnd;
              GetSel( selStart, selEnd );      
          //獲取當(dāng)前選擇的位置
              int selLen = selEnd-selStart;    
          //求選擇區(qū)長(zhǎng)度
              if( selLen )
              {
                  CString text;
                  GetWindowText( text );      
          //獲取控件文本
                  str = text.Mid( selStart, selLen );  
          //獲取選擇的文本
              }
              else
                  str = _T("");
              return selLen;
          }

          參數(shù)str是字符串的引用,用于接收讀出的文本,返回值是讀出的文本字節(jié)數(shù)。

          如果當(dāng)前控件中有內(nèi)容被選擇,則讀出選擇文本,并返回長(zhǎng)度;如果沒有選擇的文本,讀出的是空串,返回為0。

          4、設(shè)置選擇區(qū)SetSelText()

          void CEditBox::SetSelText(int nStartChar,int nSelLen)
          {
              SetSel(nStartChar,nStartChar+nSelLen);
          }

          參數(shù)nStartChar為選擇區(qū)起點(diǎn)(從0算起),nSelLen為選擇區(qū)長(zhǎng)度。

          功能是把控件的指定區(qū)域設(shè)置為選擇的狀態(tài)。

          5、當(dāng)前是否有選擇isSelect()

          BOOL CEditBox::isSelect()
          {
              int selStart, selEnd;
              GetSel( selStart, selEnd );     
          //獲取當(dāng)前選擇的位置
              return selEnd-selStart;
          }

          如果當(dāng)前控件中有選擇的文本,返回非0值,否則返回0。

          以上是為了使控件訪問更方便而增加的接口函數(shù)。再配合CEdit本身提供的訪問函數(shù),很多操作都可輕易實(shí)現(xiàn)了。

          CEdit控件提供訪問函數(shù)主要有:

          int GetWindowText(LPCTSTR lpszStringBuf,int nMaxCount);
          獲取控件文本,與ReadText()功能相同。

          void SetWindowText(LPCTSTR lpszString);
          設(shè)置控件文本。

          void GetSel(int& nStartChar,int& nEndChar);
          獲取選擇區(qū)的位置

          void SetSel(int nStartChar,int nEndChar,BOOL bNoScroll=FALSE);
          設(shè)置選擇區(qū),參數(shù)為起點(diǎn)和終點(diǎn),用SetSel(0,-1)可設(shè)置為全選

          void ReplaceSel(LPCTSTR lpszNewText,BOOL bCanUndo=FALSE);
          用字符串替換選擇的文本

          四、與文件的接口:

          這部分接口函數(shù)供“打開文件”和“保存文件”等操作調(diào)用。把它們定義在CEditBox類中,增強(qiáng)了控件的封裝性,也可以簡(jiǎn)化應(yīng)用中“打開”和“保存”的操作。

          1、文件內(nèi)容裝入Edit控件

          void CEditBox::LoadFile(LPCTSTR PathName)
          {
              CFile file;        
          //構(gòu)造一個(gè)CFile類的對(duì)象
              if( file.Open( PathName, CFile::modeRead )==0 )  
          //以讀方式打開文件
                  return;
              int len = file.GetLength();        
          //求文件長(zhǎng)度
              CString text = _T("");
              file.Read( text.GetBufferSetLength(len), len );  
          //讀文件
              text.ReleaseBuffer();
              file.Close();                   
          //關(guān)閉文件
              SetText( text );                
          //裝入編輯控件
              m_PathName = PathName;
              SetModify( false );        
          //清除修改標(biāo)志
          }

          參數(shù)PathName為文件路徑名,調(diào)用該函數(shù)可以把指定文件裝入編輯控件。如果文件不存在,直接返回。

          2、保存編輯控件內(nèi)容到文件

          void CEditBox::SaveFile(LPCTSTR PathName)
          {
              CFile file;
              if( file.Open( PathName, CFile::modeCreate | CFile::modeWrite )==0 )
                  return;
              CString text;
              int textLen = ReadText( text );
              file.Write( (LPCTSTR)text, textLen ); 
          //把字符串內(nèi)容寫入文件
              file.Close();            
          //關(guān)閉文件
              m_PathName = PathName;
              SetModify( false );      
          //清除修改標(biāo)志
          }

          參數(shù)PathName為文件路徑名,調(diào)用該函數(shù)可以把控件內(nèi)容寫入指定文件。如果建立文件失敗,直接返回。

          3、新建文件

          void CEditBox::NewFile()
          {
              SetSel( 0, -1, true );  
          //全選
              Clear();                
          //清除
              m_PathName = _T("");
              SetModify( false );     
          //清除修改標(biāo)志
          }

          供“新建”文件菜單消息調(diào)用,功能是清空控件。

          4、是否有文件打開

          BOOL CEditBox::isOpenFile()
          {
              return !(m_PathName.IsEmpty());
          }

          如果控件中已經(jīng)有打開的文件,返回非0,否則返回0。

          5、獲取打開的文件名

          CString CEditBox::GetPathName()
          {
              return m_PathName;
          }

          如果控件中已經(jīng)有打開的文件,返回文件路徑名,否則返回空串。

          這5個(gè)函數(shù)中的m_PathName是在CEditBox中定義的字符串變量,并初始化為空串。

          五、自定義右鍵菜單:

          文本編輯框已經(jīng)提供了一個(gè)默認(rèn)右鍵菜單,如果你想重新定義一個(gè)來代替它,可以按下面的方法制作。

          在VC++的Project菜單下選擇Add To Project下的Components and Controls,在彈出的對(duì)話框中打開Visual C++ Components,找到Pop-up Menu,單擊Insert按鈕,選擇加入的類為CEditBox,確定。關(guān)閉對(duì)話框。

          這時(shí),你在CEditBox類中會(huì)看到已經(jīng)加入了下面的代碼:

          void CEditBox::OnContextMenu(CWnd*, CPoint point)
          {
              // CG: This block was added by the Pop-up Menu component
              {
                  if (point.x == -1 && point.y == -1){
                      //keystroke invocation
                      CRect rect;
                      GetClientRect(rect);
                      ClientToScreen(rect);
                      point = rect.TopLeft();
                      point.Offset(5, 5);
                  }
                  CMenu menu;
                  VERIFY(menu.LoadMenu(CG_IDR_POPUP_EDIT_BOX));
                  CMenu* pPopup = menu.GetSubMenu(0);
                  ASSERT(pPopup != NULL);
                  CWnd* pWndPopupOwner = this;
                  while (pWndPopupOwner->GetStyle() & WS_CHILD)
                      pWndPopupOwner = pWndPopupOwner->GetParent();
                  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
                      pWndPopupOwner);
              }
          }

          再到資源的Menu下,你可以找到一個(gè)ID號(hào)為CG_IDR_POPUP_EDIT_BOX的新菜單,編輯它就可得到你想要的右鍵菜單了。這和其它菜單的做法沒有區(qū)別,我就不再詳細(xì)介紹了。

          主站蜘蛛池模板: 阿合奇县| 汉阴县| 西乌珠穆沁旗| 佛教| 措美县| 鄯善县| 正阳县| 绿春县| 漾濞| 府谷县| 武安市| 安康市| 荃湾区| 曲沃县| 黄梅县| 新宁县| 灵川县| 固始县| 淮滨县| 分宜县| 绩溪县| 富锦市| 论坛| 鄯善县| 东源县| 和林格尔县| 北宁市| 合作市| 如东县| 文化| 岑溪市| 当涂县| 横山县| 建瓯市| 曲靖市| 琼结县| 桦甸市| 晋江市| 谢通门县| 上栗县| 抚州市|