增加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( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();

		CDuiString sText;
		if(GetText() == m_sTipValue || GetText() == _T(""))
		{
			mCurTextColor = m_dwTipValueColor;
			sText = m_sTipValue;
		}
		else
		{
			sText = m_sText;

			if( m_bPasswordMode ) {
				sText.Empty();
				LPCTSTR p = m_sText.GetData();
				while( *p != _T('\0') ) {
					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

时间: 2024-07-28 18:41:39

增加duilib edit控件的提示功能和多种文字颜色的相关文章

改进duilib的richedit控件的部分功能

转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41208207       如果要使用透明异形窗体功能,首先要改进duilib库让他本身支持(可以下载duilib扩展群群主改进的库,或者下载我的库),然后要开启窗体的bktrans属性.这时只要使用透明的背景素材就能做出透明异形窗体.但是透明窗体并不好驾驭,会带来很多麻烦.其中之一就是原Edit控件无法使用,这时改用Richedit控件是不错的选择.       Ric

由于功能要求,需要在treeview里第三级多增加一列(相当于在第三级增加一个Label控件以显示信息所用

问题描述 asp.net由于功能要求,需要在treeview里第三级多增加一列(相当于在第三级增加一个Label控件以显示信息所用,怎么样才能实现?希各位不吝赐教! 解决方案 解决方案二:该回复于2008-03-16 10:34:01被版主删除解决方案三:支持搂主,收藏

修复duilib CEditUI控件和CWebBrowserUI控件中按Tab键无法切换焦点的bug

转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41556615         在duilib中,按tab键会让焦点在Button一类的控件中切换,但是切换焦点一直存在bug,具体的描述如下:         1.在主窗体里弹出新的窗体,当新窗体中存在CEditUI控件并且焦点在此CEditUI控件上,那么按tab键将无法切换焦点而一直处于CEditUI中.(只在新窗体中有此bug,主创体中没有,原因会在后面分析)  

C++Builder中实现控件数组的功能

Borland C++ Builder作为Inprise(原Borland)公司新推出的快速应用程序开发工具(RAD),具有威力强大的C++语言和快捷便利的可视化编程完美结合的优点,遗憾的是其没有直接提供像VB中的控件数组的功能,需要开发者自己编程实现. VB中的一个控件数组可以 允许多个控件共享同一个事件句柄 提供了运行期间增加一个控件的机制 提供了一种方便的组合控件的方法. 前两项在C++ Builder中早已实现,而且CB更有一个优点.即不同类型的控件可以使用相同的句柄(只需在相关控件的O

ASP.NET:优化DataGrid控件的编辑功能

asp.net|datagrid|datagrid控件|优化 尽管在上面的实例中我们已经实现了DataGrid的在线编辑功能,但是,如果我们已经习惯了C/S 结构的程序,就会感觉到上个实例中编辑的不足:提交数据频繁,加重了服务器的负担.在这一节中,我们利用一个实例来演示优化后的DataGrid控件的编辑功能,其中的技术就是引入批量更新数据.引入的一个新知识就是控件的FindControl方法.     我们来看具体实例.首先在DataCon Web项目里,添加一个Web Form,命名为Data

VC增强Edit控件为日期输入控件

MFC所提供的组件已经可以完成很多功能了,但有时候我们还需要这些控件按我们自己的意图去处理.比如EDIT控件,虽然我们可以设置EDIT控件为只能接受数字属性,但如果我们还需要它可以接收数字意外的字符,比如需要控件只能接收"2004-02-20"这样的格式的日期字符呢?我们需要自己在WM_CHAR消息里面来处理输入的字符.可是,当输入字符后,Windows会向Edit控件发送WM_CHAR消息,应用程序会调用Windows默认的Edit控件窗口处理函数WndProc来处理该控件.这时我们

重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider

原文:重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider [源码下载] 重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之提示控件 ProgressRing - 进度圈控件 重新想象 Windows

想实现一个ascx控件masterpage的功能,不知道有没有现成方案否?

问题描述 asp.net2.0最早的测试版,无论是控件和页面都具有masterpage功能,但是正式版出来后,控件的masterpage功能就没有,等到了3.5出来,ascx控件还是没有masterpage功能,不知道大家是否和我有同样的需求,一起交流一下! 解决方案 解决方案二:ding解决方案三:没明白解决方案四:不会吧,就是ascx控件也想增加模板功能!解决方案五:再顶!

ASP.NET:DataGrid控件的分页功能

asp.net|datagrid|datagrid控件|分页 DataGrid 控件是一个基于模板样式的.多功能的.多列的数据绑定控件.在三个数据绑定控件中,DataGrid是功能最为强大的,其次时DataList控件,然后是轻量级的数据绑定控件Repeater.要自定义 DataGrid 中各列的布局,您可以将列类型设置为"模板",然后修改列的模板.DataGrid 控件也可以无需模板,只需按照默认的设置即可进行呈现,这使得该控件成了用于报告方案的理想控件.      我们可以把Da