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());
效果图: