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



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

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

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

有标准的方法吗?类似于(假设伪代码)Application.Enabled := FALSEApplication.DiscardMessages

修改";请稍候"对话框(删除对Application.ProcessMessages的调用)超出了我的控制范围——这是一个在各种地方使用的标准公司范围的对话框。

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

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

正确的方法是在工作线程中执行HTTP请求,并在线程忙于工作时以模式显示对话框,从而使主消息队列仍能正常处理消息。模式对话框阻止用户输入到达对话框之外的窗口。线程完成后,可以关闭对话框,将用户输入恢复到其他窗口。

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

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

所以我想知道是否有任何方法可以在显示";请稍候"对话

是-在对话框运行时正常处理消息,只是不要对它们执行任何操作。如果您的对话框以模式显示,您将免费获得此行为,因为模式对话框运行自己的消息循环,并禁用其他活动窗口,从而阻止任何用户输入到达它们。

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

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

有标准的方法吗?

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

类似(假设的伪代码)Application.Enable:=FALSE还是Application.DiscardMessages?

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

procedure DiscardMouseClicks;
var
msg: TMsg;
begin
while PeekMessage(0, msg, MOUSE_FIRST, MOUSE_LAST, PM_REMOVE) do;
end;

不用说,如果你不得不这样做,那你就是在做错事。

修改";请稍候"对话框(删除对Application.ProcessMessages的调用)超出了我的控制范围——这是一个在各种地方使用的标准公司范围的对话框。

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

您的"请稍候"对话框不是模态对话框,因为模态对话框会在其生命周期内阻塞对话框外的用户输入。此外,它还将/甚至处理相关或必要的窗口和应用程序消息,因为它内部已经使用Application.ProcessMessages,之后无需手动调用它。这一切都是由设计和免费使用。

通过使用ShowModal方法显示对话框,使其成为模态对话框。

由于您当前的对话框是固定的(可以理解为它不能被修改),那么解决方案可以是创建一个新的单独的模态对话框;请稍候"对话框。

最新更新