加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 防止多个实例 – 还可以处理命令行参数?

发布时间:2020-12-15 04:25:02 所属栏目:大数据 来源:网络整理
导读:我正在处理从 Windows的应用程序相关的扩展文件.所以当你双击一个文件从Windows它会执行我的程序,我从那里处理的文件,像: procedure TMainForm.FormCreate(Sender: TObject);var i: Integer;begin for i := 0 to ParamCount -1 do begin if SameText(Extrac
我正在处理从 Windows的应用程序相关的扩展文件.所以当你双击一个文件从Windows它会执行我的程序,我从那里处理的文件,像:
procedure TMainForm.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ParamCount -1 do
  begin
    if SameText(ExtractFileExt(ParamStr(i)),'.ext1') then
    begin
      // handle my file..

      // break if needed
    end else
    if SameText(ExtractFileExt(ParamStr(i)),'.ext2') then
    begin
      // handle my file..

      // break if needed
    end else
  end;
end;

这几乎是我想要的,但是当我测试时,我意识到它不会考虑只使用我的程序的一个实例.

所以例如,如果我从Windows中选择了几个文件,并同时打开它们,这将创建与打开的文件数相同数量的程序实例.

这将是一个很好的方式来处理这个问题,所以我打开程序的几个实例,而不是被打开的Windows中的任何其他文件将简单地集中在一个唯一的实例上,我正常处理文件?

谢谢

UPDATE

我在这里发现了一个很好的文章:http://www.delphidabbler.com/articles?article=13&part=2,我认为是我需要的,并显示如何使用Windows API,如rhooligan所提到的.我现在要阅读

解决方法

这是一些简单的示例代码,可以完成工作.我希望这是不言自明的.
program StartupProject;

uses
  SysUtils,Messages,Windows,Forms,uMainForm in 'uMainForm.pas' {MainForm};

{$R *.res}

procedure Main;
var
  i: Integer;
  Arg: string;
  Window: HWND;
  CopyDataStruct: TCopyDataStruct;
begin
  Window := FindWindow(SWindowClassName,nil);
  if Window=0 then begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TMainForm,MainForm);
    Application.Run;
  end else begin
    FillChar(CopyDataStruct,Sizeof(CopyDataStruct),0);
    for i := 1 to ParamCount do begin
      Arg := ParamStr(i);
      CopyDataStruct.cbData := (Length(Arg)+1)*SizeOf(Char);
      CopyDataStruct.lpData := PChar(Arg);
      SendMessage(Window,WM_COPYDATA,NativeInt(@CopyDataStruct));
    end;
    SetForegroundWindow(Window);
  end;
end;

begin
  Main;
end.
unit uMainForm;

interface

uses
  Windows,SysUtils,Classes,Controls,StdCtrls;

type
  TMainForm = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WMCopyData(var Message: TWMCopyData); message WM_COPYDATA;
  public
    procedure ProcessArgument(const Arg: string);
  end;

var
  MainForm: TMainForm;

const
  SWindowClassName = 'VeryUniqueNameToAvoidUnexpectedCollisions';

implementation

{$R *.dfm}

{ TMainForm }

procedure TMainForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WinClassName := SWindowClassName;
end;

procedure TMainForm.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  for i := 1 to ParamCount do begin
    ProcessArgument(ParamStr(i));
  end;
end;

procedure TMainForm.ProcessArgument(const Arg: string);
begin
  ListBox1.Items.Add(Arg);
end;

procedure TMainForm.WMCopyData(var Message: TWMCopyData);
var
  Arg: string;
begin
  SetString(Arg,PChar(Message.CopyDataStruct.lpData),(Message.CopyDataStruct.cbData div SizeOf(Char))-1);
  ProcessArgument(Arg);
  Application.Restore;
  Application.BringToFront;
end;

end.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读