Miniatűrkezelők létrehozása
A Windows Vista esetében a fájlspecifikus miniatűrképek használata nagyobb, mint a Windows korábbi verzióiban. Ezek minden nézetben, párbeszédpanelen és bármilyen fájltípusban használhatók, amelyek biztosítják őket. A miniatűr megjelenítése is megváltozott. A felhasználó által kiválasztható méretek folyamatos spektruma érhető el a különálló méretek, például ikonok és miniatűrök helyett.
Az IThumbnailProvider felület egyszerűbbé és gyorsabbá teszi a miniatűrök készítését, mint a régebbi IExtractImage vagy IExtractImage2. Vegye figyelembe azonban, hogy az IExtractImage vagy IExtractImage2 használó meglévő kód továbbra is érvényes és támogatott.
A "RecipeThumbnailProvider" példa
A RecipeThumbnailProvider ebben a szakaszban ismertetett minta a Windows Software Development Kit (SDK) része. Alapértelmezett telepítési helye a C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WinUI\Shell\AppShellIntegration\RecipeThumbnailProvider. A kód nagy része azonban itt is megtalálható.
A RecipeThumbnailProvider minta egy .recept kiterjesztéssel regisztrált új fájltípus miniatűrkezelőjének implementálását mutatja be. A minta bemutatja, hogyan használják a miniatűrkezelő API-kat a miniatűr-kinyerési összetevő objektummodell (COM) kiszolgálók regisztrálására az egyéni fájltípusokhoz. Ez a témakör végigvezeti a mintakódon, kiemelve a kódolási lehetőségeket és az irányelveket.
A miniatűr kezelőjének mindig implementálnia kell IThumbnailProvider az alábbi felületek valamelyikével:
Vannak olyan esetek, amikor a streamekkel való inicializálás nem lehetséges. Olyan esetekben, amikor a miniatűr-kezelő nem implementálja IInitializeWithStream, ki kell lépnie az izolált folyamatból, ahová a rendszer indexelője automatikusan elhelyezi alapértelmezés szerint a stream módosításakor. A folyamatelkülönítési funkció letiltásához állítsa be a következő beállításjegyzék-értéket.
HKEY_CLASSES_ROOT
CLSID
{The CLSID of your thumbnail handler}
DisableProcessIsolation = 1
Ha implementálja IInitializeWithStream, és streamalapú inicializálást végez, a kezelő biztonságosabb és megbízhatóbb. A folyamatelkülönítés letiltása általában csak az örökölt kezelők számára történik; ne tiltsa le ezt a funkciót minden új kód esetében. IInitializeWithStream legyen az első választott inicializálási felület, amikor csak lehetséges.
Mivel a mintában található képfájl nincs beágyazva a .recept fájlba, és nem része a fájlfolyamának, a IInitializeWithItem használják a mintában. Az IInitializeWithItem::Initialize metódus implementálása egyszerűen átadja a paramétereit a privát osztály változóinak.
IThumbnailProvider egyetlen metódussal rendelkezik–GetThumbnail–, amelyet a kép legnagyobb kívánt méretével, képpontban hívunk meg. Bár a paraméter neve cx, a rendszer a kép x és y dimenziójának maximális méreteként használja az értékét. Ha a lekért miniatűr nem négyzet, akkor a hosszabb tengelyt cx korlátozza, és az eredeti kép méretaránya megmarad.
Amikor visszatér, a GetThumbnail egy kezelőt biztosít a lekért képfájlhoz. Emellett olyan értéket is biztosít, amely jelzi a kép színformátumát, és hogy rendelkezik-e érvényes alfainformációkkal.
A minta GetThumbnail implementációja a privát _GetBase64EncodedImageString metódus meghívásával kezdődik.
IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx,
HBITMAP *phbmp,
WTS_ALPHATYPE *pdwAlpha)
{
PWSTR pszBase64EncodedImageString;
HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);
A .recipe fájltípus egyszerűen egy egyedi fájlnévkiterjesztésként regisztrált XML-fájl. Tartalmaz egy Kép nevű elemet, amely megadja a kép relatív elérési útját és fájlnevét, amelyet az adott .recept fájl miniatűrjeként használ. A Kép elem a Forrás attribútumból áll, amely egy 64-es alapkódolt képet, valamint egy választható Méret attribútumot tartalmaz.
Méret két értékkel rendelkezik: Kicsi és Nagy. Ez azt teszi lehetővé, hogy több Kép csomópontot hozzon létre külön képekkel. A lekért kép a GetThumbnailhívásában megadott maximális méretértéktől (cx) függ. Mivel a Windows soha nem méretezi meg a képet a maximális méreténél nagyobb méretnél, különböző képeket lehet biztosítani a különböző felbontásokhoz. Az egyszerűség kedvéért azonban a minta kihagyja a Size attribútumot, és minden helyzetben csak egy képet biztosít.
A _GetBase64EncodedImageString metódus, amelynek implementációja itt látható, XML Document Object Model (DOM) API-kkal kéri le a Picture csomópontot. Ebből a csomópontból kinyeri a képet a Forrás attribútum adataiból.
HRESULT CRecipeThumbProvider::_GetBase64EncodedImageString(UINT /* cx */,
PWSTR *ppszResult)
{
*ppszResult = NULL;
IXMLDOMDocument *pXMLDoc;
HRESULT hr = _LoadXMLDocument(&pXMLDoc);
if (SUCCEEDED(hr))
{
BSTR bstrQuery = SysAllocString(L"Recipe/Attachments/Picture");
hr = bstrQuery ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
IXMLDOMNode *pXMLNode;
hr = pXMLDoc->selectSingleNode(bstrQuery, &pXMLNode);
if (SUCCEEDED(hr))
{
IXMLDOMElement *pXMLElement;
hr = pXMLNode->QueryInterface(&pXMLElement);
if (SUCCEEDED(hr))
{
BSTR bstrAttribute = SysAllocString(L"Source");
hr = bstrAttribute ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
VARIANT varValue;
hr = pXMLElement->getAttribute(bstrAttribute, &varValue);
if (SUCCEEDED(hr))
{
if ((varValue.vt == VT_BSTR) && varValue.bstrVal && varValue.bstrVal[0])
{
hr = SHStrDupW(varValue.bstrVal, ppszResult);
}
else
{
hr = E_FAIL;
}
VariantClear(&varValue);
}
SysFreeString(bstrAttribute);
}
pXMLElement->Release();
}
pXMLNode->Release();
}
SysFreeString(bstrQuery);
}
pXMLDoc->Release();
}
return hr;
}
GetThumbnail ezután átadja a lekért sztringet _GetStreamFromString.
IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx,
HBITMAP *phbmp,
WTS_ALPHATYPE *pdwAlpha)
{
PWSTR pszBase64EncodedImageString;
HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);
if (SUCCEEDED(hr))
{
IStream *pImageStream;
hr = _GetStreamFromString(pszBase64EncodedImageString, &pImageStream);
A _GetStreamFromString metódus, amelynek implementációja itt látható, amely a kódolt rendszerképet streamké alakítja.
HRESULT CRecipeThumbProvider::_GetStreamFromString(PCWSTR pszImageName,
IStream **ppImageStream)
{
HRESULT hr = E_FAIL;
DWORD dwDecodedImageSize = 0;
DWORD dwSkipChars = 0;
DWORD dwActualFormat = 0;
// Base64-decode the string
BOOL fSuccess = CryptStringToBinaryW(pszImageName,
NULL,
CRYPT_STRING_BASE64,
NULL,
&dwDecodedImageSize,
&dwSkipChars,
&dwActualFormat);
if (fSuccess)
{
BYTE *pbDecodedImage = (BYTE*)LocalAlloc(LPTR, dwDecodedImageSize);
if (pbDecodedImage)
{
fSuccess = CryptStringToBinaryW(pszImageName,
lstrlenW(pszImageName),
CRYPT_STRING_BASE64,
pbDecodedImage,
&dwDecodedImageSize,
&dwSkipChars,
&dwActualFormat);
if (fSuccess)
{
*ppImageStream = SHCreateMemStream(pbDecodedImage,
dwDecodedImageSize);
if (*ppImageStream != NULL)
{
hr = S_OK;
}
}
LocalFree(pbDecodedImage);
}
}
return hr;
}
GetThumbnail ezután a Windows Képalkotó összetevő (WIC) API-kkal kinyer egy bitképet a streamből, és lekér egy fogópontot a bitképhez. Az alfainformáció be van állítva, a WIC megfelelően kilépett, és az eljárás sikeresen befejeződik.
IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx,
HBITMAP *phbmp,
WTS_ALPHATYPE *pdwAlpha)
{
PWSTR pszBase64EncodedImageString;
HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);
if (SUCCEEDED(hr))
{
IStream *pImageStream;
hr = _GetStreamFromString(pszBase64EncodedImageString, &pImageStream);
if (SUCCEEDED(hr))
{
hr = WICCreate32BitsPerPixelHBITMAP(pImageStream,
cx,
phbmp,
pdwAlpha);
pImageStream->Release();
}
CoTaskMemFree(pszBase64EncodedImageString);
}
return hr;
}