Jak pobrać nazwy plików w koszu
reichel
Zazwyczaj pobieranie listy plików robi się z wykorzystaniem funkcji FindFirst i FindNext. W przypadku kosza jednak dają one dziwne nazwy (w stylu Dd1.html dla jakiegoś pliku html). Z pomocą przychodzi interfejs ISHellFolder oraz funkcja GetDisplayNameOf. Dzięki temu możemy poznać prawdziwą nazwę pliku (przykład poniżej).
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses ShlObj, ShellAPI, ActiveX;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hr:HRESULT;
pMalloc: IMalloc;
SFRecycleBin,SFDesktop:IShellFolder;
EnumIDList:IEnumIDList;
pidl,RecycleBinIDList:PItemIDList;
olePath:PWideChar;
fetched:Cardinal;
FD:WIN32_FIND_DATA;
StrResult:TStrRet;
ItemName:String;
begin
hr := CoInitialize(nil);
hr := SHGetMalloc(pMalloc);
hr := SHGetDesktopFolder(SFDesktop);
hr := SHGetSpecialFolderLocation(Handle, CSIDL_BITBUCKET, RecycleBinIDList);
hr := SFDesktop.BindToObject(RecycleBinIDList, nil, IID_IShellFolder, SFRecycleBin);
//wazne aby byly nonfolders
hr := SFRecycleBin.EnumObjects(Handle, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN, EnumIDList);
repeat
hr := EnumIDList.Next(1, pidl, fetched);
if (hr = NOERROR) then
begin
//pobieramy nazwe jaka mial plik
SFRecycleBin.GetDisplayNameOf(pidl,SHGDN_NORMAL,StrResult);
case StrResult.uType of
0: begin
ItemName := WideCharToString(StrResult.pOleStr);
pMalloc.Free(StrResult.pOleStr);
end;
1: ItemName := PChar(pidl)+StrResult.uOffset;
2: ItemName := StrResult.cStr;
end;
hr := SHGetDataFromIDList(SFRecycleBin, pidl, SHGDFIL_FINDDATA, @FD, sizeof(WIN32_FIND_DATA));
//nazwa pliku i przyjazna nazwa
ListBox1.Items.Add(FD.cFileName + ' '+ ExtractFileName(ItemName));
pMalloc.Free(pidl);
end;
until (hr <> NOERROR);
EnumIDList := nil;
SFRecycleBin := nil;
SFDesktop := nil;
pMalloc := nil;
CoUninitialize();//wlasciwie jest w ktoryms z drugich uses unitow.
end;
end.
Na forme kładziemy Button i Listbox'a. W nim pojawia się najpierw dziwna
nazwa a potem właściwa.
ps. Mozna jeszcze zainteresowac sie interfejsem IShellFolder2 (wiecej szczegółów).
ps2. Niestety interfejs (a przynajmniej tak zachowuje sie w windows) nie listuje plików wewnątrz folderów. Tu chyba pozostaje dłubanie w bazie danych kosza umieszczonej w pliku INFO2 (przynajmniej od Windows ME).
ps3. Co prawda wyglada na to, że w folderach usuniętych plik zachowują swoją nazwę orginalną. Tak więc po znależieniu folderów w koszu można wylistować pliki (normalnie
) aby utworzyć drzewo.