delphi - 应用程序主窗体未接收通过 SendMessage 发送的消息

标签 delphi sendmessage

我从这篇文章中复制了代码: Controlling the number of application instances

但是,SendMessage 发送的消息没有被主窗体“捕获”。

这是 DPR 文件中的代码,我们在其中注册消息,然后在应用程序的实例已在运行时广播它:

var
  Mutex: THandle;

begin
  MyMsg := RegisterWindowMessage('Show_Main_Form');
  Mutex := CreateMutex(nil, True, 'B8C24BD7-4CFB-457E-841E-1978A8ED0B16');

  if (Mutex = 0) or (GetLastError = ERROR_ALREADY_EXISTS) then
  begin
    SendMessage(HWND_BROADCAST, MyMsg, 0, 0);
  end

这是主窗体中的代码:

var
  fmMain: TfmMain;
  MyMsg: Cardinal;

implementation

uses
  uSettings;

{$R *.dfm}

procedure TfmMain.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if (Msg.Message = MyMsg) then
  begin
    beep;

    Application.Restore;
    Application.MainForm.Visible := True;
    SetForeGroundWindow(Application.MainForm.Handle);
    Handled := True;
  end;
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

问题是 AppMessage 过程没有被调用。怎么了?

最佳答案

OnMessage 用于拦截排队消息。然而,该消息是被发送而不是被排队。您需要重写窗体的窗口过程才能接收它:

将其添加到表单类型声明的 protected 部分:

procedure WndProc(var Message: TMessage); override;

像这样实现:

procedure TfmMain.WndProc(var Message: TMessage);
begin
  inherited;

  if Message.Msg = MyMsg then
  begin
    Beep;

    Application.Restore;
    Application.MainForm.Visible := True;
    SetForeGroundWindow(Application.MainForm.Handle);
  end;
end;

由于此表单可能是应用程序主表单的单个实例,因此您可以将消息处理程序的正文替换为:

Application.Restore;
Visible := True;
SetForeGroundWindow(Handle);

我还要评论说,广播这样的消息对我来说似乎有点冒险。您将将该消息发送到系统中的每个顶级窗口。我认为,如果您遇到一个程序在不应该对该消息使用react的情况下,这肯定会导致问题。

如果是我,我会识别您想要定位的窗口,并将消息直接发送到该窗口。我会使用 SendMessageTimeout 来应对目标应用程序没有响应的情况。在这种情况下,SendMessage 将永远不会返回,并且发送应用程序也将挂起。

关于delphi - 应用程序主窗体未接收通过 SendMessage 发送的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35771398/

相关文章:

delphi - 使用 Delphi 6 的 Format() 语句以十六进制格式打印 HRESULT 的格式说明符是否正确?

vb.net - Delphi 中的 VB [(Function) 句柄 ...] 等效项

安卓应用 : send post to a user's friend without knowing its id in advance

c# - 从 Windows API 返回的消息

winapi - 使用 WINAPI 而不是鼠标强制显示工具提示

c# - 有什么方法可以在不选择它的情况下从另一个程序复制文本吗?

C# Skype4COM SendMessage 用户名

delphi - 如何在delphi中使用teechart从数据集中制作堆积条形图

delphi - Delphi中的密码加密

string - 字符串内的换行符显示在 TMemoBox 上