有没有办法调整Win32列表框的大小以适应其内容(显示其所有内容的最小大小,不需要滚动条),只要其项目发生变化?
感谢!
编辑:我需要调整列表框的宽度和高度。
答案 0 :(得分:3)
你没有说明你是想要水平还是垂直,但我不会假设。基本上,你需要获取项目的数量和项目的高度和多个,然后添加控件边框的空间(除非控件是无边框的,你可能需要玩这个):
void AutosizeListBox(HWND hWndLB)
{
int iItemHeight = SendMessage(hWndLB, LB_GETITEMHEIGHT, 0, 0);
int iItemCount = SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
// calculate new desired client size
RECT rc;
GetClientRect(hWndLB, &rc);
rc.bottom = rc.top + iItemHeight * iItemCount;
// grow for borders
rc.right += GetSystemMetrics(SM_CXEDGE) * 2;
rc.bottom += GetSystemMetrics(SM_CXEDGE) * 2;
// resize
SetWindowPos(hWndLB, 0, 0, 0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
如果您还需要水平大小调整,则需要在DC中选择正确的字体,并使用GetTextExtentPoint32
遍历所有项目以计算最大文本长度。
编辑:添加了一个计算水平尺寸的版本。
void AutosizeListBox(HWND hWndLB)
{
int iItemHeight = SendMessage(hWndLB, LB_GETITEMHEIGHT, 0, 0);
int iItemCount = SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
// get a DC and set up the font
HDC hDC = GetDC(hWndLB);
HGDIOBJ hOldFont = SelectObject(hDC, (HGDIOBJ)SendMessage(hWndLB, WM_GETFONT, 0, 0));
// calculate width of largest string
int iItemWidth = 0;
for (int i = 0; i < iItemCount; i++)
{
int iLen = SendMessage(hWndLB, LB_GETTEXTLEN, i, 0);
TCHAR* pBuf = new TCHAR[iLen + 1];
SendMessage(hWndLB, LB_GETTEXT, i, (LPARAM)pBuf);
SIZE sz;
GetTextExtentPoint32(hDC, pBuf, iLen, &sz);
if (iItemWidth < sz.cx) iItemWidth = sz.cx;
delete[] pBuf;
}
SelectObject(hDC, hOldFont);
ReleaseDC(hWndLB, hDC);
// calculate new desired client size
RECT rc;
SetRect(&rc, 0, 0, iItemWidth, iItemHeight * iItemCount);
// grow for borders
rc.right += GetSystemMetrics(SM_CXEDGE) * 2;
rc.bottom += GetSystemMetrics(SM_CXEDGE) * 2;
// resize
SetWindowPos(hWndLB, 0, 0, 0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}