I am using Delphi with VCL styles enabled and I would like to change the color of the TSplitter for my form. I override TSplitter.Paint
in an interposer class to paint a darker color than the default VCL styles cBtnFace
color, but there is significant flickering on the form when resized. Is there a way to remove this flickering?
I've tried these things to try and reduce the flickering, but none have worked:
Disabling VCL styles (
TSplitter.StyleElements := []
).Changing the VCL Styles Bitmap Style Designer's object element for "Splitter," but modifying this object element doesn't change the splitter's appearance.
Trying to process the
WM_ERASEBKGND
message onTControl
objects, but I was unable to get the procedure to be called in my interposer class.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;
Any other ideas for getting rid of the flickering on a TSplitter
? There's no DoubleBuffer property for TSplitter
or anything like that from what I can tell.
UPDATE
Unfortunately, I can't share the codebase, but I can tell you that this is the way the application UI is setup when the TSplitter
flickers:
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)
There is also a toolbar and a main menu at the top of the form, but the rest of the UI components are set to alClient (or OnResized to fill the space).
I assumed that since the BackgroundPanel is behind the LeftPanel, TSplitter
, and RightPanel (i.e, Control -> Send to Back), the DoubleBuffered = True
and ParentBackground = False
on the BackgroundPanel would help reduce/remove the flicker from any components on an immediate UI layer in front of it (i.e, the TSplitter
). But, this doesn't seem to be the case.
Perhaps I'll try placing a TPanel
as a parent of LeftPanel, TSplitter
, and RightPanel and set its DoubleBuffered = True
and ParentBackground = False
. I'll have to try that later and get back. So, it would look like this:
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
Lastly, I should note that double buffering the TForm substantially slows down the UI when resizing (a black trail on the right of the window), not when doing other UI things when the app is not resizing.
UPDATE 2
Unfortunately, while my approach above (creating a background parent TPanel
) fixed the flickering on the TSplitter
, it also caused other weird UI issues, perhaps some of which @David Heffernan alluded to in the comments. For now, I've just left the flickering issue, since the splitter is only 1px wide and only flickers on width + height resizing.