Sdílet prostřednictvím


Vytváření zpracovatelů miniatur

Ve Windows Vista je využití miniatur specifických pro soubory větší než v předchozích verzích Windows. Používají se ve všech zobrazeních, v dialozích a pro všechny typy souborů, které je poskytují. Zobrazení miniatury se také změnilo. Místo samostatných velikostí, jako jsou ikony a miniatury, je k dispozici souvislé spektrum velikostí s možností výběru uživatelů.

Rozhraní IThumbnailProvider zjednodušuje poskytování miniatur, což je snadnější než u starších IExtractImage nebo IExtractImage2. Upozorňujeme však, že stávající kód, který používá IExtractImage nebo IExtractImage2 je stále platný a podporovaný.

Ukázka ReceptThumbnailProvider

Ukázka RecipeThumbnailProvider v této části je součástí sady Windows Software Development Kit (SDK). Výchozí umístění instalace je C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WinUI\Shell\AppShellIntegration\RecipeThumbnailProvider. Tady je ale i část kódu.

Ukázka RecipeThumbnailProvider ukazuje implementaci obslužné rutiny miniatur pro nový typ souboru zaregistrovaného s příponou .recept. Ukázka demonstruje použití různých API pro obsluhu miniatur k registraci serverů COM (Component Object Model) k extrakci miniatur specifických typů souborů. Toto téma vás provede ukázkovým kódem a zvýrazní možnosti kódování a pokyny.

Obsluha miniatur musí vždy implementovat IThumbnailProvider ve spojení s jedním z těchto rozhraní:

Existují případy, kdy inicializace s datovými proudy není možná. Ve scénářích, kdy váš zpracovatel miniatur neimplementuje IInitializeWithStream, musí se rozhodnout nepracovat v izolovaném procesu, kam jej systémový indexer ve výchozím nastavení umístí při změně datového proudu. Chcete-li se odhlásit z funkce izolace procesu, nastavte následující hodnotu registru.

HKEY_CLASSES_ROOT
   CLSID
      {The CLSID of your thumbnail handler}
         DisableProcessIsolation = 1

Pokud implementujete IInitializeWithStream a provedete inicializaci založenou na datových proudech, je obslužná rutina bezpečnější a spolehlivější. Zakázání izolace procesů je obvykle určeno pouze pro starší obslužné rutiny; vyhněte se zakázání této funkce pro jakýkoli nový kód. IInitializeWithStream by mělo být vaší první volbou rozhraní inicializace, kdykoli je to možné.

Vzhledem k tomu, že soubor obrázku v ukázce není vložen do souboru .recept a není součástí jeho streamu souboru, IInitializeWithItem se používá v ukázce. Implementace metody IInitializeWithItem::Initialize jednoduše předává své parametry do privátních proměnných třídy.

IThumbnailProvider má pouze jednu metodu –GetThumbnail– která se volá s největší požadovanou velikostí obrázku v pixelech. Přestože se parametr jmenuje cx, jeho hodnota se používá jako maximální velikost rozměru x i y obrázku. Pokud načtená miniatura není čtvercová, je delší osa omezená cx a poměr stran původního obrázku se zachová.

Když se vrátí, GetThumbnail poskytuje popisovač načteného obrázku. Poskytuje také hodnotu, která označuje barevný formát obrázku a jestli obsahuje platné alfa informace.

Implementace GetThumbnail v ukázce začíná voláním privátní _GetBase64EncodedImageString metody.

IFACEMETHODIMP CRecipeThumbProvider::GetThumbnail(UINT cx, 
                                                  HBITMAP *phbmp, 
                                                  WTS_ALPHATYPE *pdwAlpha)
{
    PWSTR pszBase64EncodedImageString;
    HRESULT hr = _GetBase64EncodedImageString(cx, &pszBase64EncodedImageString);

Typ souboru .recept je jednoduše soubor XML zaregistrovaný jako jedinečná přípona názvu souboru. Obsahuje prvek s názvem Picture, který poskytuje relativní cestu a název souboru obrázku, který se má použít jako miniatura pro tento konkrétní soubor .recept. Element Picture se skládá z atributu Source, který určuje základní 64 kódovaný obrázek a volitelný atribut Size.

Velikost má dvě hodnoty: Malá a Velká. To vám umožní poskytnout více uzlů obrázků a s rozdílnými obrázky. Načtený obrázek poté závisí na maximální velikosti (cx) zadané ve volání GetThumbnail. Vzhledem k tomu, že Systém Windows nikdy velikost obrázku nezvětší, než je maximální velikost, lze různé obrázky poskytnout pro různá rozlišení. Pro jednoduchost však ukázka vynechá atribut Size a poskytuje pouze jeden obrázek pro všechny situace.

Metoda _GetBase64EncodedImageString, jejíž implementace je zde zobrazena, používá rozhraní API XML Document Object Model (DOM) k vyhledání uzlu Picture. Z daného uzlu extrahuje obraz z dat atributu Zdroj .

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 pak předá načtený řetězec do _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);

Metoda _GetStreamFromString, jejíž implementace je zde zobrazena, která převádí kódovaný obrázek na datový proud.

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 pak pomocí rozhraní WIC (Windows Imaging Component) API extrahuje rastrový obrázek z datového proudu a získá popisovač tohoto rastrového obrázku. Nastaví se informace o alfě, WIC se správně ukončí a metoda byla úspěšně ukončena.

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;
}

obslužné programy miniatur

Pokyny ke správci miniatur

IID_PPV_ARGS