转载请说明原出处,谢谢~~: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('\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

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

  1. 扩展duilib edit控件的提示功能和多种文字颜色(解决edit为password显示不正常的bug)

    参考博客:Redrain 转载:http://blog.csdn.net/zhuhongshu/article/details/41786407 在Redrain博客的基础上做了修改 1.CEditU ...

  2. 设置EditText控件中提示消息hint的字体颜色和大小

    设置EditText控件中提示消息hint的字体颜色和大小 1.设置字体大小 代码例: public void init(){ hint= (EditText) findViewById(R.id.i ...

  3. 设置LISTControl控件某一行的背景和文字颜色

    定义宏 用listcontrol的SetItemData设置某一行的属性,通过自定义属性标识实现. 自定义某行内容颜色属性: #define COLOR_DEFAULT 0 //默认颜色 #defin ...

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

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41208207 如果要使用透明异形窗体功能,首先要改进duilib库让他本 ...

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

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41556615 在duilib中,按tab键会让焦点在Button一类的控 ...

  6. 修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式

    Delphi 10.1.2 edit控件在android默认的复制.剪切和粘贴样式太丑,经悟能-DelphiTeacher的提示,用最简单的代码修改后稍有改观. 默认的样式: 修改后的样式: 修改FM ...

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

    原文:重新想象 Windows 8 Store Apps (4) - 控件之提示控件: ProgressRing; 范围控件: ProgressBar, Slider [源码下载] 重新想象 Wind ...

  8. Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件!

    源:Victor 串口 VCL 控件 - 简单实用, 功能强大的 C++ Builder 串口控件! 2014年02月06日发布控件的重要更新版本: Victor 串口控件 1.5.0.2 版本 (包 ...

  9. Delphi在Listview中加入Edit控件

    原帖 : http://www.cnblogs.com/hssbsw/archive/2012/06/03/2533092.html Listview是一个非常有用的控件,我们常常将大量的数据(如数据 ...

随机推荐

  1. iOS:实现MKAnnotation协议,在地图上设置大头针,点击显示具体的位置信息

    如何添加大头针(地标): 通过MapView的addAnnotation方法可以添加一个大头针到地图上 通过MapView的addAnnotations方法可以添加多个大头针到地图上 –(void)a ...

  2. mac 下tomcat启动报错 unknown host

    解决方法:sudo scutil --set HostName localhost

  3. Docker基础技术:DeviceMapper

    在上一篇介绍AUFS的文章中,大家可以看到,Docker的分层镜像是怎么通过UnionFS这种文件系统做到的,但是,因为Docker首选的AUFS并不在Linux的内核主干里,所以,对于非Ubuntu ...

  4. Java基础复习之二:运算符,键盘录入,流程控制语句,if语句,三元运算

    1.运算符 1.1.算术运算符  +(加法有三个用法:加法,正号,字符串连接符)  -  *  /  %  ++  -- 1.1.1./ 是取商,%是取余 1.1.2.++ 与--的用法(a:作用是自 ...

  5. 【USACO】【section1.1】Your Ride Is Here

    以前的账号忘记了,只能从头了. 入门题不解释,就是sumg和sumc初始值置1不能置0.开始享用一个循环计算出sumg和sumc,其实两个数组最大程度为6,节省不了什么时间. /*ID:Moment1 ...

  6. 【Tech】Ganglia安装配置

    基础配置: Hadoop 2.2.0,Hbase 0.96. 四台集群机器,一台master,三台slave. 三台slave上分别装gmond:namenode机器上设置datasource. 客户 ...

  7. IP地址的定义和含义

    IP的定义 ip 是32位无符号整数,最小,最大分别是- 0.0.0.0 - 255.255.255.255 具体来说,由一个ip由 Net-ID+Host-ID 两部分组成,Net-ID 相同,那么 ...

  8. 如何通过session控制单点登录

    web服务器为每一个浏览器实例对应一个session.这个session有自己的一个独立id,这个id保存在浏览器的cookie中(这个cookie貌似随着这个浏览器实例的关闭而清除),访问web服务 ...

  9. Objective-C编码规范:26个方面解决iOS开发问题

    介绍 我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致.即使我们有很多不同的作者来完成不同的书籍. 这里编码规范有可能与你看到的其他Object ...

  10. OracleApps 什么是Back to Back Order?

    什么是Back to Back Order? 简单的说,B2B是我们从供应商那拿货,然后收到货后,再发运给客户.. B2B Flow B2B的例子 1.Item的定义 Item Should be c ...