Если ваше окно не имеет обработчика для сообщения
WM_SETREDRAW
, то DefWindowProc
даст вам поведение по умолчанию, которое подавляет сообщения WM_PAINT
для вашего окна, пока перерисовка отключена, и начинает пропускать WM_PAINT
(плюс вызывает полное обновление), когда перерисовка снова включается (внутренне это реализуется, делая окно псевдо-невидимым, но это деталь реализации, на которую вам не нужно ориентироваться).Хотя реализация по умолчанию работает отлично для простых элементов управления, более сложные элементы управления могут делать эту работу и лучше - и, вообще-то, они должны делать лучше, ибо в этом и заключается смысл WM_SETREDRAW.
Предполагаемое использование отключение перерисовки окна заключается в выполнении пакета действий над окном за раз, когда вы не хотите тратить время на обновление окна после каждого мельчайшего изменения, поскольку оно тут же устареет. К примеру, если вы хотите добавить сотню элементов в ListBox, то вы не хотите выполнять при этом 100 перерисовок экрана, если вам достаточно только одной. Возможно, вы видели программы, которые забывают заблокировать перерисовку в такие моменты: приложение замирает, кроме этого ListBox-а, кнопка (thumb) прокрутки которого медленно уменьшается по мере заполнения списка.
Я скажу, что операции подобного плана и есть цель
WM_SETREDRAW
для сложного элемента управления, потому что если у вас есть простой элемент управления (вроде кнопки), то существует не много таких операций, которые вы можете сделать с кнопкой, так что в блокировке перерисовки кнопки есть не много смысла.Например, ListView имеет свой обработчик
WM_SETREDRAW
, который устанавливает флаг "обновление отключено". Другой код ListView проверяет этот флаг и пропускает сложные вычисления. К примеру, когда вы добавляете новый элемент в список, то ListView не пересчитывает размеры и положение полосы прокрутки, если его перерисовка отключена; он просто устанавливает внутренний флаг "Когда перерисовку включат - надо пересчитать полосу прокрутки". Если ListView находится в режиме автоупорядочивания, то он не тратит время на вычисление новых позиций элементов при удалении или добавлении; он просто устанавливает аналогичный внутренний флаг. А когда наконец вы включаете перерисовку обратно, то обработчик WM_SETREDRAW
видит эти флаги-напоминания и говорит: "OK, давайте разберёмся со всем этим". Таким образом, если вы добавляете 100 элементов, то вы не выполняете 99 бесполезных вычислений положения полосы прокрутки и 99 бесполезных вычислений положений элементов. Поскольку некоторые из подобных операций имеют стоимость O(n), то откладывая их, вы улучшаете производительность вставки с O(n²) до O(n).Мораль истории: если у вас есть элемент управления, который управляет большим количеством элементов, то вам лучше бы иметь обработку
WM_SETREDRAW
, чтобы сделать пакетные обновления эффективными.Бонус-болтовня: заметьте, что использование
LockWindowUpdate
в качестве заменителя WM_SETREDRAW
не даст вам этой оптимизации. Несмотря на то, что окно блокировано для обновления, оно всё ещё перерисовывает себя, даже хотя вы не видите результатов - приводя к плате полной стоимости O(n²).
Комментариев нет:
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.