gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 18:30:53 24 4
gpt4 key购买 nike

我从这篇文章中复制了代码:
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/

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