function TListBox.GetFileListDataObject(APath:
string; AFileNames: TStrings): IDataObject;
Type
PPItemIDList = ^PItemIDList;
var
Desktop: IShellFolder;
Eaten, Attr: ULONG;
i: Integer;
PathIDList: PItemIDList;
PathShellFolder: IShellFolder;
IDLists: PPItemIDList;
IDListsSize: Integer;
Posi: PPItemIDList;
pbc : IBindCtx;
w32fd : TWin32FindDataW;
ifs : TFileSystemBindData;
r : HResult;
FDO : TWin32FindDataW;
ShellFolder: IShellFolder;
BindContext: IBindCtx;
begin
PathConvertShort(APath);
if Pos ('
UNC',APath) > 0
Then
Begin
apath := '
\\'+copy(apath,5);
End;
Result :=
nil;
if AFileNames.Count < 1
then Exit;
R := SHGetDesktopFolder(Desktop);
if R = S_OK
then
Begin
Attr := 0;
ZeroMemory(@FDO, Sizeof(TWin32FindDataW));
FDO.DWFileAttributes := FILE_ATTRIBUTE_DIRECTORY;;
StrCopy(FDO.cFileName,PWideChar(APath));
Ifs := TFileSystemBindData.Create;
ifs.fw32fd := FDO;
If CreateBindCtx(0,Pbc) = S_OK
Then
Begin
If Pbc.RegisterObjectParam(STR_FILE_SYS_BIND_DATA,Ifs) = S_OK
Then
Begin
R := Desktop.ParseDisplayName(0,Pointer(Pbc),PWideChar(APath),Eaten,PathIDList,Attr);
If R = S_OK
Then
Begin
R := Desktop.BindToObject(PathIDList, Pointer(pbc), IShellFolder, PathShellFolder);
If R = S_OK
Then
Begin
IDListsSize := SizeOf(PItemIDList) * AFileNames.Count;
GetMem(IDLists, IDListsSize);
ZeroMemory(IDLists, IDListsSize);
Posi := IDLists;
for i := 0
to AFileNames.Count - 1
do
begin
Attr := 0;
//FILE_ATTRIBUTE_NORMAL;;
ZeroMemory(@FDO, Sizeof(TWin32FindDataW));
FDO.DWFileAttributes := 0;
//FILE_ATTRIBUTE_NORMAL;
StrCopy(FDO.cFileName,PWideChar(AFileNames[i]));
Ifs := TFileSystemBindData.Create;
Ifs.fw32fd := FDO;
CreateBindCtx(0, BindContext);
BindContext.RegisterObjectParam(STR_FILE_SYS_BIND_DATA, IFs);
R := PathShellFolder.ParseDisplayName(0, Pointer(BindContext), PWideChar(AFileNames[i]), Eaten, Posi^, Attr);
if R = S_OK
then Inc(Posi)
else
begin
f.caption := '
PathShellFolder.ParseDisplayName';
PathShellFolder :=
nil;
CoTaskMemFree(PathIDList);
Desktop :=
Nil;
Result :=
Nil;
Exit;
end;
end;
R := PathShellFolder.GetUIObjectOf(0, AFileNames.Count, IDLists^, IDataObject,
nil, Result);
if R = S_OK
Then
Begin
Posi := IDLists;
for i := 0
to AFileNames.Count - 1
do
begin
if Assigned(Posi^)
then CoTaskMemFree(Posi^);
Inc(Posi);
end;
FreeMem(IDLists);
End Else
Begin
PathShellFolder :=
nil;
Desktop :=
Nil;
CoTaskMemFree(PathIDList);
Result :=
Nil;
Exit;
End;
End Else
Begin
f.caption := '
BindToObject';
CoTaskMemFree(PathIDList);
Result :=
Nil;
End;
End Else
Begin
f.caption := '
Desktop.ParseDisplayName';
Desktop :=
Nil;
Result :=
Nil;
End;
End Else
Begin
f.caption := '
RegisterObjectParam';
Desktop :=
Nil;
Result :=
Nil;
End;
End Else
Begin
f.caption := '
CreateBindCtx';
Desktop :=
Nil;
Result :=
Nil;
End;
end Else Result :=
Nil;
end;