用图标计算 CComboBoxEx 的最大下拉宽度
Posted
技术标签:
【中文标题】用图标计算 CComboBoxEx 的最大下拉宽度【英文标题】:Working out the maximum drop-down width for a CComboBoxEx with icons 【发布时间】:2018-12-10 21:12:50 【问题描述】:我在CodeProject 上看到了这篇关于动态设置CComboBox
的宽度的文章。
但是,我使用的是CComboBoxEx
:
正如您在最后一个条目中看到的那样,它被裁剪了。所以我想自动加宽下拉列表。
需要考虑到它们也是左侧图标的空间。所以这还不够好:
BOOL CMyComboBox::OnCbnDropdown()
// Reset the dropped width
CString str;
CRect rect;
int nWidth = 0;
int nNumEntries = GetCount();;
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject(GetFont());
for (int i = 0; i < nNumEntries; i++)
GetLBText(i, str);
int nLength = dc.GetTextExtent(str).cx;
if (nLength>nWidth)
nWidth = nLength;
nWidth += 2*::GetSystemMetrics(SM_CXEDGE) + 4;
// check if the current height is large enough for the items in the list
GetDroppedControlRect(&rect);
if (rect.Height() <= nNumEntries*GetItemHeight(0))
nWidth +=::GetSystemMetrics(SM_CXVSCROLL);
dc.RestoreDC(nSave);
SetDroppedWidth(nWidth);
return FALSE;
我们如何考虑左侧的图标?
【问题讨论】:
您还应该考虑到COMBOBOXEXITEM::iIndent
— docs.microsoft.com/en-us/windows/desktop/api/commctrl/… — “要为项目显示的缩进空间的数量。每个缩进等于 10 个像素。”
@sergiol 这是一次性计算吗?我查看了链接,但不确定如何调整最终代码。我是否使用GetItem
来获取缩进和文本?也许您可以用附录更新我的答案?
出于完全相同的目的,我想知道同样的事情:***.com/questions/52428007/…。但iIndent
表示图标LEFT 处的间隔。它对于在下拉列表中分层组织项目很有用。
@sergiol 查看我的更新答案。
【参考方案1】:
这是有效的:
void CDatesComboBoxEx::OnCbnDropdown()
CString str;
CRect rect;
int nWidth = 0, nImageWidth = 0;
int nNumEntries = GetCount();
if (nNumEntries > 0)
// Get the width of an image list entry
auto pImageList = GetImageList();
if (pImageList != nullptr && pImageList->GetImageCount() > 0)
IMAGEINFO sInfo;
pImageList->GetImageInfo(0, &sInfo);
nImageWidth = sInfo.rcImage.right - sInfo.rcImage.left;
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject(GetFont());
for (int i = 0; i < nNumEntries; i++)
COMBOBOXEXITEM sItem;
TCHAR szBuffer[_MAX_PATH] = _T("");
sItem.mask = CBEIF_INDENT | CBEIF_TEXT;
sItem.iItem = i;
sItem.cchTextMax = _MAX_PATH;
sItem.pszText = szBuffer;
if (GetItem(&sItem))
int nLength = dc.GetTextExtent(szBuffer).cx + nImageWidth + (sItem.iIndent * 10);
if (nLength > nWidth)
nWidth = nLength;
nWidth += 2 * ::GetSystemMetrics(SM_CXEDGE) + 4;
// check if the current height is large enough for the items in the list
GetDroppedControlRect(&rect);
if (rect.Height() <= nNumEntries * GetItemHeight(0))
nWidth += ::GetSystemMetrics(SM_CXVSCROLL);
dc.RestoreDC(nSave);
SetDroppedWidth(nWidth);
结果:
【讨论】:
以上是关于用图标计算 CComboBoxEx 的最大下拉宽度的主要内容,如果未能解决你的问题,请参考以下文章