第二章 第九小节Duilib中的CComboUI控件-下拉列表控件

1.CComboUI控件

  在界面开发中,非常常用的一种界面控件是下拉列表控件,xml创建方式如下所示:

//使用范例
<Combo name="accountcombo" float="true" pos="30,35,90,55"  textpadding="1,1,1,1" >
	<ListLabelElement text="张三" selected="true" />
	<ListLabelElement text="李四" />
</Combo>
//属性列表
<Combo parent="Container" notifies="setfocus killfocus timer menu dropdown itemselect 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="mousechild" 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="inset" default="0,0,0,0" type="RECT" comment="容器的内边距,如(2,2,2,2)"/>
		<Attribute name="vscrollbar" default="false" type="BOOL" comment="是否使用竖向滚动条,如(true)"/>
		<Attribute name="hscrollbar" default="false" type="BOOL" comment="是否使用横向滚动条,如(true)"/>
		<Attribute name="childpadding" default="0" type="INT" comment="子控件之间的额外距离,如(4)"/>
		<Attribute name="textpadding" default="0,0,0,0" type="RECT" comment="文字显示的边距,如(2,2,2,2)"/>
		<Attribute name="normalimage" default="" type="STRING" comment="普通状态图片"/>
		<Attribute name="hotimage" default="" type="STRING" comment="鼠标悬浮的状态图片"/>
		<Attribute name="pushedimage" default="" type="STRING" comment="鼠标按下的状态图片"/>
		<Attribute name="focusedimage" default="" type="STRING" comment="获得焦点时的状态图片"/>
		<Attribute name="disabledimage" default="" type="STRING" comment="禁用的状态图片"/>
		<Attribute name="dropboxsize" default="0,150" type="STRING" comment="弹出框大小设置"/>
		<Attribute name="itemfont" default="-1" type="INT" comment="item的字体id,如(0)"/>
		<Attribute name="itemalign" default="center" type="STRING" comment="item对齐方式,取值left、right、center,如(center)"/>
		<Attribute name="itemendellipsis" default="false" type="BOOL" comment="item句末显示不全是否使用...代替,如(true)"/>
		<Attribute name="itemtextpadding" default="0,0,0,0" type="RECT" comment="item文字显示的边距,如(2,2,2,2)"/>
		<Attribute name="itemtextcolor" default="0xFF000000" type="DWORD" comment="item字体颜色"/>
		<Attribute name="itembkcolor" default="0x00000000" type="DWORD" comment="item背景颜色"/>
		<Attribute name="itembkimage" default="" type="STRING" comment="item背景图片"/>
		<Attribute name="itemaltbk" default="false" type="BOOL" comment="item是否使用隔行交替背景"/>
		<Attribute name="itemselectedtextcolor" default="0xFF000000" type="DWORD" comment="item被选中时的字体颜色"/>
		<Attribute name="itemselectedbkcolor" default="0xFFC1E3FF" type="DWORD" comment="item被选中时的背景颜色"/>
		<Attribute name="itemselectedimage" default="" type="STRING" comment="item被选中时的背景图片"/>
		<Attribute name="itemhottextcolor" default="0xFF000000" type="DWORD" comment="item鼠标悬浮时的字体颜色"/>
		<Attribute name="itemhotbkcolor" default="0xFFE9F5FF" type="DWORD" comment="item鼠标悬浮时的背景颜色"/>
		<Attribute name="itemhotimage" default="" type="STRING" comment="item鼠标悬浮时的背景图片"/>
		<Attribute name="itemdisabledtextcolor" default="0xFFCCCCCC" type="DWORD" comment="item禁用时的字体颜色"/>
		<Attribute name="itemdisabledbkcolor" default="0xFFFFFFFF" type="DWORD" comment="item禁用时的背景颜色"/>
		<Attribute name="itemdisabledimage" default="" type="STRING" comment="item禁用时的背景图片"/>
		<Attribute name="itemlinecolor" default="0x00000000" type="DWORD" comment="item行分割线颜色"/>
		<Attribute name="itemshowhtml" default="false" type="BOOL" comment="item是否使用类html富文本绘制,如(false)"/>
		<Attribute name="multiexpanding" default="false" type="BOOL" comment="是否支持多个item同时打开,如(false)"/>
	</Combo>

  接下来分析它的源代码,它继承至CContainerUI,实现了IListOwnerUI接口,头文件如下所示:

class UILIB_API CComboUI : public CContainerUI, public IListOwnerUI
    {
        DECLARE_DUICONTROL(CComboUI)
        friend class CComboWnd;
    public:
        CComboUI();

        LPCTSTR GetClass() const;
        LPVOID GetInterface(LPCTSTR pstrName);

        void DoInit();
        UINT GetControlFlags() const;

        CDuiString GetText() const;
        void SetEnabled(bool bEnable = true);

        void SetTextStyle(UINT uStyle);
        UINT GetTextStyle() const;
        void SetTextColor(DWORD dwTextColor);
        DWORD GetTextColor() const;
        void SetDisabledTextColor(DWORD dwTextColor);
        DWORD GetDisabledTextColor() const;
        void SetFont(int index);
        int GetFont() const;
        RECT GetTextPadding() const;
        void SetTextPadding(RECT rc);
        bool IsShowHtml();
        void SetShowHtml(bool bShowHtml = true);
        bool IsShowShadow();
        void SetShowShadow(bool bShow = true);

        CDuiString GetDropBoxAttributeList();
        void SetDropBoxAttributeList(LPCTSTR pstrList);
        SIZE GetDropBoxSize() const;
        void SetDropBoxSize(SIZE szDropBox);

        UINT GetListType();
        TListInfoUI* GetListInfo();
        int GetCurSel() const;  
        bool SelectItem(int iIndex, bool bTakeFocus = false);
        bool SelectMultiItem(int iIndex, bool bTakeFocus = false);
        bool UnSelectItem(int iIndex, bool bOthers = false);
        bool SetItemIndex(CControlUI* pControl, int iIndex);

        bool Add(CControlUI* pControl);
        bool AddAt(CControlUI* pControl, int iIndex);
        bool Remove(CControlUI* pControl);
        bool RemoveAt(int iIndex);
        void RemoveAll();

        bool Activate();

        LPCTSTR GetNormalImage() const;
        void SetNormalImage(LPCTSTR pStrImage);
        LPCTSTR GetHotImage() const;
        void SetHotImage(LPCTSTR pStrImage);
        LPCTSTR GetPushedImage() const;
        void SetPushedImage(LPCTSTR pStrImage);
        LPCTSTR GetFocusedImage() const;
        void SetFocusedImage(LPCTSTR pStrImage);
        LPCTSTR GetDisabledImage() const;
        void SetDisabledImage(LPCTSTR pStrImage);

        bool GetScrollSelect();
        void SetScrollSelect(bool bScrollSelect);

        void SetItemFont(int index);
        void SetItemTextStyle(UINT uStyle);
        RECT GetItemTextPadding() const;
        void SetItemTextPadding(RECT rc);
        DWORD GetItemTextColor() const;
        void SetItemTextColor(DWORD dwTextColor);
        DWORD GetItemBkColor() const;
        void SetItemBkColor(DWORD dwBkColor);
        LPCTSTR GetItemBkImage() const;
        void SetItemBkImage(LPCTSTR pStrImage);
        bool IsAlternateBk() const;
        void SetAlternateBk(bool bAlternateBk);
        DWORD GetSelectedItemTextColor() const;
        void SetSelectedItemTextColor(DWORD dwTextColor);
        DWORD GetSelectedItemBkColor() const;
        void SetSelectedItemBkColor(DWORD dwBkColor);
        LPCTSTR GetSelectedItemImage() const;
        void SetSelectedItemImage(LPCTSTR pStrImage);
        DWORD GetHotItemTextColor() const;
        void SetHotItemTextColor(DWORD dwTextColor);
        DWORD GetHotItemBkColor() const;
        void SetHotItemBkColor(DWORD dwBkColor);
        LPCTSTR GetHotItemImage() const;
        void SetHotItemImage(LPCTSTR pStrImage);
        DWORD GetDisabledItemTextColor() const;
        void SetDisabledItemTextColor(DWORD dwTextColor);
        DWORD GetDisabledItemBkColor() const;
        void SetDisabledItemBkColor(DWORD dwBkColor);
        LPCTSTR GetDisabledItemImage() const;
        void SetDisabledItemImage(LPCTSTR pStrImage);
        DWORD GetItemLineColor() const;
        void SetItemLineColor(DWORD dwLineColor);
        bool IsItemShowHtml();
        void SetItemShowHtml(bool bShowHtml = true);

        SIZE EstimateSize(SIZE szAvailable);
        void SetPos(RECT rc, bool bNeedInvalidate = true);
        void Move(SIZE szOffset, bool bNeedInvalidate = true);
        void DoEvent(TEventUI& event);
        void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

        bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
        void PaintText(HDC hDC);
        void PaintStatusImage(HDC hDC);

    protected:
        CComboWnd* m_pWindow;

        int m_iCurSel;
        DWORD    m_dwTextColor;
        DWORD    m_dwDisabledTextColor;
        int        m_iFont;
        UINT    m_uTextStyle;
        RECT    m_rcTextPadding;
        bool    m_bShowHtml;
        bool    m_bShowShadow;
        CDuiString m_sDropBoxAttributes;
        SIZE m_szDropBox;
        UINT m_uButtonState;

        CDuiString m_sNormalImage;
        CDuiString m_sHotImage;
        CDuiString m_sPushedImage;
        CDuiString m_sFocusedImage;
        CDuiString m_sDisabledImage;

        bool m_bScrollSelect;
        TListInfoUI m_ListInfo;
    };

  查看它两个关键函数DoEvent函数和DoPaint函数,DoEvent函数代码如下所示:

 void CComboUI::DoEvent(TEventUI& event)
    {
        if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
            if( m_pParent != NULL ) m_pParent->DoEvent(event);
            else CContainerUI::DoEvent(event);
            return;
        }

        if( event.Type == UIEVENT_SETFOCUS ) 
        {
            Invalidate();
        }
        if( event.Type == UIEVENT_KILLFOCUS ) 
        {
            Invalidate();
        }
        if( event.Type == UIEVENT_BUTTONDOWN )
        {
            if( IsEnabled() ) {
                Activate();//激活下拉列表,并创建窗口
                m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;
            }
            return;
        }
        if( event.Type == UIEVENT_BUTTONUP )
        {
            if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
                m_uButtonState &= ~ UISTATE_CAPTURED;
                Invalidate();
            }
            return;
        }
        if( event.Type == UIEVENT_MOUSEMOVE )
        {
            return;
        }
        if( event.Type == UIEVENT_KEYDOWN )
        {
            switch( event.chKey ) {
            case VK_F4:
                Activate();
                return;
            case VK_UP:
                SelectItem(FindSelectable(m_iCurSel - 1, false));
                return;
            case VK_DOWN:
                SelectItem(FindSelectable(m_iCurSel + 1, true));
                return;
            case VK_PRIOR:
                SelectItem(FindSelectable(m_iCurSel - 1, false));
                return;
            case VK_NEXT:
                SelectItem(FindSelectable(m_iCurSel + 1, true));
                return;
            case VK_HOME:
                SelectItem(FindSelectable(0, false));
                return;
            case VK_END:
                SelectItem(FindSelectable(GetCount() - 1, true));
                return;
            }
        }
        if( event.Type == UIEVENT_SCROLLWHEEL )
        {
            if(GetScrollSelect()) {
                bool bDownward = LOWORD(event.wParam) == SB_LINEDOWN;
                SelectItem(FindSelectable(m_iCurSel + (bDownward ? 1 : -1), bDownward));
            }
            return;
        }
        if( event.Type == UIEVENT_CONTEXTMENU )
        {
            return;
        }
        if( event.Type == UIEVENT_MOUSEENTER )
        {
            if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
                if( (m_uButtonState & UISTATE_HOT) == 0  )
                    m_uButtonState |= UISTATE_HOT;
                Invalidate();
            }
            return;
        }
        if( event.Type == UIEVENT_MOUSELEAVE )
        {
            if( (m_uButtonState & UISTATE_HOT) != 0 ) {
                m_uButtonState &= ~UISTATE_HOT;
                Invalidate();
            }
            return;
        }
        CControlUI::DoEvent(event);
    }
    
	bool CComboUI::Activate()
    {
        if( !CControlUI::Activate() ) return false;
        if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_PREDROPDOWN);
        if( m_pWindow ) return true;
        m_pWindow = new CComboWnd();//临时生成窗口显示文本
        ASSERT(m_pWindow);
        m_pWindow->Init(this);
        if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_DROPDOWN);
        Invalidate();
        return true;
    }

  DoPaint函数代码如下所示:

	bool CComboUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
    {
        return CControlUI::DoPaint(hDC, rcPaint, pStopControl);
    }

  下拉列表控件是列表控件的一种,使用频率也是比较高,而真正的下拉列表控件种类还是比较多的,在第三章的范例里再进行详细的讲解,这一部分使读者对代码有一定程度的熟悉。

2.作者答疑


  如有疑问,请留言。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值