Site icon Embarcadero RAD Studio, Delphi, & C++Builder Blogs

Метод VCL LockDrawing в TWinControl

vcl110 lockdrawing text

Одной из функций, добавленных в библиотеку VCL в Delphi 11, является возможность простой обработки сообщения Windows WM_SETREDRAW с помощью двух специальных методов, добавленных в класс TWinControl: LockDrawing и UnlockDrawing.


Ранее на этой неделе я просматривал свой список дел и обнаружил, что не указано, что мне следует продолжить публикацию в блоге о новых функциях VCL в Delphi и C++Builder 11 о LockDrawing. На самом деле я написал:  «Базовый класс TWinControl теперь предлагает методы LockDrawing и UnlockDrawing для отключения и управления обновлением. Это инициирует выполнение сообщения Windows WM_SETREDRAW. Это, наверное, стоит отдельного поста в блоге… », но потом я совсем забыл об этом. Итак, вот сообщение в блоге с задержкой в ​​несколько месяцев.

Начнем с Windows API. Сообщение  WM_SETREDRAW  отправляется окну, чтобы « разрешить перерисовку изменений в этом окне или предотвратить перерисовку изменений в этом окне». Каждый раз, когда вам нужно выполнить набор операций, каждая из которых требует перерисовки, вы можете отложить их и перерисовать только в конце, избегая мерцания и ускоряя процесс. Конечно, важно снять блокировку, а затем вызвать специальную функцию для принудительной перерисовки (RedrawWindow).

Все это должным образом инкапсулировано в двух методах TWinControl, добавленных в библиотеку VCL в RAD Studio 11, LockDrawing и UnlockDrawing, которые отправляют сообщение WM_SETREDRAW с соответствующими параметрами. Они также реализуют «логику подсчета блокировок», так что если вы дважды заблокируете один и тот же элемент управления, вам нужно дважды разблокировать его, чтобы возобновить рисование. Кроме того, UnlockDrawing автоматически вызывает API RedrawWindow.

Сказав это, каковы варианты использования? Я написал демо-версию, показывающую два сценария, и вы также можете проверить этот хороший пост в блоге Радека Червинки.

Первый случай в моей демонстрации — добавление набора элементов в список. Хотя Delphi традиционно предлагает и по-прежнему имеет возможность избежать перерисовки, «замораживая» обновление списка строк, вместо этого имеет смысл заблокировать перерисовку пользовательского интерфейса. Это два альтернативных стиля кодирования:
[crayon-6637c7ae960e2357654525/]
В обоих случаях производительность намного выше (и заметно заметнее), чем без одного из двух решений. Другой сценарий — набор изменений в компоненте, вызывающий перерисовку. Это непросто смоделировать на простом примере, но это один из способов вызвать мерцание «намеренно» с помощью такого кода:
[crayon-6637c7ae960ec699561087/]
Я знаю, это довольно глупо, но вы можете видеть, что при вызовах блокировки/разблокировки мерцания нет, в то время как без блокировки пользовательского интерфейса эффект выглядит довольно ужасно. Не то чтобы я мог легко отобразить это на скриншоте, но в любом случае вот форма во время выполнения:

Exit mobile version