【问题标题】:Delphi - hold the system messages/prevent UI redrawing?Delphi - 保存系统消息/防止 UI 重绘?
【发布时间】:2016-03-24 17:04:54
【问题描述】:

这听起来可能很傻,但我遇到了一些情况,当我希望应用程序不显示正在发生的事情时,直到发生另一个特定操作(stringGrids 已填充数据,UI 已准备好......)。有没有办法阻止消息从应用程序发送到操作系统?

那么,有什么反对意见

application.processmessages

? 比如:

application.stopProcessingMessages;

fill stringGrids, prepare the UI...

application.processMessagesAgain;

?

当然,我可以在单独的线程中运行这些操作,但在某些情况下我不想,或者不能在单独的线程中执行。

【问题讨论】:

  • 什么是网格?没有Application.StopProcessingMessages,但是根据您具体执行的操作,有一些方法可以阻止某些组件更新屏幕。但是,由于您没有发布任何真正的相关信息,因此很难提供建议。你发布的代码几乎是我有代码可以做废话,废话,废话。如果没有任何细节,我该如何更改该代码的行为?
  • 这个皮肤有很多不同的方法。从使用控件而不是网格开始。例如,虚拟模式列表视图。将所有数据保存在 UI 控件中是糟糕的设计。你只是在收获它的后果。抑制绘画将是修补它的一种方法。实现起来并不难。你永远不应该打电话给ProcessMessages。更好地了解 Windows 消息的工作原理可能会让您受益。
  • 我不想完全坚持网格示例。但在这种情况下,我说的是 TStringGrid
  • 您可以使用WM_SETREDRAW 来暂停重绘。坦率地说,您的设计听起来很错误,我认为您对系统如何工作的理解存在问题。花大量时间从主线程工作是一个大问题。如果收集数据需要时间,请在后台线程中进行。完成后,更新 UI。
  • 如果您在后台收集新数据,则无需禁止任何绘画,然后在获得所有数据后进行更新。这只是一个更好的解决方案。

标签: delphi user-interface redraw


【解决方案1】:

检查TDataSet.DisableControls 以获取数据感知控件,并检查 BeginUpdate / EndUpdate 以获取某些 VCL / RTL 类(包括 TStrings),并且 - 特定于提到的 TStringGrid - 请参阅 Delphi TStringGrid Flicker

【讨论】:

  • WM_SETREDRAW - 这正是我所需要的。我提供的例子不好。如果我在 for 循环中更新网格,即使我在每次传递中添加一行,它也会“闪烁”。谢谢...
  • WM_SETREDRAW?这是很早之前提到的。不过,这可能不是您描述的问题的正确解决方案。
  • @DavidHeffernan 有人提到过,是的,但我不知道它的作用,直到我阅读了此处链接的主题。我还对你提到的评论投了赞成票。这是正确的解决方案,每个人都坚持使用 for 循环和网格的例子,不是很好。这个问题非常清楚......
  • 这可能不是正确的解决方案。如果您想了解它,可以阅读文档。你知道如何找到它们吗?
【解决方案2】:

事实证明,虽然我认为使用 WM_SETREDRAW 消息是正确的解决方案,但它有一些缺点。最大的一个是,如果使用,用户可以点击表单。所以最终的解决方案就是像这样在整个表单上放置一个空的 TPanel

  panel1.Left:= 0;
  panel1.Top:= 0;
  panel1.Width:= frmMain.Width;
  panel1.Height:= frmMain.Height;

表格准备好后,面板会缩小,变得不可见等。它可靠地隐藏了每一个闪烁和其他看起来不太好的东西,我想对用户隐藏它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2014-06-10
    • 2011-09-26
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    相关资源
    最近更新 更多