gpt4 book ai didi

multithreading - 为什么显示弹出菜单时不调用Application.OnMessage?

转载 作者:行者123 更新时间:2023-12-03 14:47:45 28 4
gpt4 key购买 nike

我使用 Application.OnMessage 事件处理程序来处理来自程序中其他线程的消息(通知)。我发现如果弹出菜单处于事件状态(打开),则不会调用此事件处理程序。测试代码如下(没有线程但原理是一样的):

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := ApplicationEvents1Message;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = WM_USER then
Beep();
end;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
PostThreadMessage(GetCurrentThreadId, WM_USER, 0, 0);
end;

最佳答案

OnMessage 从主线程的消息循环中调用。这个消息循环是在Delphi 的VCL 库代码中实现的。因此,该库代码有机会调用 OnMessage 的事件处理程序。

通过调用 Win32 函数 TrackPopupMenuEx 显示弹出菜单。此函数实现模式消息循环来运行菜单的跟踪 UI。由于此消息循环是在 Win32 代码中实现的,因此 VCL 代码没有机会触发 OnMessage 事件。 Win32 代码对 VCL 一无所知,并且运行简单的消息循环。消息得到服务和分派(dispatch),但无法执行 VCL 特定代码。

这是一个完美的例子,说明了为什么应该避免 PostThreadMessage。只有控制了每一个消息循环才可以使用。其他故障点包括系统消息对话框、拖放模式循环、窗口移动/大小模式循环。

您应该停止使用PostThreadMesaage。而是使用 AllocateHWnd 在主线程中创建窗口句柄。从工作线程将消息发布到该窗口。

关于multithreading - 为什么显示弹出菜单时不调用Application.OnMessage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40254708/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com