Listbox изменяет ширину динамически

Списки не меняются автоматически. Лучшее, что у нас есть:

SendMessage(my_listbox, LB_SETHORIZONTALEXTENT, 1000, 0);

MS услужливо отмечает, что «… окно списка не обновляет свой горизонтальный экстент динамически».

(почему, черт возьми, нет … но я отвлекся)

Как можно установить ширину динамически, чтобы избежать усечения текста сообщения длиннее 1000 пикселей?

0

Решение

если я понимаю вопрос … 🙂

По сути, вам нужно измерить все элементы в списке и вычислить максимальную ширину содержимого списка, а затем настроить ширину списка.

Вот код из этот проект (это добавляет автоматическую горизонтальную полосу прокрутки к спискам). Этот фрагмент вызывается при изменении шрифта, но он демонстрирует (примерно), что необходимо:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]