我写了个程序更改注册表使扩展名为abc的文件跟我写的程序关联,在注册表的Command里设置键值为:"C:\123.exe" "%1" (假设我的程序名为123.exe并且放在C:\底下),这样当在资源管理器中双击*.abc文件时系统就会自动运行我的程序,并向程序传递*.abc的路径。现在我的问题是:当用户在资源管理器中选中多个*.abc文件,然后点击右键菜单中的open,那样系统会多次运行123.exe,而且每次运行都将用户选中的*.abc文件中的其中一个的路径传递给程序,这样就会有多个实例在运行,而现在我需要在一个实例中处理所有用户要打开的文件,应该如何才好,请指教。
windows,
Messages,
system,
SysUtils,
Forms,
Unit1 in 'Unit1.pas' {MainForm};{$R *.res}
var
SendData: tagCOPYDATASTRUCT;begin
Application.Initialize;
CreateMutex(nil, True, 'MyApp');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
with SendData do
begin
cbData := Length(ParamStr(1)) + 1;
GetMem(lpData, cbData); //为传递的数据区分配内存
StrCopy(lpData, PChar(ParamStr(1)));
end;
SendMessage(FindWindow('TMainForm', nil), WM_COPYDATA, 0, integer(@SendData));
FreeMem(SendData.lpData); //释放资源 end
else
begin
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end;
end.主窗口中:
type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}{ TMainForm }
procedure TMainForm.FormCreate(Sender: TObject);
begin
if ParamStr(1) <> '' then
begin
//处理传送过来的文件名
end;
end;procedure TMainForm.WMCopyData(var Msg: TWMCopyData);
var
Txt: string;
begin
Txt := Trim(strpas(Msg.CopyDataStruct.lpData));
if Txt = '' then//如果为空,就显示主窗口
begin
Application.BringToFront ;
SetActiveWindow(Self.Handle);
end
else
begin
//否则就处理传送过来的文件名
end;
end;
end.
WM_COPYDATA 和 tagCOPYDATASTRUCT 这两样东西,请解释一下好吗?