Как сделать так, чтобы форма менялась более плавно?

При изменении размера формы с множеством элементов управления форма выглядит плохо из-за мерцания. Какие есть советы по более плавному изменению размера формы?


person zz1433    schedule 21.09.2009    source источник


Ответы (5)


Попробуйте использовать WM_SETREDRAW (не LockWindowUpdate < / а>).

Вы также можете ознакомиться с DeferWindowPos.

person Uli Gerhardt    schedule 21.09.2009
comment
+1, оба очень хорошие советы сами по себе. Однако это, вероятно, не поможет со сложной формой VCL, использующей выравнивание, вложенные элементы управления и так далее. DeferWindowPos() стоит протестировать для ручного размещения в OnResize обработчике. - person mghie; 21.09.2009

Сложные формы часто состоят из вложенных панелей, и процесс перерисовки может вызвать мерцание. Если это так с вашим проектом, есть два простых решения, которые могут помочь:

  1. Отключите свойство FullRepaint на своих панелях.
  2. Включите свойство DoubleBuffered в вашей форме. Вы не найдете это свойство в инспекторе объектов, поэтому поместите DoubleBuffered := true; в FormCreate.
person Svein Bringsli    schedule 21.09.2009
comment
Обратите внимание, что DoubleBuffered обменивает меньшее мерцание на более медленную скорость обновления, эффект, который может быть заметен на больших экранах, где изменение размера может стать скачкообразным с большими размерами окон. - person mghie; 21.09.2009
comment
DoubleBuffered в основном делает ваше приложение бесполезным на Citrix и Terminal Server. - person Jeroen Wiert Pluimers; 21.09.2009
comment
››› DoubleBuffered делает ваше приложение бесполезным на Citrix и Terminal Server. Вы можете указать, почему? - person Alex; 21.09.2009
comment
@Alexander: См. Ответы на stackoverflow.com / questions / 1408664 / - person mghie; 21.09.2009
comment
DoubleBuffered: см. delphi3000.com/articles/article_1537.asp?SK= и stackoverflow.com/questions/1444830/ - person Jeroen Wiert Pluimers; 21.09.2009
comment
@JeroenPluimers +1 для уплаты налогов и определения того, когда вы находитесь в сеансе терминальных служб (например, подключение к удаленному рабочему столу) - person Ian Boyd; 29.12.2011

Я обошел это следующим образом:

  1. В событии OnResize формы создайте процедуру, чтобы скрыть все дочерние элементы управления, а затем запустить таймер с тиком около 500 мс.
  2. Когда сработает таймер, отключите его, а затем установите все дочерние элементы управления как видимые.

Играя с этим заданием, вы получаете форму, которая становится пустой, пока вы ее масштабируете, но затем аккуратно заполняется, когда вы «отпускаете».

Bri

person Brian Frost    schedule 21.09.2009
comment
Я думаю, вы обнаружите, что обработка сообщений перемещения размера входа / выхода (с модификацией, отмеченной в моем комментарии выше) обеспечивает лучший пользовательский интерфейс, потому что вы можете по крайней мере видеть (безразмерную) форму при изменении размера окна. - person frogb; 23.09.2009

Я избегаю мерцания, выравнивая не более 1 компонента, отличного от alClient, на одного родителя, всегда в паре с alClient (например, TPanel), чтобы содержать все остальные компоненты. Сгруппируйте их в панели без границ.

Допустим, вы хотите совместить три элемента: alLeft, alTop и alClient для основного представления. Не делай этого: Form alTop alLeft alClient // your main view

Но вместо этого вставьте их следующим образом: Form alTop alClient // panel to avoid flicker alLeft alClient // your main view

Та же история для встраивания нескольких alTop элементов.

person Barry Staes    schedule 23.09.2015

person    schedule
comment
Это нормально для предотвращения мерцания, но также, похоже, полностью предотвращает выравнивание. Я добавил вызов Invalidate после включения выравнивания: не идеально, потому что вы не можете точно увидеть, какой эффект будет иметь изменение размера формы, но, по крайней мере, он устраняет все мерцание на сложной многопанельной форме. - person frogb; 23.09.2009
comment
процедура WMEnterSizeMove (сообщение var: TWMMove); сообщение WM_ENTERSIZEMOVE; процедура WMExitSizeMove (сообщение var: TWMMove); сообщение WM_EXITSIZEMOVE; не запускает соответствующие события. На самом деле забыл упомянуть, что это рама, а не форма, но я догадался, что это будет то же самое. - person zz1433; 23.09.2009