Application.ProcessMessages命令是众所周知的,我在长进程中使用它来确保我的程序不会占用计算机。
但是我有一个相当快速的处理集,我将视图缓冲到文件中。在缓冲过程期间,可以发送一些系统消息(例如,重绘或滚动条移动或其他事件)。我希望防止这些被ProcessMessages处理,直到我的缓冲完成。
有没有办法:
在我的程序完成之前阻止Application.ProcessMessages,或
捕获我程序中生成的所有消息,并且在程序结束前不会释放它们。
答案 0 :(得分:5)
即使发送了您不想要的消息,也允许ProcessMessages
继续进行,但不应归类为有问题。通过一些代码重构,您可以将缓冲方法移动到一个单独的线程中并从那里开始。
如果您尝试将控件的“可视内容”复制到文件中,
LockWindowUpdate
Win32 API方法调用,该方法将关闭所有绘制消息到该控件WndProc
/ DefaultWndProc
方法,只需为发送的每条消息返回“true”OnPaint
”,“OnPaintBackground
”等),如果缓冲在进度覆盖WndProc
或DefaultWndProc
并简单地为每封邮件返回true基本上“关闭”ProcessMessages
但是以这种方式执行此操作是不安全的,因为控件可能需要处理一个或多个消息才能正常运行。
关闭ProcessMessages
是不可能的(没有重写用于消息处理的VCL代码),因为它是VCL表单的消息循环构建方式的一部分。
答案 1 :(得分:3)
捕获在我的过程中生成的所有消息,而不是释放它们 直到程序结束。
你可以做一个肮脏的黑客攻击(只有你不能提出更好的方法):
您可以使用Win32 Hooks观看(捕获)任何消息
具体来说,使用带有WH_CALLWNDPROC的SetWindowsHookEx作为idHook值
然后,您可以在列表/队列中记录,并在需要时重新发送它们。
答案 2 :(得分:1)
我在Windows 2中了解到,Windows消息有时会发生在您不期望的情况下。库的任何部分都可能导致应用程序的消息处理发生。而不是阻止潮流,使您的代码强大抵御情况。这可能就像使用BeginUpdate / EndUpdate对一样简单,或者更复杂(使用临时更新并在最后进行最终更新)。
答案 3 :(得分:1)
在迂腐级别,“阻止”Application.ProcessMessages的方式是不调用任何代码
如果您编写的循环除了数值计算和文件I / O之外什么都不做,那么您的UI将被冻结,直到您退出循环,因为没有消息正在处理。
如果您希望您的UI在未知任意代码(第三方库)的长时间运行期间响应,但您不希望在此期间在您的应用中发生某些类型的操作,那么这是一个不同的问题 - 这是关于防止重入。您希望在特定活动进行时阻止使用代码的某些部分。例如,模态对话框通过禁用除模式对话框本身之外的所有应用程序的顶级窗口,阻止您与对话框下方的应用程序窗口进行交互。