完善duilib的List控件显示SHGetFileInfo获得的系统图标

duilib没有支持对系统图标HICON句柄的直接显示,需要修改底层,简单记录一下解决过程

找到Control\UIList.h文件

在对应的控件中添加一个SetIcon函数,我这里需要用的是CListTextElementUI控件,找到CListTextElementUI类,修改为

class DUILIB_API CListTextElementUI : public CListLabelElementUI
{
public:
    CListTextElementUI();
    ~CListTextElementUI();

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

    LPCTSTR GetText(int iIndex) const;
    void SetText(int iIndex, LPCTSTR pstrText);

    void SetOwner(CControlUI* pOwner);
    CDuiString* GetLinkContent(int iIndex);

    void DoEvent(TEventUI& event);
    SIZE EstimateSize(SIZE szAvailable);
    //* 插入图标函数
    //* 参数HICON 通过SHGetFileInfo获得的句柄
    //* 参数width 图标宽度
    //* 参数height 图标高度
    void SetIcon(HICON hIcon, int width, int height);    

    void DrawItemText(HDC hDC, const RECT& rcItem);

protected:
    enum { MAX_LINK = 8 };
    int m_nLinks;
    RECT m_rcLinks[MAX_LINK];
    CDuiString m_sLinks[MAX_LINK];
    int m_nHoverLink;
    IListUI* m_pOwner;
    CDuiPtrArray m_aTexts;

    CDuiString m_sTextLast;

    HICON m_hIcon = NULL;    //保存图标句柄
    int m_icon_width = 0;    //保存图标宽度
    int m_icon_height = 0;    //保存图标高度
};

找到Control\UIList.cpp文件,在最后添加SetIcon函数实现

void CListTextElementUI::SetIcon(HICON hIcon , int width , int height)
{
	m_hIcon = hIcon;
	m_icon_width = width;
	m_icon_height = height;
}

并修改DrawItemText(HDC hDC, const RECT& rcItem)函数

void CListTextElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
{
    if( m_pOwner == NULL ) return;
    TListInfoUI* pInfo = m_pOwner->GetListInfo();
    if (pInfo == NULL) return;
    DWORD iTextColor = pInfo->dwTextColor;

    if( (m_uButtonState & UISTATE_HOT) != 0 ) {
        iTextColor = pInfo->dwHotTextColor;
    }
    if( IsSelected() ) {
        iTextColor = pInfo->dwSelectedTextColor;
    }
    if( !IsEnabled() ) {
        iTextColor = pInfo->dwDisabledTextColor;
    }
    IListCallbackUI* pCallback = m_pOwner->GetTextCallback();

    //此处的if为修改部分。其他都不需要动
    //offset为了使图标居中使用,可以不设置或直接设置为0
    if (m_hIcon)
    {
        int offset = (rcItem.bottom - rcItem.top - m_icon_height) / 2;
        ::DrawIconEx(hDC, rcItem.left + offset, rcItem.top + offset, m_hIcon, m_icon_width, m_icon_height, 0, NULL, DI_NORMAL);
    }

    m_nLinks = 0;
    int nLinks = lengthof(m_rcLinks);
    if (pInfo->nColumns > 0) {
        for( int i = 0; i < pInfo->nColumns; i++ )
        {
            RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom };
            if (pInfo->iVLineSize > 0 && i < pInfo->nColumns - 1) {
                RECT rcLine = { rcItem.right - pInfo->iVLineSize / 2, rcItem.top, rcItem.right - pInfo->iVLineSize / 2, rcItem.bottom};
                CRenderEngine::DrawLine(hDC, rcLine, pInfo->iVLineSize, GetAdjustColor(pInfo->dwVLineColor));
                rcItem.right -= pInfo->iVLineSize;
            }

            rcItem.left += pInfo->rcTextPadding.left;
            rcItem.right -= pInfo->rcTextPadding.right;
            rcItem.top += pInfo->rcTextPadding.top;
            rcItem.bottom -= pInfo->rcTextPadding.bottom;

            CDuiString strText;//不使用LPCTSTR,否则限制太多 by cddjr 2011/10/20
            if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, i);
            else strText.Assign(GetText(i));
            if( pInfo->bShowHtml )
                CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
                &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, pInfo->nFont, pInfo->uTextStyle);
            else
                CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
                pInfo->nFont, pInfo->uTextStyle);

            m_nLinks += nLinks;
            nLinks = lengthof(m_rcLinks) - m_nLinks; 
        }
    }
    else {
        RECT rcItem = m_rcItem;
        rcItem.left += pInfo->rcTextPadding.left;
        rcItem.right -= pInfo->rcTextPadding.right;
        rcItem.top += pInfo->rcTextPadding.top;
        rcItem.bottom -= pInfo->rcTextPadding.bottom;

        CDuiString strText;
        if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, 0);
        else if (m_aTexts.GetSize() > 0) strText.Assign(GetText(0));
        else strText = m_sText;
        if( pInfo->bShowHtml )
            CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
            &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, pInfo->nFont, pInfo->uTextStyle);
        else
            CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
            pInfo->nFont, pInfo->uTextStyle);

        m_nLinks += nLinks;
        nLinks = lengthof(m_rcLinks) - m_nLinks; 
    }

    for( int i = m_nLinks; i < lengthof(m_rcLinks); i++ ) {
        ::ZeroMemory(m_rcLinks + i, sizeof(RECT));
        ((CDuiString*)(m_sLinks + i))->Empty();
    }
}

 将duilib的库重新编译即可使用,使用方法

CListTextElementUI* pLine = new CListTextElementUI;
m_list->Add(pLine);
SHFILEINFO shfi;
SHGetFileInfo(files.at(0).c_str(),
	FILE_ATTRIBUTE_NORMAL,
	&shfi,
	sizeof(shfi),
	SHGFI_ICON | SHGFI_USEFILEATTRIBUTES);

pLine->SetIcon(shfi.hIcon , 20 , 20);//宽度高度都为20
pLine->SetText(1, files.at(0).c_str());
pLine->SetText(2, files.at(1).c_str());
pLine->SetText(3, files.at(2).c_str());

效果图:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值