zoukankan      html  css  js  c++  java
  • 增加duilib edit控件的提示功能和多种文字颜色

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41786407

          duilib的CEditUI控件内部使用了win32的原生edit控件,最近在做的一个项目里需要增强CEditUI控件的一些功能,我就把改进的代码写到博客里。实际上改进代码很简单,不过也许能其他人会用到,就不用再费时了。


        增加的功能如下:

         1、增加提示文本,并且可以设置提示文本的颜色,当CEditUI初始化或者无文本的状态下,可以自动按照一定颜色显示出提示文本。(可以不设置提示文本)

         2、可以单独为原生edit控件设置文本颜色(原来是原生edit控件和CEditUI的文本颜色都一样)


        对应的属性描述如下:

    		<Attribute name="nativetextcolor" default="0x00000000" type="DWORD" comment="windows原生edit控件的文字颜色,如(0xFFFFFFFF)"/>
    		<Attribute name="tipvalue" default="" type="STRING" comment="文本框内提示文字,当文本框text为空时显示并失去焦点时显示"/>
    		<Attribute name="tipvaluecolor" default="0xFFBAC0C5" type="DWORD" comment="文本框内提示文字的颜色"/>


         这样子修改后可以做的效果是:通过设置初始提示字符串和颜色,达到提示作用,常用在搜索栏和用户账户输入的情况下,当用户点击CEditUI后这个提示字符串将自动消失,当CEditUI内无文本时提示字符串自动出现。单独设置原生edit控件的文本颜色,可以让CEditUI的当前状态更加明显,比如无焦点时文本是一个颜色,获取焦点时文本是另一个颜色(实际上类似于其他控件的hottextcolor属性)。


         这样的话,修改后的CEditUI就有三种文本颜色效果,根据需求来使用他。这里先贴一张效果图说明这个效果,初始状态或者无文本情况下,CEditUI出现了灰色的提示文字,当用户输入时文本颜色为黑色,输入完成后变为红色文字:




           上图效果对应的xml描述如下:

    <Edit name="edt_url" padding="10,5,0,0" textpadding="5,5,5,5" bkcolor="#FFFFFFFF" width="350" height="28"  font="0"  tipvalue="请输入用户名" tipvaluecolor="#FF989898" nativetextcolor="#FF000000" nativebkcolor="#FFFFFFFF" textcolor="#FFFF0000"  />


    改进过程1:


          实际上在Uilib库(duilib的扩展版本,在我的维护库里面也提供了Uilib)中的CEditUI控件提供了这个功能,但是使用上有些不足,我从Uilib里把提示文本的功能移植到Duilib中,并且增强了提示的功能和逻辑:


         首先给CEditUI增加几个成员函数:

    void SetTipValue(LPCTSTR pStrTipValue);
    void SetTipValueColor(LPCTSTR pStrColor);
    DWORD GetTipValueColor();
    CDuiString GetTipValue();
    LPCTSTR GetSrcTipValue();
    
    CDuiString m_sTipValue;
    CDuiString m_sSrcTipValue;
    DWORD m_sTipValueColor;

          对应的实现代码为:


    	void CEditUI::SetTipValue( LPCTSTR pStrTipValue )
    	{
    		if(m_sText != _T(""))
    			m_sText = pStrTipValue;
    		m_sSrcTipValue	= pStrTipValue;
    		m_sTipValue = CDuiString(_T("__IsTipValue__"))+pStrTipValue;
    	}
    
    	void CEditUI::SetTipValueColor( LPCTSTR pStrColor )
    	{
    		if( *pStrColor == _T('#')) pStrColor = ::CharNext(pStrColor);
    		LPTSTR pstr = NULL;
    		DWORD clrColor = _tcstoul(pStrColor, &pstr, 16);
    
    		m_sTipValueColor = clrColor;
    	}
    
    	DWORD CEditUI::GetTipValueColor()
    	{
    		return m_sTipValueColor;
    	}
    
    	CDuiString CEditUI::GetTipValue()
    	{
    		return m_sTipValue;
    	}
    
    	LPCTSTR CEditUI::GetSrcTipValue()
    	{
    		return m_sSrcTipValue.GetData();
    	}


            这里面SetTipValue函数会判断,如果CEditUI控件本身的文本为空的话,就设置他的初始本文为tipvalue的文本,这就是CEditUI控件初始化时显示的提示文本。如果在xml编写中另外设置了CEditUI的text属性,那么SetTipValue函数就不会初始化CEditUI的文本了。


            然后给SetAttribute函数增加代码:

    		else if( _tcscmp(pstrName, _T("tipvalue")) == 0 ) SetTipValue(pstrValue);
    		else if( _tcscmp(pstrName, _T("tipvaluecolor")) == 0 ) SetTipValueColor(pstrValue);
    		else if( _tcscmp(pstrName, _T("nativetextcolor")) == 0 ) SetNativeEditTextColor(pstrValue);

          接下来重写PaintText函数,就完成了这个功能:


    	void CEditUI::PaintText(HDC hDC)
    	{
    		DWORD mCurTextColor = m_dwTextColor;
    
    		if( m_dwTextColor == 0 ) mCurTextColor = m_dwTextColor = m_pManager->GetDefaultFontColor();
    		if(GetText() == m_sSrcTipValue || GetText() == _T(""))	mCurTextColor = m_sTipValueColor;
    		if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
    
    		CDuiString sText;
    		if( m_sText.IsEmpty() ) 
    			sText = m_sSrcTipValue;
    		else 
    			sText = m_sText;
    
    		if( m_bPasswordMode ) {
    			sText.Empty();
    			LPCTSTR p = m_sText.GetData();
    			while( *p != _T('') ) {
    				sText += m_cPasswordChar;
    				p = ::CharNext(p);
    			}
    		}
    
    		RECT rc = m_rcItem;
    		rc.left += m_rcTextPadding.left;
    		rc.right -= m_rcTextPadding.right;
    		rc.top += m_rcTextPadding.top;
    		rc.bottom -= m_rcTextPadding.bottom;
    		if( IsEnabled() ) {
    			CRenderEngine::DrawText(hDC, m_pManager, rc, sText, mCurTextColor, 
    				m_iFont, DT_SINGLELINE | m_uTextStyle);
    		}
    		else {
    			CRenderEngine::DrawText(hDC, m_pManager, rc, sText, m_dwDisabledTextColor, 
    				m_iFont, DT_SINGLELINE | m_uTextStyle);
    		}
    	}

            在代码里面判断,如果当前的文本为空或者本文恰好是提示文本,那就设把绘制文本的颜色设置为提示文本的颜色。接下来判断如果CEditUI的文本是空的,就让他绘制提示文本。这就完成了当CEditUI无文本状态下显示提示文本的功能。


    改进过程2:


           CEditUI控件没有hottextcolor(或者叫focustextcolor更合适)这个属性,如果有这个属性,就可以设置更多的颜色值,让输入状态和普通状态的文本颜色有区别,让用户可以更明显区分出CEditUI正在输入和输入完毕。


          在输入状态下,实际是win32的edit控件起作用,所以给她设置颜色就行了。为此应该添加一个名为nativetextcolor的属性,增加成员函数如下:

    		void SetNativeEditTextColor( LPCTSTR pStrColor );
    		DWORD GetNativeEditTextColor() const;
    		DWORD m_dwEditTextColor;


         对应的实现代码:

    	void CEditUI::SetNativeEditTextColor( LPCTSTR pStrColor )
    	{
    		if( *pStrColor == _T('#')) pStrColor = ::CharNext(pStrColor);
    		LPTSTR pstr = NULL;
    		DWORD clrColor = _tcstoul(pStrColor, &pstr, 16);
    
    		m_dwEditTextColor = clrColor;
    	}
    
    	DWORD CEditUI::GetNativeEditTextColor() const
    	{
    		return m_dwEditTextColor;
    	}

            

             其中m_dwEditTextColor初始化为0x000000,SetAttribute里增加的代码我也就不贴了。接下来CEditWnd类的HandleMessage函数的WM_CTLCOLOREDIT和WM_CTLCOLORSTATIC消息响应:


    LRESULT CEditWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	//.....省略
    	else if( uMsg == OCM__BASE + WM_CTLCOLOREDIT  || uMsg == OCM__BASE + WM_CTLCOLORSTATIC ) {
    		if( m_pOwner->GetNativeEditBkColor() == 0xFFFFFFFF ) return NULL;
    		::SetBkMode((HDC)wParam, TRANSPARENT);
    
    		DWORD dwTextColor;
    		if (m_pOwner->GetNativeEditTextColor() != 0x000000)
    			dwTextColor = m_pOwner->GetNativeEditTextColor();
    		else
    			dwTextColor = m_pOwner->GetTextColor();
    
    		::SetTextColor((HDC)wParam, RGB(GetBValue(dwTextColor),GetGValue(dwTextColor),GetRValue(dwTextColor)));
    		if( m_hBkBrush == NULL ) {
    			DWORD clrColor = m_pOwner->GetNativeEditBkColor();
    			m_hBkBrush = ::CreateSolidBrush(RGB(GetBValue(clrColor), GetGValue(clrColor), GetRValue(clrColor)));
    		}
    		return (LRESULT)m_hBkBrush;
    	}
    	//.....省略
    }

           这里判断如果用户设置过nativetextcolor(也就是他不为0x000000),就文本颜色为nativetextcolor,否则和CEditUI的textcolor保持一致。


    总结:

         修改代码很简单,不过我使用了一下感觉挺方便的。修改的代码我已经更新到了我维护的duilib和uilib库中,地址为:点击打开链接


    Redrain  2014.12.7


    QQ:491646717


  • 相关阅读:
    在struct 中使用string,赋值会报错
    添加telnet命令
    can't set blob value on that column
    Floating-point exception
    2014.01.13 今天目标,完结战斗系统中的已知各种细节
    hanframe开微博了
    Educational Codeforces Round 78 (Rated for Div. 2)D(并查集+SET)
    Codeforces Round #604 (Div. 2)D(构造)
    Codeforces Round #608 (Div. 2)D(贪心)
    【PAT甲级】1108 Finding Average (20分)
  • 原文地址:https://www.cnblogs.com/redrainblog/p/4209719.html
Copyright © 2011-2022 走看看