Мерцающая проблема Delphi TSplitter
Я использую Delphi со включенными стилями VCL, и я хотел бы изменить цвет TSplitter для моей формы. Я переопределяю TSplitter.Paint
в классе Interposer для рисования более темного цвета, чем стили VCL по умолчанию cBtnFace
цвет, но при изменении размера на форме заметно мерцание. Есть ли способ убрать это мерцание?
Я пробовал эти вещи, чтобы попытаться уменьшить мерцание, но ничего не получилось:
Отключение стилей VCL (
TSplitter.StyleElements := []
).Изменение элемента объекта "Конструктор растрового стиля стилей VCL" для "Splitter", но изменение этого элемента объекта не изменяет внешний вид разделителя.
Пытаясь обработать
WM_ERASEBKGND
сообщение наTControl
объекты, но я не смог получить процедуру для вызова в моем классе вставки.procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND; ... procedure TSplitter.WMEraseBkgnd(var Msg: TWMEraseBkgnd); begin // this is never invoked by the TSplitter Msg.Result := 1; end;
Любые другие идеи для избавления от мерцания на TSplitter
? Нет свойства DoubleBuffer для TSplitter
или что-нибудь подобное из того, что я могу сказать.
ОБНОВИТЬ
К сожалению, я не могу поделиться кодовой базой, но могу вам сказать, что именно так настраивается пользовательский интерфейс приложения, когда TSplitter
мерцает:
TForm (DoubleBuffered = False)
-> BackgroundPanel (DoubleBuffered = True, ParentBackground = False)
-> -> A TGradient, image and label to fill the BackgroundPanel
-> LeftPanel (ParentBackground = False`, no flickering)
-> -> LeftPanelFrame and frame content (selective double buffering)
-> TSplitter
-> RightPanel (ParentBackground = False, no flickering)
-> -> RightPanelFrame and frame content (selective double buffering)
В верхней части формы также есть панель инструментов и главное меню, но для остальных компонентов пользовательского интерфейса установлено значение alClient (или OnResized для заполнения пространства).
Я предположил, что поскольку BackgroundPanel находится за левой панелью, TSplitter
и RightPanel (т. е. Control -> Send to Back), DoubleBuffered = True
а также ParentBackground = False
на BackgroundPanel поможет уменьшить / убрать мерцание от любых компонентов на непосредственном уровне пользовательского интерфейса перед ним (то есть, TSplitter
). Но, похоже, это не так.
Возможно я постараюсь разместить TPanel
как родитель LeftPanel, TSplitter
и RightPanel и установите его DoubleBuffered = True
а также ParentBackground = False
, Я попробую это позже и вернусь. Итак, это будет выглядеть так:
TForm
-> BackgroundPanel (DoubleBuffered = True, ParentBackground = False)
-> -> A TGradient, image and label to fill the BackgroundPanel
-> EncapsulatingPanel (DoubleBuffered = True, ParentBackground = False)
-> -> LeftPanel (ParentBackground = False)
-> -> -> LeftPanelFrame and frame content
-> -> TSplitter
-> -> RightPanel (ParentBackground = False)
-> -> -> RightPanelFrame and frame content
Наконец, я должен отметить, что двойная буферизация TForm существенно замедляет пользовательский интерфейс при изменении размера (черный след справа от окна), а не при выполнении других действий пользовательского интерфейса, когда приложение не изменяет размер.
ОБНОВЛЕНИЕ 2
К сожалению, пока мой подход выше (создание фонового родителя TPanel
) исправлено мерцание на TSplitter
Это также вызвало другие странные проблемы с пользовательским интерфейсом, возможно, некоторые из которых @David Heffernan упоминались в комментариях. Сейчас я только что оставил проблему мерцания, поскольку разделитель имеет ширину всего 1 пиксель и мерцает только при изменении ширины и высоты.
1 ответ
TSplitter
контроль может не иметь DoubleBuffered
свойство, но это свойство должно быть реализовано на самом верхнем элементе управления мерцанием - в большинстве случаев - на форме. Пока все элементы управления имеют ParentDoubleBuffered
все еще включен по умолчанию, все они также получат это изменение.
DoubleBuffered
не всегда устраняет мерцание, а в некоторых ситуациях может усугубить ситуацию. Вы можете рассмотреть только использование DoubleBuffered
во время изменения размера, а затем выключите его, когда изменение размера будет сделано. Это свойство должно использоваться только для тех элементов управления, размер которых на самом деле изменяется. Например, при изменении размера формы включите DoubleBuffered
на форме. Но при изменении размера только содержимого панели включите его только для этой панели (и всех ее дочерних элементов управления).
Что касается падения производительности вашего приложения из-за этого изменения, вы можете также рассмотреть возможность применения флага при изменении размера, который приостановит выполнение любой программы, которая может привести к ее сбою (что-либо перерисовывает, например, метки, изображения и т. Д.). Это само по себе также может быть решением вашей проблемы (на самом деле может быть вторым ответом).