文章目录
1.CEditUI控件
在duilib中,如何引入文本编辑框,实现采用的是CEditUI控件,它实现的是单行文本的输入,继承至CLabelUI控件,XML创建方式如下所示:
//使用范例
<Edit name="okbtn" float="true" pos="16,14,0,0" width="91" height="26" textcolor="#FF000000" />
//属性列表
<Edit parent="Label" notifies="setfocus killfocus timer menu return textchanged windowinit(root)">
<Attribute name="name" default="" type="STRING" comment="控件名字,同一窗口内必须唯一,如(testbtn)"/>
<Attribute name="pos" default="0,0,0,0" type="RECT" comment="位置,如果为float控件则指定位置和大小,否则只指定大小,如(0,0,100,100)"/>
<Attribute name="padding" default="0,0,0,0" type="RECT" comment="外边距,如(2,2,2,2)"/>
<Attribute name="bkcolor" default="0x00000000" type="DWORD" comment="背景颜色,如(0xFFFF0000)"/>
<Attribute name="bkcolor2" default="0x00000000" type="DWORD" comment="背景渐变色2,和bkcolor配合使用,如(0xFFFFFF00)"/>
<Attribute name="bkcolor3" default="0x00000000" type="DWORD" comment="背景渐变色3,和bkcolor、bkcolor2配合使用,如(0xFFFF00FF)"/>
<Attribute name="bordercolor" default="0x00000000" type="DWORD" comment="边框颜色,如(0xFF000000)"/>
<Attribute name="focusbordercolor" default="0x00000000" type="DWORD" comment="获得焦点时边框的颜色,如(0xFFFF0000)"/>
<Attribute name="colorhsl" default="false" type="BOOL" comment="本控件的颜色是否随窗口的hsl变化而变化,如(false)"/>
<Attribute name="bordersize" default="1" type="INT" comment="边框大小,如(1)"/>
<Attribute name="borderround" default="0,0" type="SIZE" comment="边框圆角半径,如(2,2)"/>
<Attribute name="bkimage" default="" type="STRING" comment="背景图片,如(bk.bmp或file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false')"/>
<Attribute name="width" default="0" type="INT" comment="控件预设的宽度,如(100)"/>
<Attribute name="height" default="0" type="INT" comment="控件预设的高度,如(30)"/>
<Attribute name="minwidth" default="0" type="INT" comment="控件的最小宽度,如(100)"/>
<Attribute name="minheight" default="0" type="INT" comment="控件的最小高度,如(30)"/>
<Attribute name="maxwidth" default="9999" type="INT" comment="控件的最大宽度,如(100)"/>
<Attribute name="maxheight" default="9999" type="INT" comment="控件的最大高度,如(30)"/>
<Attribute name="text" default="" type="STRING" comment="显示文本,如(测试文本)"/>
<Attribute name="tooltip" default="" type="STRING" comment="鼠标悬浮提示,如(请在这里输入你的密码)"/>
<Attribute name="userdata" default="" type="STRING" comment="自定义标识"/>
<Attribute name="enabled" default="true" type="BOOL" comment="是否可以响应用户操作,如(true)"/>
<Attribute name="mouse" default="true" type="BOOL" comment="本控件是否可以响应鼠标操作,如(true)"/>
<Attribute name="visible" default="true" type="BOOL" comment="是否可见,如(true)"/>
<Attribute name="float" default="false" type="BOOL" comment="是否使用绝对定位,如(true)"/>
<Attribute name="shortcut" default="" type="CHAR" comment="对应的快捷键,如(P)"/>
<Attribute name="menu" default="false" type="BOOL" comment="是否需要右键菜单,如(true)"/>
<Attribute name="align" default="left" type="STRING" comment="文字对齐方式,取值left、right、center、top、button,如(center)"/>
<Attribute name="endellipsis" default="false" type="BOOL" comment="句末显示不完是否使用...代替,如(true)"/>
<Attribute name="font" default="-1" type="INT" comment="字体id,如(0)"/>
<Attribute name="textcolor" default="0x00000000" type="DWORD" comment="字体颜色,0表示使用默认字体颜色,如(0xFFFF0000)"/>
<Attribute name="disabledtextcolor" default="0x00000000" type="DWORD" comment="disabled字体颜色,0表示使用默认disabled字体颜色,如(0xFFFF0000)"/>
<Attribute name="textpadding" default="0,0,0,0" type="RECT" comment="文字显示的边距,如(2,2,2,2)"/>
<Attribute name="showhtml" default="false" type="BOOL" comment="是否使用类html富文本绘制,如(false)"/>
<Attribute name="readonly" default="false" type="BOOL" comment="是否只读,如(false)"/>
<Attribute name="password" default="false" type="BOOL" comment="是否显示密码字符,如(false)"/>
<Attribute name="maxchar" default="255" type="INT" comment="输入字符最大长度,如(100)"/>
<Attribute name="normalimage" default="" type="STRING" comment="普通状态图片"/>
<Attribute name="hotimage" default="" type="STRING" comment="鼠标悬浮状态图片"/>
<Attribute name="focusedimage" default="" type="STRING" comment="获得焦点状态图片"/>
<Attribute name="disabledimage" default="" type="STRING" comment="禁用状态图片"/>
<Attribute name="nativebkcolor" default="0x00000000" type="DWORD" comment="windows原生edit控件的背景颜色,如(0xFFFFFFFF)"/>
</Edit>
源代码如下所示:
class UILIB_API CEditUI : public CLabelUI
{
DECLARE_DUICONTROL(CEditUI)
friend class CEditWnd;
public:
CEditUI();
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
UINT GetControlFlags() const;
void SetEnabled(bool bEnable = true);
void SetText(LPCTSTR pstrText);
void SetMaxChar(UINT uMax);
UINT GetMaxChar();
void SetReadOnly(bool bReadOnly);
bool IsReadOnly() const;
void SetPasswordMode(bool bPasswordMode);
bool IsPasswordMode() const;
void SetPasswordChar(TCHAR cPasswordChar);
TCHAR GetPasswordChar() const;
void SetNumberOnly(bool bNumberOnly);
bool IsNumberOnly() const;
int GetWindowStyls() const;
LPCTSTR GetNormalImage();
void SetNormalImage(LPCTSTR pStrImage);
LPCTSTR GetHotImage();
void SetHotImage(LPCTSTR pStrImage);
LPCTSTR GetFocusedImage();
void SetFocusedImage(LPCTSTR pStrImage);
LPCTSTR GetDisabledImage();
void SetDisabledImage(LPCTSTR pStrImage);
void SetNativeEditBkColor(DWORD dwBkColor);
DWORD GetNativeEditBkColor() const;
void SetNativeEditTextColor( LPCTSTR pStrColor );
DWORD GetNativeEditTextColor() const;
bool IsAutoSelAll();
void SetAutoSelAll(bool bAutoSelAll);
void SetSel(long nStartChar, long nEndChar);
void SetSelAll();
void SetReplaceSel(LPCTSTR lpszReplace);
void SetTipValue(LPCTSTR pStrTipValue);
LPCTSTR GetTipValue();
void SetTipValueColor(LPCTSTR pStrColor);
DWORD GetTipValueColor();
void SetPos(RECT rc, bool bNeedInvalidate = true);
void Move(SIZE szOffset, bool bNeedInvalidate = true);
void SetVisible(bool bVisible = true);
void SetInternVisible(bool bVisible = true);
SIZE EstimateSize(SIZE szAvailable);
void DoEvent(TEventUI& event);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
void PaintStatusImage(HDC hDC);
void PaintText(HDC hDC);
protected:
CEditWnd* m_pWindow;
UINT m_uMaxChar;
bool m_bReadOnly;
bool m_bPasswordMode;
bool m_bAutoSelAll;
TCHAR m_cPasswordChar;
UINT m_uButtonState;
CDuiString m_sNormalImage;
CDuiString m_sHotImage;
CDuiString m_sFocusedImage;
CDuiString m_sDisabledImage;
CDuiString m_sTipValue;
DWORD m_dwTipValueColor;
DWORD m_dwEditbkColor;
DWORD m_dwEditTextColor;
int m_iWindowStyls;
};
使用win32编辑框的读者,阅读以上代码,会觉得很简单,只是一些常用属性的设置,接着在cpp文件里,有一个动态win32编辑窗口的实现,源代码如下:
class CEditWnd : public CWindowWnd
{
public:
CEditWnd();
void Init(CEditUI* pOwner);
RECT CalPos();
LPCTSTR GetWindowClassName() const;
LPCTSTR GetSuperClassName() const;
void OnFinalMessage(HWND hWnd);
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
protected:
enum {
DEFAULT_TIMERID = 20,
};
CEditUI* m_pOwner;
HBRUSH m_hBkBrush;
bool m_bInit;
bool m_bDrawCaret;
};
LPCTSTR CEditWnd::GetWindowClassName() const
{
return _T("EditWnd");
}
LPCTSTR CEditWnd::GetSuperClassName() const
{
return WC_EDIT;//超类化,扩展系统提供的窗口类
}
LRESULT CEditWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
//if ((HWND)wParam != m_pOwner->GetManager()->GetPaintWindow()) {
// ::SendMessage(m_pOwner->GetManager()->GetPaintWindow(), WM_KILLFOCUS, wParam, lParam);
//}
PostMessage(WM_CLOSE);
return lRes;
}
LRESULT CEditWnd::OnEditChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
if( !m_bInit ) return 0;
if( m_pOwner == NULL ) return 0;
// Copy text back
int cchLen = ::GetWindowTextLength(m_hWnd) + 1;
LPTSTR pstr = static_cast<LPTSTR>(_alloca(cchLen * sizeof(TCHAR)));
ASSERT(pstr);
if( pstr == NULL ) return 0;
::GetWindowText(m_hWnd, pstr, cchLen);
m_pOwner->m_sText = pstr;
m_pOwner->GetManager()->SendNotify(m_pOwner, DUI_MSGTYPE_TEXTCHANGED);
if( m_pOwner->GetManager()->IsLayered() ) m_pOwner->Invalidate();
return 0;
}
编辑窗口在失去焦点时关闭,在文本改变时动态保存。
void CEditUI::DoEvent(TEventUI& event)
{
......
if( event.Type == UIEVENT_SETFOCUS && IsEnabled() )
{
if( m_pWindow ) return;
m_pWindow = new CEditWnd();//聚焦新建窗口
ASSERT(m_pWindow);
m_pWindow->Init(this);
Invalidate();
}
......
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK || event.Type == UIEVENT_RBUTTONDOWN)
{
if( IsEnabled() ) {
GetManager()->ReleaseCapture();
if( IsFocused() && m_pWindow == NULL )
{
//左键按下时动态创建编辑窗口,并选择所有
m_pWindow = new CEditWnd();
ASSERT(m_pWindow);
m_pWindow->Init(this);
if( PtInRect(&m_rcItem, event.ptMouse) )
{
int nSize = GetWindowTextLength(*m_pWindow);
if( nSize == 0 ) nSize = 1;
Edit_SetSel(*m_pWindow, 0, nSize);
}
}
else if( m_pWindow != NULL )
{
if (!m_bAutoSelAll) {
POINT pt = event.ptMouse;
pt.x -= m_rcItem.left + m_rcTextPadding.left;
pt.y -= m_rcItem.top + m_rcTextPadding.top;
Edit_SetSel(*m_pWindow, 0, 0);//取消选择
//编辑框鼠标点击事件
::SendMessage(*m_pWindow, WM_LBUTTONDOWN, event.wParam, MAKELPARAM(pt.x, pt.y));
}
}
}
return;
}
if( event.Type == UIEVENT_MOUSEMOVE )
{
return;
}
if( event.Type == UIEVENT_BUTTONUP )
{
return;
}
if( event.Type == UIEVENT_CONTEXTMENU )
{
return;
}
if( event.Type == UIEVENT_MOUSEENTER )
{
if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
if( IsEnabled() ) {
if( (m_uButtonState & UISTATE_HOT) == 0 ) {
m_uButtonState |= UISTATE_HOT;
Invalidate();
}
}
}
}
if( event.Type == UIEVENT_MOUSELEAVE )
{
if( IsEnabled() ) {
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
}
return;
}
CLabelUI::DoEvent(event);
}
最后一部分是绘制文本,代码如下:
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 sDrawText = GetText();
CDuiString sTipValue = GetTipValue();
if(sDrawText == sTipValue || sDrawText == _T("")) {
mCurTextColor = m_dwTipValueColor;
sDrawText = sTipValue;
}
else {
CDuiString sTemp = sDrawText;
if( m_bPasswordMode ) {//密码模式
sDrawText.Empty();
LPCTSTR pStr = sTemp.GetData();
while( *pStr != _T('\0') ) {
sDrawText += m_cPasswordChar;
pStr = ::CharNext(pStr);
}
}
}
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, sDrawText, mCurTextColor, \
m_iFont, DT_SINGLELINE | m_uTextStyle);
}
else {
CRenderEngine::DrawText(hDC, m_pManager, rc, sDrawText, m_dwDisabledTextColor, \
m_iFont, DT_SINGLELINE | m_uTextStyle);
}
}
2.作者答疑
如有疑问,请留言。