c++ - 列表框动态改变宽度

标签 c++ c winapi layout win32gui

列表框不会自动调整大小。我们最好的办法是:

SendMessage(my_listbox, LB_SETHORIZONTALEXTENT, 1000, 0);

MS 有用地指出“...列表框不会动态更新其水平范围。”

(为什么不……但我离题了)

如何动态设置宽度以避免截断长度超过 1000px 的消息文本?

最佳答案

如果我理解这个问题...:-)

您实际上需要测量列表框中的所有项目并计算列表框内容的最大宽度,然后调整列表框的宽度。

这是来自 this project 的一些代码(向列表框添加自动水平滚动条)。当字体更改时会调用此代码片段,但它(大致)演示了需要什么:

static void OnSetFont( HWND hwnd, HFONT hFont )
//
//  Font has changed!
//  We need to measure all of our items and reset the horizontal extent of the listbox
{
    CData *pData = reinterpret_cast< CData * >( ::GetProp( hwnd, g_pcszDataProperty ) );

    pData->m_hFont = hFont;

    //
    //  Set up a HDC...
    HDC hdc = GetDC( hwnd );
    HGDIOBJ hOld = SelectObject( hdc, pData->m_hFont );


    //
    //  Record the average width for use as our 'fudge factor' later.
    TEXTMETRIC tm;
    GetTextMetrics( hdc, &tm );
    pData->m_nAvergeCharWidth = tm.tmAveCharWidth;


    pData->m_nMaxWidth = 0;

    //
    //  This is used as our item buffer. Saves us from having to handle the reallocation
    //  for different string lengths
    CArray< TCHAR, TCHAR > arrBuffer;

    //
    //  Quick reference to make the code below read better
    CArray< int, int > &arrWidth = pData->m_arrItemWidth;

    //
    //  The main loop. Iterate over the items, get their text from the listbox and measure
    //  it using our friendly little helper function.
    const UINT uCount = arrWidth.GetSize();
    for( UINT u = 0; u < uCount; u++ )
    {
        const int nLength = ::SendMessage( hwnd, LB_GETTEXTLEN, u, 0 );
        arrBuffer.SetSize( nLength + 1 );
        ::SendMessage( hwnd, LB_GETTEXT, u, (WPARAM)arrBuffer.GetData() );


        const int nItemWidth = BaseMeasureItem( pData, hwnd, hdc, arrBuffer.GetData() );

        pData->m_arrItemWidth.SetAt( u, nItemWidth );
        if( nItemWidth > pData->m_nMaxWidth )
        {
            pData->m_nMaxWidth = nItemWidth;
        }
    }


    //
    //  Now, either set the horizontal extent or not, depending on whether we think we need it.
    if( pData->m_nMaxWidth > pData->m_nClientWidth )
    {
        ::SendMessage( hwnd, LB_SETHORIZONTALEXTENT, pData->m_nMaxWidth + pData->m_nAvergeCharWidth, 0 );
    }
    else
    {
        ::SendMessage( hwnd, LB_SETHORIZONTALEXTENT, 0, 0 );
    }

    //
    //  The usual release of resources.
    SelectObject( hdc, hOld );
    ReleaseDC( hwnd, hdc );
}

还有...

static int BaseMeasureItem( CData *pData, HWND hwnd, HDC hdc, LPCTSTR pcszText )
//
//  Measure and item and adjust the horizontal extent accordingly.
//  Because the HDC is already set up we can just do it.
//  We return the width of the string so our caller can use it.
{
    SIZE size;
    ::GetTextExtentPoint32( hdc, pcszText, _tcslen( pcszText ), &size ); 

    if( size.cx > pData->m_nMaxWidth )
    {

        pData->m_nMaxWidth = size.cx;

        if( pData->m_nMaxWidth > pData->m_nClientWidth )
        {
            ::SendMessage( hwnd, LB_SETHORIZONTALEXTENT, pData->m_nMaxWidth + pData->m_nAvergeCharWidth, 0 );
        }

    }

    return size.cx;
}

关于c++ - 列表框动态改变宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13679277/

相关文章:

c++ - 在 C++ 中创建全局静态的多个实例?

c++ - 获取 lambda 的函数原型(prototype)

c++ - (x+1) > x 如何评估为 0 和 1?

c - 自动与动态内存分配 : what to consider?

python - win32 excel 复制 except 函数

c++ - C++ 中不存在从 "std::wstring"到 "LPWSTR"的合适转换函数

c++ - 成员相互指向的类

c++回调就像在java中一样

c - 如何保证write()将通过套接字传输整个int?

c - struct { ... } 和 struct { union { struct { ... } } } 有什么区别?