Windows缩略图处理程序永远不会被调用

时间:2016-06-20 20:40:16

标签: windows visual-studio visual-c++ windows-shell

我正在为自定义文件类型编写缩略图处理程序。当我注册它时,它返回一个成功消息。 "缩略图"显示为完全空白,但它没有说"没有缩略图"。问题是,实际的缩略图处理程序永远不会被调用。我知道这一点,因为我在handler::initializehandler::queryinterfacehandler::getthumbnail下的处理程序中添加了一系列语句。我已经完成了大部分this documentation.,但我能找到的只是我需要使用initialize和getthumbnail。这是我的代码:

部首:

#pragma once

#include <windows.h>
#include <thumbcache.h>     // For IThumbnailProvider
#include <wincodec.h>       // Windows Imaging Codecs

#include <fstream>
#include <iostream>

#pragma comment(lib, "windowscodecs.lib")


class  ThumbnailProvider :
    public IInitializeWithStream,
    public IThumbnailProvider
{
public:
    // IUnknown
    IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv);
    IFACEMETHODIMP_(ULONG) AddRef();
    IFACEMETHODIMP_(ULONG) Release();

    // IInitializeWithStream
    IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode);

    // IThumbnailProvider
    IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha);

     ThumbnailProvider();

protected:
    ~ ThumbnailProvider();

private:
    // Reference count of component.
    long m_cRef;

    // Provided during initialization.
    IStream *m_pStream;

    std::ofstream output;

    void stripImageFrom (IStream *stream, HBITMAP *phbmp);
};

体:

#include " ThumbnailProvider.h"
#include <Shlwapi.h>
#include <Wincrypt.h>   // For CryptStringToBinary.
#include <msxml6.h>
#include <atlimage.h>
#include <fstream>

#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "msxml6.lib")

extern HINSTANCE g_hInst;
extern long g_cDllRef;

 ThumbnailProvider:: ThumbnailProvider() : m_cRef(1), m_pStream(NULL)
{
    std::ofstream st;
    st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
    st << "Made provider";
    st.close();
    InterlockedIncrement(&g_cDllRef);

}


 ThumbnailProvider::~ ThumbnailProvider()
{
    InterlockedDecrement(&g_cDllRef);
}

#pragma region IUnknown

// Query to the interface the component supported.
IFACEMETHODIMP  ThumbnailProvider::QueryInterface(REFIID riid, void **ppv)
{
    std::ofstream st;
    st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
    st << "Querying interface";
    st.close();
    static const QITAB qit[] =
    {
        QITABENT( ThumbnailProvider, IThumbnailProvider),
        QITABENT( ThumbnailProvider, IInitializeWithStream),
        { 0 },
    };
    return QISearch(this, qit, riid, ppv);
}

// Increase the reference count for an interface on an object.
IFACEMETHODIMP_(ULONG)  ThumbnailProvider::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

// Decrease the reference count for an interface on an object.
IFACEMETHODIMP_(ULONG)  ThumbnailProvider::Release()
{
    ULONG cRef = InterlockedDecrement(&m_cRef);
    if (0 == cRef)
    {
        delete this;
    }

    return cRef;
}

#pragma endregion

#pragma region IInitializeWithStream

// Initializes the thumbnail handler with a stream.
IFACEMETHODIMP  ThumbnailProvider::Initialize(IStream *pStream, DWORD grfMode)
{
    std::ofstream st;
    st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
    st << "Got to initialization";
    st.close();
    // A handler instance should be initialized only once in its lifetime. 
    HRESULT hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
    if (m_pStream == NULL)
    {
        // Take a reference to the stream if it has not been initialized yet.
        hr = pStream->QueryInterface(&m_pStream);
    }
    return hr;
}

#pragma endregion


#pragma region IThumbnailProvider

// Gets a thumbnail image and alpha type. The GetThumbnail is called with the 
// largest desired size of the image, in pixels. Although the parameter is 
// called cx, this is used as the maximum size of both the x and y dimensions. 
// If the retrieved thumbnail is not square, then the longer axis is limited 
// by cx and the aspect ratio of the original image respected. On exit, 
// GetThumbnail provides a handle to the retrieved image. It also provides a 
// value that indicates the color  at of the image and whether it has 
// valid alpha in ation.
IFACEMETHODIMP  ThumbnailProvider::GetThumbnail(UINT cx, HBITMAP *phbmp,
    WTS_ALPHATYPE *pdwAlpha) {
    std::ofstream st;
    st.open("C:\\Users\\labs\\Desktop\\Output\\out.txt", std::ios_base::app);
    st << "Getting thumbnail";
    st.close();
     ThumbnailProvider::stripImageFrom (m_pStream, phbmp);
    cx = 1024 * 1024;
    *pdwAlpha = WTSAT_UNKNOWN;
    return S_OK;
}

#pragma endregion

#pragma region Helper Functions

// The PNG signature is 137 80 78 71 13 10 26 10. This does not make sense to do backward. I will do it forward.
void  ThumbnailProvider::stripImageFrom (IStream *stream, HBITMAP *phbmp) {
    unsigned long numBytes = 0;
    unsigned long *numBytesPtr = &numBytes;
    char *chptr = nullptr;
    byte vals[8] = { 0 };
    STATSTG *stat = nullptr;
    DWORD temp = NULL;
    stream->Stat(stat, temp);
    unsigned long long length = stat->cbSize.QuadPart;
    unsigned long long i;
    for (i = 0; i<length; i++) {
        stream->Read(chptr, 1, numBytesPtr);
        if (*chptr == 137) {
            vals[0] = 1;
        }
        else if (*chptr == 80 && vals[0]) {
            vals[1] = 1;
        }
        else if (*chptr == 78 && vals[1]) {
            vals[2] = 1;
        }
        else if (*chptr == 71 && vals[2]) {
            vals[3] = 1;
        }
        else if (*chptr == 13  && vals[3]) {
            vals[4] = 1;
        }
        else if (*chptr == 10  && vals[4] && !vals[5]) {
            vals[5] = 1;
        }
        else if (*chptr == 26  && vals[5]) {
            vals[6] = 1;
        }
        else if (*chptr == 10 && vals[6]) {
            vals[7] = 1;
            i -= 7;
            break;
        }
        else {
            memset(vals, 0, 8 * sizeof(vals[0]));
        }
    }
    if (vals[7]) {
        IStream *imgstream = nullptr;
        stream->Read(imgstream, length-i, numBytesPtr);
        CImage *img = nullptr;
        img->Load(imgstream);
        *phbmp = *img;
    }
}
#pragma endregion

其他所有内容都是从微软的一个例子中编辑的,所以我很确定没问题。 The example is here.

1 个答案:

答案 0 :(得分:0)

如果您遇到此问题,请确保您正在构建正确的架构。这解决了我。