Автор: Mike Scott
...вот я и удивляюсь - почему я получаю мерцание, если я вызываю
Repaint или Refresh, а не метод OnPaint напрямую? Или это просто
"вариация на тему"?
Имеются две фазы обновления окна. В первой фазе, при выводе окна,
Windows посылает ему сообщение WM_ERASEBKGND, сообщающее о
необходимости стирания фона перед процедурой рисования. Затем
посылается сообщение WM_PAINT, служащее сигналом для закрашивания
"переднего плана".
Тем не менее, вы можете пропустить первую фазу, которая вызывает
мерцание, одним из двух способов: первый способ заключается в том,
что вы форсируете обновление сами, с помощью вызова функции Windows
API InvalidateRect. На входе он получает дескриптор окна, указатель
на закрашиваемую область - передаем NIL, если вы хотите отрисовать
всю область окна - и третий параметр, сообщающий о необходимости
очистки фона. Вот как раз последний параметр и должен содержать
значение FALSE, если вы сами будете в методе Paint полностью
отрисовывать всю область:
InvalidateRect( Handle, NIL, FALSE ) ;
|
Handle должен быть дескриптором формы или элемента управления.
Описав первый способ, я скажу, что существует другое подходящее
решение - использовать функциональность VCL. Вы можете указать VCL
не стирать фон, добавляя [ csOpaque ] к значению свойства
ControlStyle, как показано ниже:
ControlStyle := ControlStyle + [ csOpaque ] ;
|
Это ограничивает заполнение заднего фона, но вы все еще можете
видеть процесс "наполнения" области изображением, т.е. процесс
рисования. В этом случае вы можете отделаться от эффекта
мельтешения, рисуя на TBitmap и выводя его затем на экран командой
CopyRect.
Если вы хотите углубиться в тему дальше, то я отошлю вас к моей
статье "Optimizing Display Updates in Delphi" (Оптимизация
обновления экрана в Delphi), опубликованной в первом выпуске журнала
"Delphi magazine". |