Показать сообщение отдельно
  #2  
Старый 20.08.2022, 03:10
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Тут все сложнее.
Тебе надо при старте новой копии определить, что передан файл.
Потом найти существующую копию, передать в нее имя файла, а текущую копию закрыть.

Вот пример, как сделано у меня, но мне не евдо было передавать имя файла, просто "поднять" уже существующую копию:
Код:
program PwdKeeper;

uses
  System.Types,
  Winapi.Windows,
  Vcl.Forms,
  MainFrm in 'MainFrm.pas' {MainForm},
  Model in 'Model.pas',
  SetupGeneralPwdFrm in 'SetupGeneralPwdFrm.pas' {SetupGeneralPwdForm},
  EnterGeneralPwdFrm in 'EnterGeneralPwdFrm.pas' {EnterGeneralPwdForm},
  AddEditPwdFrm in 'AddEditPwdFrm.pas' {AddEditPwdForm},
  AboutFrm in 'AboutFrm.pas' {AboutForm},
  UserProfile in 'Common\UserProfile.pas',
  SysFolders in 'Common\SysFolders.pas',
  Settings in 'Settings.pas',
  FindFrm in 'FindFrm.pas' {FindForm},
  SearchParams in 'SearchParams.pas',
  VerInfo in 'Common\VerInfo.pas',
  FormSizePosStorage in 'Common\FormSizePosStorage.pas';

{$R *.res}

function AllowSetForegroundWindow(dwProcessId: DWORD): BOOL; stdcall; external 'user32.dll';

function IsSecondCopy : Boolean;
var
  hMutex : THandle;
begin
  Result := False;

  WndMessage := RegisterWindowMessage(PChar("PWDKEEPER_MSG"));

  hMutex := CreateMutex(Nil, True, PChar("PWDKEEPER_MTX"));
  If hMutex<>0 Then
    If GetLastError=ERROR_ALREADY_EXISTS Then
      Begin
        AllowSetForegroundWindow(DWORD(-1));
        PostMessage(HWND_BROADCAST,WndMessage,0,0);
        Result := True;
      End;
end;

begin
  If IsSecondCopy Then Halt(0);
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'Password Keeper';
  Application.CreateForm(TMainForm, MainForm);
  Application.HookMainWindow(MainForm.HookMessageProc);
  Application.Run;
end.
Я заменил имена сообщения и мьютекса на константы, в оригинальном коде эти имена создаются для каждого юзера, т.о. если в системе залогинены несколько пользователей, то каждый может запустить свою копию, но только одну.
А вот, собственно, как вышеуказанное сообщение обраватывается в главной форме:
Код:
type
  TMainForm = class(TForm)
    ...
  public
    { Public declarations }
    function HookMessageProc(var Message : TMessage) : Boolean;
  end;

var
  MainForm: TMainForm;
  WndMessage : Cardinal;

...

function TMainForm.HookMessageProc(var Message : TMessage) : Boolean;
begin
  Result := False;
  If Message.Msg = WndMessage Then
    Begin
      If WindowState = wsMinimized Then Application.Restore;
      Application.BringToFront;
      SetForegroundWindow(Self.Handle);
      Result := True;
    End;
end;
Как я говорил, мне надо просто "поднять" предыдущую копию. Можно ли прямо в этом сообщении переслать имя файла - надо "курить" MSDN...
Ответить с цитированием