Как максимально быстро загрузить большой массив строк в поле со списком MFC?

У меня есть массив из 1000 строк для загрузки в поле со списком. Каков самый быстрый способ загрузить массив строк в поле со списком?

Есть ли какой-то другой способ, кроме как перебирать список строк, помещая каждую строку в поле со списком по одной?

И как скопировать данные поля со списком после загрузки в 10 других полей со списком?


person yesraaj    schedule 23.10.2008    source источник


Ответы (5)


Если у вас есть 1000 строк, повторяющихся в 10 полях со списком, вы можете рассмотреть возможность использования поля со списком, нарисованного владельцем, которое рисует строки на лету на основе индексов в вашем массиве, а не сохраняет их в поле со списком вообще. Намного быстрее, намного эффективнее памяти. Ознакомьтесь с методом DrawItem и структурой DRAWITEMSTRUCT в интерактивной справке. По сути, вы должны сделать что-то вроде использования InitStorage и InsertString (как упоминалось NuSonic), чтобы создать 1000 пустых элементов в вашем списке и переопределить DrawItem для извлечения и рисования необходимой строки на основе индекса по мере необходимости.

person SmacL    schedule 23.10.2008
comment
Это боль, но это быстрый способ... +1 - person Aardvark; 23.10.2008
comment
Это сделает работу.. Я бы не подумал об этом. Браво - person baash05; 07.12.2008
comment
У меня та же проблема - у меня 256 полей со списком, в каждом из которых мне нужно заполнить 10 элементов. Каждое поле со списком заполняется за 2-3 мс. Я делаю все, что было предложено выше - действительно ли нужно 2-3 мс, чтобы вставить 16 пустых элементов в поле со списком? - person Tom Davies; 29.03.2017
comment
Не уверен, сколько времени это займет, но производительность большей части MFC может быть ужасной. Возможный обходной путь — расширить область действия ваших 256 полей со списком, чтобы они были либо глобальными, либо частью класса, который сохраняется дольше, чтобы они не инициализировались и не удалялись так часто. - person SmacL; 30.03.2017
comment
Старый поток (каламбур), но если вы загружаете 256 уникальных полей со списком, тогда может помочь многопоточность, если у вас есть кодовая база, безопасная для потоков. - person Mitchell Bland; 19.08.2019

Я не знаю ни одного способа атомарной загрузки нескольких строк, но есть пара вещей, которые вы можете сделать, чтобы сделать процесс более эффективным:

  • Вызов CComboBox::InitStorage перед добавлением элементов для предварительного выделения памяти
  • Используйте InsertString вместо AddString, чтобы предотвратить запуск сортировки при каждом добавлении (при условии, что стиль CBS_SORT включен)
person Stu Mackellar    schedule 23.10.2008


Я рассмотрю возможность использования списка выбора вместо поля со списком для повышения производительности.

Общее эмпирическое правило для повышения производительности при вставке большого количества элементов в список пользовательского интерфейса заключается в том, чтобы вызывать перед вставкой и возвращать значение true после.

Вот правильный синтаксис

#define NB_ITEM 1000
#define ITEM_LENGTH 10

void CMFCComboDlg::InitMyCombo()
{
    CString _strData;
    m_cbMyCombo.SetRedraw( FALSE );

    m_cbMyCombo.Clear();

    m_cbMyCombo.InitStorage(NB_ITEM, ITEM_LENGTH); 

    for( int i = 0; i < NB_ITEM; i++ )
    {
        _strData.Format( L"Test %ld", i );
        m_cbMyCombo.InsertString( i, _strData );
    }

    m_cbMyCombo.SetCurSel(0);

    m_cbMyCombo.SetRedraw( TRUE );
}

РЕДАКТИРОВАТЬ: улучшите решение, чтобы включить предложение smacl

person Hapkido    schedule 23.10.2008
comment
Этот вопрос конкретно относится к МФЦ, у которого нет такого механизма. - person Stu Mackellar; 23.10.2008
comment
@nusonic - да, CWnd::SetRedraw (или WM_SETREDRAW). Что на самом деле является хорошим предложением. Жаль, что Hapkido говорит на другом языке, а не на Win32/MFC (в любом случае, что это за список выбора?) - person Aardvark; 23.10.2008
comment
Список выбора — это своего рода диалоговое окно поиска, оптимизированное для быстрого получения нужных данных. Просмотр более тысячи записей действительно неэффективен. - person Hapkido; 24.10.2008
comment
@Hapkido, простой мод для улучшения кода выше — добавить m_cbMyCombo.InitStorage(1000,10000); после SetRedraw согласился, что 1000 элементов слишком много для поля со списком, и альтернативный пользовательский интерфейс был бы хорошей идеей. - person SmacL; 24.10.2008
comment
InitStorage — хорошее предложение, я включил его в свое решение. Однако синтаксис такой: int InitStorage(int nNbItems, UINT nBytesPerItem); - person Hapkido; 24.10.2008
comment
Я присоединюсь к вызову функции SetRedraw. Даже для небольших списков со списком (40 элементов) имеет значение, если вы отключите перерисовку перед обновлением списка. - person bsruth; 27.01.2009

У меня была эта проблема, и я решил ее двумя способами, в зависимости от # элементов. Настройка «не рисовать» и «инициализировать хранилище» не имела для меня никакого значения. Сделать так, чтобы владелец нарисовал один, также жизнеспособно, но у меня было множество полей со списком. Предполагая фиксированный список для каждого поля со списком, который не меняет содержимое, список устанавливается один раз.

Очень большие # Элементы: Поле со списком сделано простым/отключенным с помощью SetWindowText для установки исходной строки, а маленькая кнопка рядом с ним открывает диалоговое окно, позволяющее выбрать элемент из списка в режиме отчета для данных, которые будут я был в поле со списком (может быть что-нибудь сделать в диалоговом окне).

Умеренное количество элементов: создан собственный производный класс со списком, который переопределяет AddString, SelectString и обрабатывает OnDropDown. Когда вы добавляете элементы, он помещает их во временный вектор, а затем в SelectString (также можно выполнить переопределение SetCurSel) добавляет один элемент, который он находит и выбирает. При выпадании он сбрасывает поле со списком, добавляет все элементы и выбирает выбранный в данный момент. При сбросе выпадающего списка есть небольшое замедление, но при небольшом количестве элементов это не заметно.

Это заставило мои диалоги загружаться намного быстрее и по-прежнему полностью функционировать без рисования владельца.

person Mary Ellen Bench    schedule 10.11.2017