gpt4 book ai didi

delphi - 防止多个实例 - 但还要处理命令行参数?

转载 作者:行者123 更新时间:2023-12-03 14:39:05 25 4
gpt4 key购买 nike

我正在从我的应用程序处理来自 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 中的任何其他文件将简单地集中回唯一的实例,并且我可以正常处理文件?

谢谢

更新

我在这里找到了一篇好文章:http://www.delphidabbler.com/articles?article=13&part=2我认为这就是我所需要的,并展示了如何使用 rhooligan 提到的 Windows API。我现在要通读它..

最佳答案

这里是一些完成工作的简单示例代码。我希望它是不言自明的。

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, 0, NativeInt(@CopyDataStruct));
end;
SetForegroundWindow(Window);
end;
end;

begin
Main;
end.

 

unit uMainForm;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, Forms, 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.

关于delphi - 防止多个实例 - 但还要处理命令行参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8688078/

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