Erstellen von Miniaturansichtshandlern

Ab Windows Vista werden dateispezifische Miniaturansichten stärker verwendet als in früheren Versionen von Windows. Sie werden in allen Ansichten, in Dialogfeldern und für alle Dateitypen verwendet, die sie bereitstellen. Die Miniaturansicht wurde ebenfalls geändert. Anstelle der diskreten Größen wie Symbole und Miniaturansichten ist ein kontinuierliches Spektrum von vom Benutzer auswählbaren Größen verfügbar.

Die IThumbnailProvider-Schnittstelle vereinfacht die Bereitstellung einer Miniaturansicht als die ältere IExtractImage- oder IExtractImage2-Schnittstelle. Beachten Sie jedoch, dass vorhandener Code, der IExtractImage oder IExtractImage2 verwendet, weiterhin gültig und unterstützt wird.

Das RecipeThumbnailProvider-Beispiel

Das in diesem Abschnitt beschriebene RecipeThumbnailProvider-Beispiel ist im Windows Software Development Kit (SDK) enthalten. Der Standardspeicherort für die Installation ist C: \ Programme \ Microsoft SDKs Windows \ \ v6.0 \ Samples \ WinUI Shell \ \ AppShellIntegration \ RecipeThumbnailProvider. Der Großteil des Codes ist jedoch auch hier enthalten.

Das RecipeThumbnailProvider-Beispiel veranschaulicht die Implementierung eines Miniaturansichtshandlers für einen neuen Dateityp, der mit der Erweiterung .recipe registriert ist. Das Beispiel veranschaulicht die Verwendung der verschiedenen ApIs für den Miniaturansichtshandler, um miniaturansichtsextraktion Component Object Model (COM)-Server für benutzerdefinierte Dateitypen zu registrieren. In diesem Thema wird der Beispielcode beschrieben, in dem Codierungsoptionen und Richtlinien hervorgehoben werden.

Ein Miniaturansichtshandler muss IThumbnailProvider immer zusammen mit einer der folgenden Schnittstellen implementieren:

Es gibt Fälle, in denen die Initialisierung mit Streams nicht möglich ist. In Szenarien, in denen der Miniaturansichtshandler IInitializeWithStreamnicht implementiert, muss er die Ausführung im isolierten Prozess deaktivieren, in dem der Systemindexer es standardmäßig platziert, wenn eine Änderung am Stream erfolgt. Legen Sie den folgenden Registrierungswert fest, um die Prozessisolationsfunktion zu deaktivieren.

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

Wenn Sie IInitializeWithStream implementieren und eine streambasierte Initialisierung verwenden, ist Ihr Handler sicherer und zuverlässiger. In der Regel ist das Deaktivieren der Prozessisolation nur für Legacyhandler vorgesehen. Deaktivieren Sie dieses Feature nicht für neuen Code. IInitializeWithStream sollte nach Möglichkeit die erste Wahl der Initialisierungsschnittstelle sein.

Da die Bilddatei im Beispiel nicht in die RECIPE-Datei eingebettet ist und nicht Teil ihres Dateistreams ist, wird IInitializeWithItem im Beispiel verwendet. Die Implementierung der IInitializeWithItem::Initialize-Methode übergibt ihre Parameter einfach an private Klassenvariablen.

IThumbnailProvider verfügt nur über eine Methode(GetThumbnail),die mit der größten gewünschten Größe des Bilds in Pixel aufgerufen wird. Obwohl der -Parameter cx genannt wird, wird sein Wert als maximale Größe der x- und y-Dimensionen des Bilds verwendet. Wenn die abgerufene Miniaturansicht nicht quadratisch ist, wird die längere Achse durch cx eingeschränkt, und das Seitenverhältnis des ursprünglichen Bilds wird beibehalten.

Nach der Rückgabe stellt GetThumbnail ein Handle für das abgerufene Bild zur Hand. Außerdem wird ein Wert angegeben, der das Farbformat des Bilds angibt und ob es über gültige Alphainformationen verfügt.

Die GetThumbnail-Implementierung im Beispiel beginnt mit einem Aufruf der privaten _ GetBase64EncodedImageString-Methode.

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

Der .recipe-Dateityp ist einfach eine XML-Datei, die als eindeutige Dateierweiterung registriert ist. Es enthält ein Element namens Picture, das den relativen Pfad und Dateinamen des Bilds zur Verwendung als Miniaturansicht für diese bestimmte REZEPT-Datei enthält. Das Picture-Element besteht aus dem Source-Attribut, das ein Base64-codiertes Bild angibt, und einem optionalen Size-Attribut.

Die Größe hat zwei Werte: Klein und Groß. Dadurch können Sie mehrere Bildknoten mit separaten Bildern bereitstellen. Das abgerufene Bild hängt dann vom maximalen Größenwert (cx) ab, der im Aufruf von GetThumbnail bereitgestellt wird. Da Windows bildgröße nie größer als die maximale Größe ist, können unterschiedliche Bilder für unterschiedliche Auflösungen bereitgestellt werden. Der Einfachheit halber wird im Beispiel jedoch das Size-Attribut ausgelassen, und es wird nur ein Bild für alle Situationen angezeigt.

Die _ GetBase64EncodedImageString-Methode, deren Implementierung hier gezeigt wird, verwendet DOM-APIs (XML Dokumentobjektmodell), um den Picture-Knoten abzurufen. Von diesem Knoten wird das Bild aus den Quellattributdaten extrahiert.

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 übergibt dann die abgerufene Zeichenfolge an _ 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);

Die _ GetStreamFromString-Methode, deren Implementierung hier gezeigt wird, die das codierte Bild in einen Stream konvertiert.

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 verwendet dann Windows Imaging Component (WIC)-APIs, um eine Bitmap aus dem Stream zu extrahieren und ein Handle für diese Bitmap zu erhalten. Die Alphainformationen werden festgelegt, WIC wird ordnungsgemäß beendet, und die Methode wird erfolgreich beendet.

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

Miniaturansichtshandler

Richtlinien für Miniaturansichtshandler

IID _ PPV _ ARGS