Рисование без мерцания
Автор: 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".
|