Küçük Resim İşleyicileri Oluşturma

Windows Vista'dan itibaren dosyaya özgü küçük resim görüntüleri, Windows'un önceki sürümlerine göre daha fazla kullanılır. Bunlar tüm görünümlerde, iletişim kutusunda ve bunları sağlayan herhangi bir dosya türü için kullanılır. Küçük resimlerin gösterimi de değiştirildi. Simgeler ve Küçük Resimler gibi ayrık boyutlar yerine kullanıcı tarafından seçilebilen boyutların sürekli bir spektrumu kullanılabilir.

IThumbnailProvider arabirimi, küçük resim sağlamayı, eski IExtractImage veya IExtractImage2arabirimlerine göre daha kolay hale getirir. Ancak, IExtractImage veya IExtractImage2 kullanan mevcut kodun hala geçerli ve desteklendiğini unutmayın.

RecipeThumbnailProvider Örneği

Bu bölümde kesilen RecipeThumbnailProvider örneği Windows Yazılım Geliştirme Seti'ne (SDK) dahildir. Varsayılan yükleme konumu C:\Program Files\Microsoft SDKs\Windows\v6.0\Samples\WinUI\Shell\AppShellIntegration\RecipeThumbnailProvider'dır. Ancak kodun toplu kısmı da burada yer alır.

RecipeThumbnailProvider örneği, .recipe uzantısıyla kaydedilen yeni bir dosya türü için küçük resim işleyicisinin uygulanmasını gösterir. Örnek, özel dosya türleri için küçük resim ayıklama Bileşen Nesne Modeli (COM) sunucularını kaydetmek için farklı küçük resim işleyici API'lerinin kullanımını gösterir. Bu konu, kod seçeneklerini ve yönergeleri vurgulayarak örnek kodda size yol gösterir.

Küçük resim işleyicisi, her zaman IThumbnailProvider ile birlikte, şu arabirimlerden biriyle uyum içinde çalışmalıdır:

Akışlarla başlatmanın mümkün olmadığı durumlar vardır. Küçük resim işleyicinizin IInitializeWithStreamuygulamadığı senaryolarda, akışta bir değişiklik olduğunda sistem dizin oluşturucusunun varsayılan olarak yerleştirdiği yalıtılmış işlemde çalıştırmayı geri çevirmesi gerekir. İşlem yalıtımı özelliğini geri çevirmek için aşağıdaki kayıt defteri değerini ayarlayın.

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

IInitializeWithStream uygular ve akış tabanlı bir başlatma yaparsanız, işleyiciniz daha güvenli ve güvenilirdir. Genellikle, işlem yalıtımını devre dışı bırakmak yalnızca eski işleyicilere yöneliktir; yeni kodlar için bu özelliği devre dışı bırakmaktan kaçının. IInitializeWithStream mümkün olduğunda ilk başlatma arabirimi seçiminiz olmalıdır.

Örnekteki görüntü dosyası .recipe dosyasına eklenmediğinden ve dosya akışının bir parçası olmadığından, örnekte IInitializeWithItemkullanılır. IInitializeWithItem::Initialize yönteminin uygulanması, parametrelerini özel sınıf değişkenlerine geçirir.

IThumbnailProvider, piksel cinsinden görüntünün en büyük istenen boyutuyla çağrılan tek bir yöntem olanGetThumbnailyöntemine sahiptir. parametresi cxolarak adlandırılıyor olsa da, değeri görüntünün hem x hem de y boyutlarının en büyük boyutu olarak kullanılır. Alınan küçük resim kare değilse, uzun eksen cx ile sınırlıdır ve özgün görüntünün en boy oranı korunur.

Geri döndüğünde, GetThumbnail alınan görüntü için bir tanıtıcı sağlar. Ayrıca görüntünün renk biçimini ve geçerli alfa bilgileri olup olmadığını gösteren bir değer sağlar.

Örnekteki GetThumbnail uygulaması, özel _GetBase64EncodedImageString yöntemine yapılan çağrıyla başlar.

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

.recipe dosya türü yalnızca benzersiz dosya adı uzantısı olarak kaydedilmiş bir XML dosyasıdır. Bu özel .recipe dosyası için küçük resim olarak kullanılacak görüntünün göreli yolunu ve dosya adını sağlayan Resim adlı bir öğe içerir. Resim öğesi, temel 64 kodlu bir görüntüyü belirten Source özniteliğinden ve isteğe bağlı Boyut özniteliğinden oluşur.

Boyut küçük ve büyük olarak iki değere sahiptir. Bu, ayrı görüntüler içeren birden çok Resim düğümü sağlamanıza olanak tanır. Daha sonra alınan görüntü, getThumbnailçağrısında sağlanan en büyük boyut değerine (cx) bağlıdır. Windows hiçbir zaman görüntüyü maksimum boyutundan daha büyük boyuta getiremediğinden, farklı çözünürlükler için farklı görüntüler sağlanabilir. Ancak basitlik için örnek, Boyut özniteliğini atlar ve tüm durumlar için yalnızca bir görüntü sağlar.

Uygulaması burada gösterilen _GetBase64EncodedImageString yöntemi, Resim düğümünü almak için XML Belge Nesne Modeli (DOM) API'lerini kullanır. Bu düğümden görüntüyü Kaynak öznitelik verilerinden ayıklar.

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, ardından alınan dizeyi _GetStreamFromString'e aktarır.

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

Uygulaması burada gösterilen ve kodlanmış görüntüyü bir akışa dönüştüren _GetStreamFromString yöntemi.

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 ardından, akıştan bir bitmap ayıklamak ve bu bitmap için bir tanıtıcı almak için Windows Görüntüleme Bileşeni (WIC) API'lerini kullanır. Alfa bilgileri ayarlanır, WIC'dan düzgün bir şekilde çıkılır ve yöntem başarıyla sonlandırılır.

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

Küçük Resim İşleyicileri

Küçük Resim İşleyici Yönergeleri

IID_PPV_ARGS