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

时间:2016-03-03 11:49:27

标签: delphi sendmessage

我复制了本文中的代码: {{3}}

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

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

s = "267 B361"
s1 = unlist(strsplit(s, split='B', fixed=TRUE))[2]

这是主要表格中的代码:

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

问题是程序AppMessage没有被调用。有什么问题?

1 个答案:

答案 0 :(得分:3)

OnMessage用于拦截排队的邮件。但是,此消息是发送而不是排队。您需要覆盖窗体的窗口过程才能接收它:

将此添加到表单类型声明的受保护部分:

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);

我还要评论说播放这样的信息对我来说似乎有点风险。您将该消息发送到系统中的每个顶级窗口。我认为如果你遇到一个对它不应该响应的程序,那么它有明确的潜在问题。

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