Просто небольшой совет: если вы собираетесь добавить много элементов в ListBox или ComboBox, то есть несколько небольших трюков, которые вы можете сделать для существенного ускорения этой операции (заметьте: улучшения будут работать, если вы хотите добавить действительно МНОГО элементов. Конечно же, юзабилити ListBox-а с сотней элементов может быть низка, но я предполагаю, что у вас на это есть действительно хорошая причина).
Во-первых, вы можете отключить перерисовку, пока вы добавляете элементы (вообще-то, это работает для любых элементов управления):
SetWindowRedraw(Handle, FALSE);Это подавит обновление контрола при каждом добавлении нового элемента (*). Но есть и ещё кое-что, что можно сделать:
try
... добавляем элементы ...
finally
SetWindowRedraw(Handle, True);
InvalidateRect(Handle, nil, True);
end;
SendMessage(hwndCombo, CB_INITSTORAGE, cItems, cbStrings);cItems - это число элементов, которые вы собираетесь добавить, а cbStrings это суммарное кол-во памяти (в байтах), необходимое для хранения всех строк, что вы хотите вставить.
// для ListBox используйте LB_INITSTORAGE
... добавляем элементы ...
Ничего страшного, если эти значения будут не точны. Если вы укажите слишком маленькие значения, тогда в процессе добавлении элементов будет несколько перераспределений памяти для доп. элементов. Если вы укажите слишком большие значения, то часть памяти хотя будет размещена, но не будет использоваться.
Некоторые люди рекомендуют использовать LockWindowUpdate, но это неверно. LockWindowUpdate отключает перерисовку в окне, которое вы ей указываете, но она не предназначена для подавления мигания в процессе обновления контролов.
Очевидное ограничение LockWindowUpdate: только одно окно может быть заблокировано в каждый момент времени. Так что, если два окна попытаются одновременно использовать трюк с LockWindowUpdate, то получится это только у одного из них. Это не слишком-то надёжно, не так ли?
LockWindowUpdate была спроектирована, чтобы помогать при перерисовке во время операций drag/drop. Если вы рисуете курсор для операции drag/drop, вы не хотите, чтобы окно под курсором начало рисоваться (и портить ваш прекрасный курсор). Поэтому вы блокируете перерисовку окна, пока вы рисуете курсор и разблокируете его, когда курсор покидает окно.
Вот почему может быть только одно заблокированное окно: в каждый момент времени может быть только одна drag/drop операция, потому что у нас есть только одна мышь.
Примечания переводчика:
(*) В Delphi, если вы используете VCL, то эта функциональность уже заключена в базовые классы. Делается это так:
ListBox.Items.BeginUpdate;
try
... добавляем элементы ...
finally
ListBox.Items.EndUpdate;
end;
👍
ОтветитьУдалить