我正在处理从
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.