Uzyskiwanie informacji o zawartości folderu
Sekcja Uzyskiwanie identyfikatora folderu omówiła dwie metody pobierania wskaźnika obiektu przestrzeni nazw do listy identyfikatorów elementów (PIDL). Jednym z oczywistych pytań jest: Gdy masz PIDL, co można z tym zrobić? Powiązane pytanie brzmi: Co zrobić, jeśli żadna z metod nie działa lub jest odpowiednia dla aplikacji? Odpowiedź na oba pytania wymaga bliższego przyjrzenia się implementacji przestrzeni nazw. Kluczem jest interfejs IShellFolder.
- Przy użyciu interfejsu IShellFolder
- wyliczanie zawartości folderu
- określanie nazw wyświetlanych i innych właściwości
- Uzyskiwanie wskaźnika do interfejsu IShellFolder dla podfoldera
- Określanie folderu nadrzędnego obiektu
Korzystanie z interfejsu IShellFolder
Wcześniej w tej dokumentacji foldery przestrzeni nazw były nazywane obiektami. Chociaż wówczas termin został użyty w luźnym sensie, jest on rzeczywiście prawdziwy w ścisłym sensie. Każdy folder przestrzeni nazw jest reprezentowany przez obiekt Modelu obiektów składników (COM). Każdy obiekt folderu uwidacznia szereg interfejsów, które mogą być używane w wielu różnych zadaniach. Niektóre interfejsy, które są opcjonalne, mogą nie być uwidocznione przez wszystkie foldery. Jednak wszystkie foldery muszą uwidocznić podstawowy interfejs, IShellFolder.
Pierwszym krokiem w korzystaniu z obiektu folderu jest pobranie wskaźnika do interfejsu IShellFolder. Oprócz zapewnienia dostępu do innych interfejsów obiektu, IShellFolder uwidacznia grupę metod, które obsługują wiele typowych zadań, z których kilka zostało omówionych w tej sekcji.
Aby pobrać wskaźnik do interfejsu IShellFolder obiektu przestrzeni nazw, należy najpierw wywołać SHGetDesktopFolder. Ta funkcja zwraca wskaźnik do interfejsu IShellFolder korzenia przestrzeni nazw, czyli pulpitu. Gdy masz interfejs IShellFolder pulpitu, istnieje wiele sposobów kontynuowania.
Jeśli masz już kod PIDL folderu, który cię interesuje — na przykład wywołując SHGetFolderLocation— możesz pobrać jego interfejs IShellFolder przez wywołanie IShellFolder pulpitu::BindToObject metody. Jeśli masz ścieżkę obiektu systemu plików, musisz najpierw uzyskać jego kod PIDL, wywołując metodę IShellFolder::ParseDisplayName, a następnie IShellFolder::BindToObject. Jeśli żadna z tych metod nie ma zastosowania, możesz użyć innych metod IShellFolder, aby nawigować po przestrzeni nazw. Aby uzyskać więcej informacji, zobacz Nawigowanie po przestrzeni nazw.
Wyliczanie zawartości folderu
Pierwszą rzeczą, którą zwykle chcesz zrobić z folderem, jest dowiedzenie się, co zawiera. Najpierw należy wywołać metodę IShellFolder::EnumObjects folderu. Folder utworzy standardowy obiekt wyliczenia OLE i zwróci interfejs IEnumIDList. Ten interfejs uwidacznia cztery standardowe metody —Clone, Next, Reseti Skip— które mogą służyć do wyliczania zawartości folderu.
Podstawową procedurą wyliczania zawartości folderu jest:
- Wywołaj metodę IShellFolder::EnumObjects w folderach , aby pobrać wskaźnik do interfejsu IEnumIDList obiektu wyliczenia .
- Przekaż nieprzydzielony kod PIDL do IEnumIDList::Next. Next zajmuje się przydzielaniem kodu PIDL, ale aplikacja musi cofnąć jej przydział, gdy nie jest już potrzebny. Po powrocie Next PIDL będzie zawierać tylko identyfikator elementu obiektu oraz kończące znaki NULL. Innymi słowy, jest to jednopoziomowy PIDL względem folderu, a nie w pełni kwalifikowany PIDL.
- Powtarzaj krok 2, aż zwróci S_FALSE, co wskaże, że wszystkie elementy zostały wyliczone.
- W celu zwolnienia obiektu wyliczenia wywołaj IEnumIDList::Release.
Notatka
Ważne jest, aby śledzić, czy pracujesz z pełnym lub względnym numerem PIDL. Niektóre funkcje i metody zaakceptują jeden z dwóch, ale inne będą przyjmować tylko jedną lub drugą.
Pozostałe trzy metody IEnumIDList (Resetuj, Pomińi Clone) są przydatne, jeśli trzeba wykonać powtarzające się wyliczenia folderu. Umożliwiają one zresetowanie wyliczenia, pominięcie co najmniej jednego obiektu i utworzenie kopii obiektu wyliczenia w celu zachowania jego stanu.
Określanie nazw wyświetlanych i innych właściwości
Po wyliczeniu wszystkich PIDL zawartych w folderze można dowiedzieć się, jakie obiekty reprezentują. InterfejsIShellFolderudostępnia wiele przydatnych metod, z których dwa zostały omówione tutaj. Inne metody IShellFolder i inne interfejsy powłoki Shell są omówione w dalszej części.
Jedną z najbardziej przydatnych właściwości jest nazwa wyświetlana obiektu. Aby pobrać nazwę wyświetlaną obiektu, przekaż jego nazwę PIDL do IShellFolder::GetDisplayNameOf. Mimo że obiekt może znajdować się w dowolnym miejscu poniżej folderu nadrzędnego w przestrzeni nazw, jego kod PIDL musi być względny względem folderu.
IShellFolder::GetDisplayNameOf zwraca nazwę wyświetlaną w ramach struktury STRRET. Ponieważ wyodrębnianie nazwy wyświetlanej ze struktury STRRET może być trochę trudne, powłoka zapewnia dwie funkcje, które wykonują to zadanie za ciebie: StrRetToStr i StrRetToBuf. Obie funkcje przyjmują strukturę STRRET i zwracają nazwę wyświetlaną jako zwykły ciąg. Różnią się one tylko sposobem przydzielania ciągu.
Oprócz nazwy wyświetlanej obiekt może mieć wiele atrybutów, na przykład czy jest to folder, czy można go przenieść. Atrybuty obiektu można pobrać, przekazując jego identyfikator PIDL do IShellFolder::GetAttributesOf. Powinnaś zobaczyć odniesienie dla szczegółów, ponieważ pełna lista atrybutów jest dość obszerna. Należy pamiętać, że kod PIDL przekazywany do GetAttributesOf musi być jednopoziomowy. W szczególności IShellFolder::GetAttributesOf zaakceptuje PIDLs zwrócone przez IEnumIDList::Next. Można przekazać tablicę PIDLs, a GetAttributesOf zwróci te atrybuty, które są wspólne dla wszystkich obiektów w tablicy.
Jeśli masz w pełni kwalifikowaną ścieżkę obiektu lub kod PIDL, SHGetFileInfo zapewnia prosty sposób pobierania informacji o obiekcie, który jest wystarczający do wielu celów. SHGetFileInfo przyjmuje w pełni kwalifikowaną ścieżkę lub PIDL i zwraca różne informacje o obiekcie, w tym:
- Nazwa wyświetlana obiektu
- Atrybuty obiektu
- Dojście do ikon obiektu
- Dojście do listy obrazów systemowych
- Ścieżka pliku zawierającego ikonę obiektu
Uzyskiwanie wskaźnika do interfejsu IShellFolder tego podfoldera
Możesz określić, czy folder zawiera jakiekolwiek podfoldery, wywołując IShellFolder::GetAttributesOf i sprawdzając, czy ustawiono flagę SFGAO_FOLDER. Jeśli obiekt jest folderem, można się do niego odwołać, co zapewnia wskaźnik do jego interfejsu IShellFolder.
Aby powiązać z podfolderem, wywołaj metodęfolderu nadrzędnegoIShellFolder::BindToObject. Ta metoda pobiera identyfikator PIDL podfoldera i zwraca wskaźnik do interfejsu IShellFolder. Po utworzeniu tego wskaźnika można użyć metod IShellFolder, aby wyliczyć zawartość podfolderów, określić ich właściwości itd.
Określanie folderu nadrzędnego obiektu
Jeśli masz plik PIDL obiektu, może być konieczne dojście do jednego z interfejsów uwidocznionych przez jego folder nadrzędny. Jeśli na przykład chcesz określić nazwę wyświetlaną skojarzoną z identyfikatorem PIDL przy użyciu IShellFolder::GetDisplayNameOf, musisz najpierw pobrać interfejs IShellFolder obiektu nadrzędnego. Można to zrobić za pomocą technik omówionych w poprzednich sekcjach. Jednak znacznie prostszą metodą jest użycie funkcji Shell, SHBindToParent. Ta funkcja pobiera w pełni kwalifikowaną nazwę PIDL obiektu i zwraca określony wskaźnik interfejsu w folderze nadrzędnym. Opcjonalnie zwraca również jednopoziomowy identyfikator PIDL elementu do użycia w metodach takich jak IShellFolder::GetAttributesOf.
Poniższa przykładowa aplikacja konsolowa pobiera kod PIDL folderu specjalnego System i zwraca jego nazwę wyświetlaną.
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream.h>
#include <objbase.h>
int main()
{
IShellFolder *psfParent = NULL;
LPITEMIDLIST pidlSystem = NULL;
LPCITEMIDLIST pidlRelative = NULL;
STRRET strDispName;
TCHAR szDisplayName[MAX_PATH];
HRESULT hr;
hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);
hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);
if(SUCCEEDED(hr))
{
hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);
hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));
cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';
}
psfParent->Release();
CoTaskMemFree(pidlSystem);
return 0;
}
Aplikacja najpierw używa SHGetFolderLocation w celu pobrania pliku PIDL folderu System. Następnie wywołuje SHBindToParent, która zwraca wskaźnik do interfejsu IShellFolder folderu nadrzędnego oraz identyfikator PIDL folderu System względem jego folderu nadrzędnego. Następnie używa metody IShellFolder::GetDisplayNameOf folderu nadrzędnego, aby pobrać nazwę wyświetlaną folderu System. Ponieważ GetDisplayNameOf zwraca strukturę STRRET, strRetToBuf jest używana do konwertowania nazwy wyświetlanej na normalny ciąg. Po wyświetleniu nazwy wyświetlanej wskaźniki interfejsu są zwalniane, a System PIDL jest zwalniany. Należy pamiętać, że nie można zwolnić względnego kodu PIDL zwróconego przez SHBindToParent.