如何在Delphi中防止ProcessMessages

时间:2009-08-09 16:24:07

标签: delphi messages idle-processing

Application.ProcessMessages命令是众所周知的,我在长进程中使用它来确保我的程序不会占用计算机。

但是我有一个相当快速的处理集,我将视图缓冲到文件中。在缓冲过程期间,可以发送一些系统消息(例如,重绘或滚动条移动或其他事件)。我希望防止这些被ProcessMessages处理,直到我的缓冲完成。

有没有办法:

  1. 在我的程序完成之前阻止Application.ProcessMessages,或

  2. 捕获我程序中生成的所有消息,并且在程序结束前不会释放它们。

4 个答案:

答案 0 :(得分:5)

即使发送了您不想要的消息,也允许ProcessMessages继续进行,但不应归类为有问题。通过一些代码重构,您可以将缓冲方法移动到一个单独的线程中并从那里开始。

如果您尝试将控件的“可视内容”复制到文件中,

  • 查看WM_PRINT(xxx)消息,该消息允许子控件将自己绘制成位图
  • 尝试LockWindowUpdate Win32 API方法调用,该方法将关闭所有绘制消息到该控件
  • 如果需要,
  • 覆盖控件类甚至父类的WndProc / DefaultWndProc方法,只需为发送的每条消息返回“true”
  • 覆盖控件类甚至父级的特定控制方法(例如“滚动条移动”,“OnPaint”,“OnPaintBackground”等),如果缓冲在进度

覆盖WndProcDefaultWndProc并简单地为每封邮件返回true基本上“关闭”ProcessMessages 但是以这种方式执行此操作是不安全的,因为控件可能需要处理一个或多个消息才能正常运行。

关闭ProcessMessages是不可能的(没有重写用于消息处理的VCL代码),因为它是VCL表单的消息循环构建方式的一部分。

答案 1 :(得分:3)

  

捕获在我的过程中生成的所有消息,而不是释放它们   直到程序结束。

你可以做一个肮脏的黑客攻击(只有你不能提出更好的方法):

您可以使用Win32 Hooks观看(捕获)任何消息 具体来说,使用带有WH_CALLWNDPROC的SetWindowsHookEx作为idHook值 然后,您可以在列表/队列中记录,并在需要时重新发送它们。

答案 2 :(得分:1)

我在Windows 2中了解到,Windows消息有时会发生在您不期望的情况下。库的任何部分都可能导致应用程序的消息处理发生。而不是阻止潮流,使您的代码强大抵御情况。这可能就像使用BeginUpdate / EndUpdate对一样简单,或者更复杂(使用临时更新并在最后进行最终更新)。

答案 3 :(得分:1)

在迂腐级别,“阻止”Application.ProcessMessages的方式是不调用任何代码

  1. 显示模态对话框
  2. 调用SendMessage
  3. 运行自己的本地消息循环
  4. 调用Application.ProcessMessages(本地消息循环)
  5. 如果您编写的循环除了数值计算和文件I / O之外什么都不做,那么您的UI将被冻结,直到您退出循环,因为没有消息正在处理。

    如果您希望您的UI在未知任意代码(第三方库)的长时间运行期间响应,但您不希望在此期间在您的应用中发生某些类型的操作,那么这是一个不同的问题 - 这是关于防止重入。您希望在特定活动进行时阻止使用代码的某些部分。例如,模态对话框通过禁用除模式对话框本身之外的所有应用程序的顶级窗口,阻止您与对话框下方的应用程序窗口进行交互。