SendMessage到Application.Handle无法正常工作

lui*_*x10 0 delphi postmessage sendmessage

我已经创建了一个类,当它将被释放时,它应该向整个应用程序传播一个自定义消息.我做到了PostMessage,它只有几个错误

PostMessage(Application.Handle, UM_MYMESSAGE, 0, 0);
Run Code Online (Sandbox Code Playgroud)

然后我意识到它应该是同步的 - 通过SendMessage.

SendMessage(Application.Handle, UM_MYMESSAGE, 0, 0);
Run Code Online (Sandbox Code Playgroud)

在我的表单上,我使用TApplicationEvents组件处理消息,但只是切换SendMessagePostMessage没有使它处理消息

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  if Msg.message = UM_MYMESSAGE then
  begin
    ShowMessage('Ok');

    Handled := True;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如果我通过表格处理但没有合作,它可以工作Application.Handle......我做错了什么?

Rem*_*eau 5

TApplication(Events).OnMessage事件仅适用于邮件触发张贴到主UI线程消息队列. 已发送的消息将直接转到目标窗口的消息过程,从而绕过消息队列.这就是你的OnMessage事件处理程序使用PostMessage()但不使用的原因SendMessage().

要捕获发送TApplication窗口的消息,您需要使用TApplication.HookMainWindow()而不是TApplication(Events).OnMessage,例如:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.HookMainWindow(MyAppHook);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Application.UnhookMainWindow(MyAppHook);
end;

function TForm1.MyAppHook(var Message: TMessage): Boolean;
begin
  if Message.Msg = UM_MYMESSAGE then
  begin
    ShowMessage('Ok');
    Result := True;
  end else
    Result := False;
end;
Run Code Online (Sandbox Code Playgroud)

话虽这么说,一个更好的解决方案是使用AllocateHWnd()创建自己的私人窗口,您可以发布/发送您的自定义消息,例如:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMyWnd := AllocateHWnd(MyWndMsgProc);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  DeallocateHWnd(FMyWnd);
end;

procedure TForm1.MyWndMsgProc(var Message: TMessage);
begin
  if Message.Msg = UM_MYMESSAGE then
  begin
    ShowMessage('Ok');
    Message.Result := 0;
  end else
    Message.Result := DefWindowProc(FMyWnd, Message.Msg, Message.WParam, Message.LParam);
end;
Run Code Online (Sandbox Code Playgroud)

然后你可以发送/发送消息FMyWnd.