How to resize a Win32 listbox to fit its content?

爱⌒轻易说出口 提交于 2020-07-10 17:41:29

问题


Is there any way to resize a Win32 listbox to fit its content (the minimum size that will show all its content, not needing a scrollbar), whenever its items change?

Thank!

Edit: I need resize both width and height of listbox.


回答1:


You didn't specify whether you wanted horizontal as well as vertical, but I'm going to assume not. Basically, you need to get the number of items and the item height and multiply them, then add on the space for the control borders (unless the control is borderless, you may need to play around with this):

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);
}

If you want horizontal sizing as well you would need to select the right font into a DC, and loop through all the items to calculate the maximum text length using GetTextExtentPoint32.

EDIT: Added a version that calculates horizontal size as well.

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);
}


来源:https://stackoverflow.com/questions/29039075/how-to-resize-a-win32-listbox-to-fit-its-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!