2009-09-11 70 views
25

创建新表单后,我通常会执行这个仪式:为什么DoubleBuffered默认禁用?

  1. 将名称改为有意义的;
  2. 输入a Caption;
  3. 更改位置属性(DefaultPosOnly几乎不会满足用户的期望);
  4. ShowHint设置为true;
  5. Set DoubleBuffered to true;

我一直想知道为什么默认值是'假'。对我来说,它只是低技术和蹩脚的,在我的新机器上,我没有注意到性能上的差异。

旧计算机,VNC,远程桌面或虚拟机上的doublebuffering问题可能是?

你把它打开还是关闭?任何建议?

回答

32

正如您可能知道的,双缓冲区通常涉及创建与视觉组件大小相同的屏幕外缓冲区。在此缓冲区上执行写入/绘图,完成后,整个缓冲区将“交换”,以便它现在绘制在可视组件上。

(注:“交换”可以包括简单地改变地址的指针指向,或实际上可能涉及复制的存储器块,例如使用的BitBlt,memcpy的等)

因此存储器的合理量分配为每个支持该组件的进程提供支持。如果您的应用程序有很多窗口或/和组件,则分配的内存量不会很少。如果你不需要流畅的视觉更新/滚动,为什么浪费这些内存?

当然也有一种说法,那就是今天大多数电脑都有足够的内存可用,所以为什么要担心。不过,如果你不需要它,我仍然不认为这是默认启用双缓冲的理由。

如果手动将DoubleBuffered设置为true对您而言是一种痛苦,那么您可以始终创建自己的自定义控件/继承自内置控件的组件,并将DoubleBuffered(和其他属性)设置为所需的默认值。

+1

+1不错的答案。 Nitpick:将“快速复制”替换为“交换”或其他没有给出印象的其他内容,实际上是进行缓冲区复制。缓冲区交换通常是简单的指针交换。 – 2009-09-11 02:21:54

+0

好点,我已经更新了答案。当然,在Windows Forms.NET中,还有一个“假装”双缓冲,实际上它只是一个内存拷贝。 – Ash 2009-09-11 02:26:56

+11

当'DoubleBuffered'为true时,控件响应如下的画图消息:它创建一个位图,绘制位图,调用BitBlt将位图复制到窗口上,然后销毁该位图。这不仅仅是一个简单的指针交换。 – 2009-09-11 04:49:21

12

在现代操作系统上进行桌面合成双缓冲实际上可能会降低性能。无论如何,渲染是在离屏位图中执行的,所以使用双缓冲会导致额外的复制,而这些复制在这些系统上根本没有任何好处。所以除非VCL在这种情况下足够聪明以忽略双缓冲(不知道它是否需要检查),否则无法无条件设置它实际上会更好。

编辑:

我检查,并在这两个德尔福2007年和2009年德尔福的TWinControl.WMPaint方法不使用双缓冲时DwmCompositionEnabled回报True。尼斯。

25

做某种类型的远程桌面时要避免双缓冲,因为必须通过网络发送控件/表单的整个位图来完成BitBlt。见this blog post ...

+3

+1真棒。如此明显,只要您指出,但我从来没有想到会发生这种情况。这将使我重新思考我的一些程序....感谢您指出这一点! – robsoft 2009-09-11 12:04:13

+0

+1同意上面提到的内容! – user271077 2010-10-11 21:04:49

1

您也可以创建一个设计时专家,为您创建的每个表单/控件自动设置此值,而不是为每个现有工作都派生新的控件,这将涉及更多的工作。 查看GExperts.org的源代码,了解如何实现这一点。