我正在开发一个防止多个实例的应用程序。我尝试使用wm_copydata向第一个应用程序实例发送消息,它不起作用,但我可以通过WM_SYSCOMMAND发送消息
if not checkInstance.RestoreIfRunning(Application.Handle,oldHandle, 1) then
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(Tfrm_main, frm_main);
Application.Run;
end
else
begin
stringToSend := 'My Message';
aCopyData.dwData := 0; //use it to identify the message contents
aCopyData.cbData := 1 + Length(stringToSend) ;
aCopyData.lpData := PChar(stringToSend) ;
SendMessage(oldHandle,WM_COPYDATA,longint(oldHandle),longint(@aCopyData));
end;
....
mainform:
private
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
.
.
.
procedure mainForm.WMCopyData(var Msg: TWMCopyData);
begin
ShowMessage('received!');
end;
答案 0 :(得分:1)
看起来您正在将消息发送到错误的窗口。或者另一种查看方式,您正试图在错误的窗口中处理消息。
你有:
if not checkInstance.RestoreIfRunning(Application.Handle, oldHandle, 1) then
当然,我们看不到checkInstance.RestoreIfRunning
背后的代码,但我的蜘蛛意识告诉我oldHandle
中返回的句柄是应用程序句柄而不是主窗口句柄。让我怀疑的是:
Application.Handle
传递给RestoreIfRunning
,因此可能是第二个应用程序尝试运行时看到的句柄。WM_SYSCOMMAND
响应,可能是为了恢复应用程序的第一个实例,但这是由应用程序窗口过程处理的消息。因此,在应用程序窗口过程而不是主窗体窗口过程中处理消息,一切都应该很好。使用Application.HookMainWindow
来实现这一目标。
答案 1 :(得分:-1)
这是一个解决方案
<强> Unit1.pas 强>
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
procedure WMApp(var msg: TMessage); message WM_APP;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMApp(var msg: TMessage);
begin
Application.Restore;
end;
end.
执行:项目 - 查看来源
Project1.dpr
program Project1;
uses
Vcl.Forms,
Windows,
Messages,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
Hwnd: THandle;
begin
Hwnd := FindWindow('TForm1', nil);
if Hwnd = 0 then
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end else
begin
if not IsWindowVisible(Hwnd) then
PostMessage(Hwnd, WM_APP, 0, 0);
SetForegroundWindow(Hwnd);
end;
end.
全部