Inicjowanie programów obsługi rozszerzeń powłoki
Większość implementacji obiektu obsługi rozszerzenia powłoki jest dyktowana przez jego typ. Istnieją jednak pewne typowe elementy. W tym temacie omówiono te aspekty implementacji, które są współużytkowane przez wszystkie programy obsługi rozszerzeń powłoki.
Wszystkie wewnątrzprocesowe programy obsługi rozszerzeń powłoki są obiektami modelu obiektów komponentu (Component Object Model, COM). Muszą być przypisane identyfikatory GUID i zarejestrowane zgodnie z opisem w Rejestrowanie programów obsługi rozszerzeń powłoki. Są one implementowane jako biblioteki DLL i muszą eksportować następujące standardowe funkcje:
- DllMain. Standardowy punkt wejścia do biblioteki DLL.
- DllGetClassObject. Uwidacznia fabrykę klas obiektu.
- DllCanUnloadNow. Com wywołuje tę funkcję, aby określić, czy obiekt obsługuje jakichkolwiek klientów. Jeśli nie, system może zwolnić bibliotekę DLL i zwolnić skojarzoną pamięć.
Podobnie jak wszystkie obiekty COM, programy obsługi rozszerzeń powłoki muszą implementować interfejs IUnknown i fabrykę klas . Większość musi również zaimplementować interfejs IPersistFile lub IShellExtInit w systemie Windows XP lub starszym. Zostały one zastąpione przez IInitializeWithStream, IInitializeWithItem i IInitializeWithFile w systemie Windows Vista. Powłoka używa tych interfejsów do inicjowania obsługi.
Interfejs IPersistFile musi zostać zaimplementowany przez następujące elementy:
- Programy obsługi ikon
- Programy obsługi danych
- Programy obsługi porzucania
Interfejs IShellExtInit musi zostać zaimplementowany przez następujące elementy:
- Programy obsługi menu skrótów
- Programy obsługi przeciągania i upuszczania
- Programy obsługi kart właściwości
W pozostałej części tego tematu omówiono następujące tematy:
- Implementacja IPersistFile
- Implementowanie IShellExtInit
- dostosowywania etykietek informacji
- Tematy pokrewne
Implementowanie pliku IPersistFile
Interfejs IPersistFile został zaprojektowany tak, aby umożliwić załadowanie obiektu z pliku dysku lub zapisanie go. Ma sześć metod oprócz IUnknown, pięć własnych i GetClassID metodę, którą dziedziczy z IPersist. W przypadku rozszerzeń powłoki IPersist służy tylko do inicjowania obiektu obsługi rozszerzeń powłoki. Ponieważ zwykle nie trzeba odczytywać ani zapisywać na dysku, tylko metody GetClassID i Load wymagają implementacji nietokenizowanej.
Powłoka najpierw wywołuje GetClassID, a funkcja zwraca identyfikator klasy (CLSID) obiektu programu obsługi rozszerzeń. Następnie powłoka wywołuje Load i przekazuje dwie wartości. Pierwszy, pszFile, to ciąg Unicode zawierający nazwę pliku lub folderu, na którym powłoka systemowa ma operować. Drugi to dwMode, który wskazuje tryb dostępu do plików. Ponieważ zwykle nie ma potrzeby uzyskiwania dostępu do plików, dwMode zwykle wynosi zero. Metoda przechowuje te wartości zgodnie z potrzebami do późniejszego odwołania.
Poniższy fragment kodu ilustruje, jak typowy program obsługi rozszerzenia powłoki implementuje metody GetClassID oraz Load. Jest przeznaczony do obsługi ANSI lub Unicode. CLSID_SampleExtHandler jest identyfikatorem GUID obiektu programu obsługi rozszerzeń, a CSampleShellExtension jest nazwą klasy używanej do implementowania interfejsu. Zmienne m_szFileName i m_dwMode to zmienne prywatne, które są używane do przechowywania nazw i flag dostępu pliku.
class CSampleShellExtension : public IPersistFile
{
// Method declarations not included
private:
WCHAR m_szFileName[MAX_PATH]; // The file name
DWORD m_dwMode; // The file access mode
}
IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
*pCLSID = CLSID_SampleExtHandler;
}
IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
m_dwMode = dwMode;
return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile);
}
// The implementation sample is continued in the next section.
Implementowanie interfejsu IShellExtInit
Interfejs IShellExtInit ma tylko jedną metodę, IShellExtInit::Initialize, oprócz IUnknown. Metoda ma trzy parametry, których powłoka może używać do przekazywania różnych typów informacji. Przekazane wartości zależą od typu programu obsługi, a niektóre można ustawić na wartość null.
- pidlFolder przechowuje wskaźnik folderu do listy identyfikatorów elementów (PIDL). Jest to bezwzględny PIDL. W przypadku rozszerzeń arkusza właściwości ta wartość to NULL. W przypadku rozszerzeń menu skrótów jest to PIDL folderu, który zawiera element, którego menu skrótów jest wyświetlane. W przypadku programów obsługi przeciągania i upuszczania niezdefiniowania jest to piDL folderu docelowego.
- pDataObject przechowuje wskaźnik do interfejsu IDataObject obiektu danych. Obiekt danych zawiera co najmniej jedną nazwę pliku w formacie CF_HDROP.
- hRegKey zawiera klucz rejestru dla typu obiektu lub folderu pliku.
Metoda IShellExtInit::Initialize przechowuje nazwę pliku, wskaźnik IDataObject i klucz rejestru w razie potrzeby do późniejszego użycia. Poniższy fragment kodu ilustruje implementację IShellExtInit::Initialize. Dla uproszczenia w tym przykładzie przyjęto założenie, że obiekt danych zawiera tylko jeden plik. Ogólnie rzecz biorąc, obiekt danych może zawierać wiele plików, z których każdy będzie musiał zostać wyodrębniony.
// This code continues the CSampleShellExtension sample shown in the
// "Implementing IPersistFile" section above.
class CSampleShellExtension : public IShellExtInit
{
// Method declarations not included
private:
// IDList of the folder for extensions invoked on the folder, such as
// background context menu handlers or nondefault drag-and-drop handlers.
PIDLIST_ABSOLUTE m_pidlFolder;
// The data object contains an expression of the items that the handler is
// being initialized for. Use SHCreateShellItemArrayFromDataObject to
// convert this object to an array of items. Use SHGetItemFromObject if you
// are only interested in a single Shell item. If you need a file system
// path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
IDataObject *m_pdtobj;
// For context menu handlers, the registry key provides access to verb
// instance data that might be stored there. This is a rare feature to use
// so most extensions do not need this variable.
HKEY m_hRegKey;
}
// This method must be very efficient. Do not do any unnecessary work here.
// Use Initialize to acquire resources that will be used later.
IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt PCIDLIST_ABSOLUTE pidlFolder,
__in_opt IDataObject *pDataObject,
__in_opt HKEY hRegKey)
{
// In some cases, handlers are initialized multiple times. Therefore,
// clear any previous state here.
CoTaskMemFree(m_pidlFolder);
m_pidlFolder = NULL;
if (m_pdtobj)
{
m_pdtobj->Release();
}
if (m_hRegKey)
{
RegCloseKey(m_hRegKey);
m_hRegKey = NULL;
}
// Capture the inputs for use later.
HRESULT hr = S_OK;
if (pidlFolder)
{
m_pidlFolder = ILClone(pidlFolder); // Make a copy to use later.
hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
// If a data object pointer was passed into the method, save it and
// extract the file name.
if (pDataObject)
{
m_pdtobj = pDataObject;
m_pdtobj->AddRef();
}
// It is uncommon to use the registry handle, but if you need it,
// duplicate it now.
if (hRegKey)
{
LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey);
hr = HRESULT_FROM_WIN32(result);
}
}
return hr;
}
Dostosowywanie etykietki informacji
Istnieją dwa sposoby dostosowywania podpowiedzi. Jednym ze sposobów jest zaimplementowanie obiektu obsługującego IQueryInfo, a następnie zarejestrowanie obiektu w odpowiednim podkluczu w rejestrze (patrz poniżej). Alternatywnie można określić stały ciąg lub listę niektórych właściwości pliku, które mają być wyświetlane.
Aby wyświetlić stały ciąg rozszerzenia przestrzeni nazw, utwórz podklucz o nazwie InfoTip pod kluczem CLSID rozszerzenia przestrzeni nazw. Ustaw dane tego podklucza na ciąg, który chcesz wyświetlić.
HKEY_CLASSES_ROOT
CLSID
{CLSID}
InfoTip = InfoTip string for your namespace extension
Aby wyświetlić stały napis dla typu pliku, utwórz podklucz o nazwie InfoTip pod kluczem ProgID typu pliku, dla którego chcesz podać infopodpowiedzi. Ustaw dane tego podklucza na ciąg, który chcesz wyświetlić.
HKEY_CLASSES_ROOT
ProgID
InfoTip = InfoTip string for all files of this type
Jeśli chcesz, aby powłoka wyświetlała określone właściwości pliku w etykietce informacji dla określonego typu pliku, utwórz podklucz o nazwie InfoTip pod kluczem ProgID tego typu pliku. Ustaw dane tego podklucza jako rozdzieloną średnikami listę nazw właściwości kanonicznych lub {fmtid}, par pid, w których propname jest nazwą właściwości kanonicznej, a {fmtid},pid jest parą FMTID/PID.
HKEY_CLASSES_ROOT
ProgID
InfoTip = propname;propname;{fmtid},pid;{fmtid},pid
Można użyć następujących nazw właściwości.
Nazwa właściwości | Opis | Pobrano z |
---|---|---|
Autor | Autor dokumentu | PIDSI_AUTHOR |
Tytuł | Tytuł dokumentu | PIDSI_TITLE |
Temat | Podsumowanie tematu | PIDSI_SUBJECT |
Komentarz | Komentarze do dokumentu | PIDSI_COMMENT lub właściwości folderu/dysku |
LiczbaStron | Liczba stron | PIDSI_PAGECOUNT |
Nazwa | Przyjazna nazwa | Standardowy widok folderu |
Oryginalna lokalizacja | Lokalizacja oryginalnego pliku | Folder aktówki i folder Kosza |
Data usunięcia | Data usunięcia pliku | Kosz |
Typ | Typ pliku | Widok szczegółów folderu standardowego |
Rozmiar | Rozmiar pliku | Widok szczegółów folderu standardowego |
SyncCopyIn | Tak samo jak OriginalLocation | Tak samo jak OriginalLocation |
Zmodyfikowano | Data ostatniej modyfikacji | Widok szczegółów folderu standardowego |
Utworzono | Data utworzenia | Widok szczegółów folderu standardowego |
Dostępne | Data ostatniego dostępu | Widok szczegółów folderu standardowego |
InFolder | Katalog zawierający plik | Wyniki wyszukiwania dokumentów |
Ranga | Jakość dopasowania wyszukiwania | Wyniki wyszukiwania dokumentów |
Freespace | Dostępne miejsce do magazynowania | Napędy dysków |
LiczbaWizyt | Liczba wizyt | Folder Ulubione |
Atrybuty | Atrybuty pliku | Widok szczegółów folderu standardowego |
Firma | Nazwa firmy | PIDDSI_COMPANY |
Kategoria | Kategoria dokumentu | PIDDSI_CATEGORY |
Prawo autorskie | Prawa autorskie do multimediów | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | Plik podpowiedzi HTML | plik Desktop.ini dla folderu |
Tematy pokrewne