如何禁用屏幕更新,使其不会频繁更新控件?

15

我有一个包含50个或更多控件的表单,这些控件是在运行时创建并添加的。我不想一个一个地看到它们出现;我更愿意在开始时禁用绘画/启动缓冲,然后一次性地看到它们全部出现。

我记得大约10年前在BCB中做过类似的事情,但现在忘记了。


3
你可以将所有这些控件放在一个TPanel上并进行显示/隐藏。但是你确定你真的需要50个控件吗?也许你可以用一个由50个部分组成的自定义控件更好?我不知道你的具体情况,但根据我的经验,当有人向窗体添加大量类似的控件时,他/她应该构建一个包含大量相似部分的新控件! - Andreas Rejbrand
好观点(+1),但并不总是相同的控件。它们是由某些用户选择动态创建的,然后他可以将它们定位。有一个保存选项,而我关心的是在加载时重新绘制。 - Mawg says reinstate Monica
2个回答

51

我不确定是否有Delphi特定的方法来做到这一点,但是使用Win32 API,可以通过WM_SETREDRAW消息来实现。

编辑:感谢Ken White和Sertac Akyuz提供下面的示例代码。

begin
  // Defer updates
  SendMessage(Handle, WM_SETREDRAW, WPARAM(False), 0);
  try
    // Create all your controls here
  finally
    // Make sure updates are re-enabled
    SendMessage(Handle, WM_SETREDRAW, WPARAM(True), 0);
    // Invalidate;  // Might be required to reflect the changes  
  end;
end;

10
+1,我希望你的回答能够迅速得到很多赞,以防止使用LockWindowUpdate的回答。 - Sertac Akyuz
6
LockWindowUpdate旨在停止拖放操作时的绘图,它比WM_SETREDRAW更进一步,因为它可以做出用户正在进行什么操作的假设。其中一个假设是,在进行拖放操作时可以禁用/忽略窗口移动。即使将WM_SETREDRAW设置为false,您仍然可以拖动窗口。 - Gregor Brandt
8
@Mawg:请参考“LockWindowUpdate不应该使用的操作是什么?”(http://blogs.msdn.com/b/oldnewthing/archive/2007/02/22/1742084.aspx)。 - mghie
1
@Ken和Sertac:谢谢你们两个。我已经有10年没用Delphi了,所以很高兴有人能提供示例代码。 - casablanca
1
@Sertac:不需要还原或重新编辑。我在使用WM_SETREDRAW的几次中没有遇到过需要Invalidate的情况,但有时可能会需要。我认为这个建议没有问题。 :-) 谢谢。 - Ken White
显示剩余7条评论

11

在所有准备工作完成之前,我只需将Visible = False。


+1 这也是一种可能性(我已经考虑过了,只是想看看是否有其他方法)。 - Mawg says reinstate Monica
5
针对运行时组件创建,保持Visible=False 感觉上更好一些,而针对已经存在且可见的控件更新,则使用WM_SETREDRAW感觉更好。 - Cosmin Prund
2
保持Visible=False并不是最好的选择。WM_SETREDRAW更好一些。特别是当控件的Align属性设置为alClient且连接到TSplitter时,设置Visible=False会破坏整个布局。而且它也更慢。 - nagylzs
如果您只想锁定一个面板怎么办?您不能每次都将其隐藏,然后再将其带回来。这样会使闪烁问题更加严重。 - Gabriel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接