如何在 Delphi 应用程序中丢弃未处理的事件消息?

Mag*_*s W 1 delphi

我在 Delphi 应用程序中执行一些 HTTP 请求时显示“请稍候”表单。“请稍候”对话框Application.ProcessMessages在关闭时调用。

这似乎会产生一些不良后果。例如,如果用户点击“请稍候”对话框后面表单中的按钮,这些点击似乎被添加到事件队列并在Application.ProcessMessages执行时处理,即使按钮在显示对话框之前被禁用并在隐藏后再次启用它。

所以我想知道是否有任何方法可以在显示“请稍候”对话框时完全忽略整个应用程序的鼠标单击事件?我发现我可以设置Enabled整个表单以False防止该特定表单上的鼠标单击事件,但其他表单Application.ProcessMessages在执行时仍会收到鼠标单击事件。

有没有标准的方法来做到这一点?无论是像(假设伪代码)Application.Enabled := FALSEApplication.DiscardMessages

修改“请稍候”对话框的行为(删除对 的调用Application.ProcessMessages)不在我的控制范围内 - 它是在各个地方使用的标准全公司对话框。

Rem*_*eau 6

我在 Delphi 应用程序中执行一些 HTTP 请求时显示“请稍候”表单。“请稍候”对话框在关闭时调用 Application.ProcessMessages。

它不应该这样做。这是一个很好的迹象,表明正在使用糟糕的设计。

解决这个问题的正确方法是在工作线程中执行 HTTP 请求,并在线程忙于工作时模态显示对话框,允许主消息队列仍然正常处理消息。模态对话框阻止用户输入到达对话框外的窗口。当线程完成时,可以关闭对话框,将用户输入恢复到其他窗口。

这似乎会产生一些不良后果。例如,如果用户单击“请稍候”对话框后面表单中的按钮,则这些单击似乎被添加到事件队列中并在执行 Application.ProcessMessages 时处理,即使按钮在显示对话框之前被禁用并启用隐藏后再次。

这意味着对话框在显示时根本不处理任何消息。这是任何对话框的错误设计。

所以我想知道是否有任何方法可以在显示“请稍候”对话框时完全忽略整个应用程序的鼠标单击事件?

是的 - 在对话框运行时正常处理消息,只是不要对它们做任何事情。如果您的对话框以模态显示,您将免费获得这种行为,因为模态对话框运行自己的消息循环,并禁用其他活动窗口,防止任何用户输入到达它们。

我发现我可以将整个表单的 Enabled 设置为 False 以防止该特定表单上的鼠标单击事件,但是当 Application.ProcessMessages 被执行时,其他表单仍然会收到鼠标单击事件。

更有理由怀疑您没有以模态方式使用对话框,因为它会为您禁用调用线程中的所有窗口。

有没有标准的方法来做到这一点?

是的 - 修复您的设计。正确使用模态对话框。

或者像(假设的伪代码)Application.Enabled := FALSE 或 Application.DiscardMessages?

在 VCL 或 FMX 框架中没有类似的东西。如果你真的需要这样的东西,你必须PeekMessage()直接调用 Win32函数(当然只在 Windows 上),例如:

procedure DiscardMouseClicks;
var
  msg: TMsg;
begin
  while PeekMessage(0, msg, MOUSE_FIRST, MOUSE_LAST, PM_REMOVE) do;
end;
Run Code Online (Sandbox Code Playgroud)

不用说,如果你不得不求助于这个,你就做错了。

修改“请稍候”对话框的行为(删除对 Application.ProcessMessages 的调用)不在我的控制范围内 - 它是在各个地方使用的标准全公司对话框。

那么要么您的公司在其所有应用程序中强制执行糟糕的设计,要么您只是在滥用对话框。