第二章 第六小节Duilib中的CEditUI控件-简单编辑框

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.作者答疑


  如有疑问,请留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值