Delphi TSplitter 闪烁问题

标签 delphi flicker vcl-styles

我正在使用启用了 VCL 样式的 Delphi,并且我想更改我的表单的 TSplitter 的颜色。我覆盖TSplitter.Paint在插入器类中绘制比默认 VCL 样式更深的颜色 cBtnFace颜色,但调整大小时表单上有明显的闪烁。有没有办法消除这种闪烁?

我尝试过这些方法来减少闪烁,但没有任何效果:

  1. 禁用 VCL 样式 ( TSplitter.StyleElements := [] )。

  2. 更改“分割器”的 VCL 样式位图样式设计器的对象元素,但修改此对象元素不会更改分割器的外观。

  3. 尝试处理 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 上闪烁的想法? TSplitter 没有 DoubleBuffer 属性或据我所知类似的事情。

更新

遗憾的是,我无法共享代码库,但我可以告诉您,这是在 TSplitter 时设置应用程序 UI 的方式。闪烁:

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)

表单顶部还有一个工具栏和一个主菜单,但其余 UI 组件设置为 alClient(或 OnResized 来填充空间)。

我假设由于BackgroundPanel位于LeftPanel后面,TSplitter和 RightPanel(即控制 -> 发送到底层),DoubleBuffered = TrueParentBackground = False BackgroundPanel 上的内容将有助于减少/消除其前面的直接 UI 层上的任何组件(即 TSplitter )的闪烁。但是,事实似乎并非如此。

也许我会尝试放置 TPanel作为 LeftPanel 的父级,TSplitter 、RightPanel 并设置其 DoubleBuffered = TrueParentBackground = 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 会显着减慢 UI 的速度,而不是在应用程序未调整大小时执行其他 UI 操作时。

更新2

不幸的是,虽然我上面的方法(创建背景父 TPanel )修复了 TSplitter 上的闪烁。 ,它还导致了其他奇怪的 UI 问题,也许其中一些 @David Heffernan 在评论中提到了。目前,我刚刚解决了闪烁问题,因为分离器只有 1px 宽,并且仅在宽度 + 高度调整大小时闪烁。

最佳答案

TSplitter 控件可能没有 DoubleBuffered 属性,但此属性应该在您遇到闪烁的最上面的控件上实现 - 在大多数情况下,形式。只要所有控件仍然默认启用 ParentDoubleBuffered,它们也都会获得此更改。

DoubleBuffered 并不总能修复闪烁,在某些情况下可能会使情况变得更糟。您可以考虑在调整大小期间仅使用 DoubleBuffered,然后在调整大小完成后将其关闭。此属性只能用在那些实际正在调整大小的控件上。例如,调整表单大小时,在表单上启用 DoubleBuffered。但是,当仅调整面板内容的大小时,请仅针对该面板(及其所有子控件)启用它。

至于由于此更改而导致的应用程序性能下降,您还可以考虑在调整大小时实现一个标志,这将暂停任何可能使其陷入困境的程序执行(任何重绘的内容,例如标签、图像等) .)。这本身也可能是您问题的解决方案(实际上可能是第二个答案)。

关于Delphi TSplitter 闪烁问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15822299/

相关文章:

delphi - 向右移动菜单最后一项

delphi - 如何将滚动条位置转换为 Gamma 校正?

delphi - 如何在单独的进程中使用 SendMessage(..) 发送数据记录

jQuery 垂直巨型菜单子(monad)菜单在加载时闪烁。如何阻止wordpress中的闪烁

c++ - 不闪烁的绘图

delphi - TSaveTextFileDialog 和 Vcl 样式

delphi - Delphi 中使用 {.$DEFINE VAR} 而不是 {$DEFINE VAR} 的目的是什么

delphi - 验证 '*.map' 文件是否与 Delphi 应用程序匹配

java - JPanel 上无法停止闪烁

德尔福XE2 : Reloading a custom VCL style from file?