IThumbnailProvider and IExtractImage on Windows 8

Category: visual studio vclanguage


FrancescoBLT on Fri, 03 Oct 2014 15:32:35

Hi to all

I wrote a shell extension for displaying thumbnails of custom video file type.  This extension works well

under Windows XP, but don't work under Vista and greater.  Registration seems ok: and looking at registry I see the shellext key with correct CLSID (like in windows XP).  But the extension doesn't work. No thumbnails and it seems that isn't loaded at all. In the constructor I have inserted an OutputDebugString that prints the version but no printout on DebugView.


Shu 2017 on Mon, 06 Oct 2014 03:21:35

Hi FrancescoBLT,

Thanks for posting in MSDN forum.

From the title and body of your thread, It seems that your shell extension doesn’t work both in windows vista and windows 8. So which interface you are using IThumbnailProvider or IExtractImage to provider thumbmail?

If you are using IExtractImage interface, it is a good choice to use IShellItemImageFactory on Vista or higher to get icons. Refer to the answer in this thread:” IShellItemImageFactory would fall back to IExtractImage if a thumbnail is not available and no thumbnail provider is registered for the file type. But if a thumbnail provider is available, or the icon is cached, IExtractImage won't be called.”

If you are using IThumbnailProvider interface, you may need to show us some key code or share your project on the OneDrive. Please refer to:

Best regards,

Shu Hu

We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.

FrancescoBLT on Mon, 06 Oct 2014 09:23:23

Hi Mr Shu

I am using both. This is my shell extension queryInterface:

// Query to the interface the component supported.
IFACEMETHODIMP BLTThumbnailProvider::QueryInterface(REFIID riid, void **ppv)
    static const QITAB qit[] =
        QITABENT(BLTThumbnailProvider, IPersistFile),
        QITABENT(BLTThumbnailProvider, IColumnProvider),
        QITABENT(BLTThumbnailProvider, IThumbnailProvider),
        QITABENT(BLTThumbnailProvider, IExtractImage),
        QITABENT(BLTThumbnailProvider, IInitializeWithFile),

        QITABENT(BLTThumbnailProvider, IShellExtInit),         // For context menu
        QITABENT(BLTThumbnailProvider, IQueryInfo),
        QITABENT(BLTThumbnailProvider, IUnknown),
        { 0 },
    HRESULT hr = QISearch(this, qit, riid, ppv);

    return hr;

I compile in 64bit mode under windows xp (VS2010) and it works on Windows 8 professional, but it doesn't on Windows 8.1 Enterprise. The component seems to be loaded. This is main entry:

BLTThumbnailProvider::BLTThumbnailProvider() : m_cRef(1), m_pStream(NULL),RGB_oneshot(1),                     myR_Crscaled(NULL),myG_Crscaled(NULL),myG_Cbscaled(NULL),myB_Cbscaled(NULL),my_BMP_lookup(NULL),
                     m_pszMenuText(L"&BLT Clip check"),
                     m_pszVerbHelpText("Display File Name (blt)"),
                     m_pwszVerbHelpText(L"Display File Name (blt)")
    bltStartOfF0Size_ = 0;  ncompo = 3;

    m_hMenuBmp = LoadImage(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1),

#if (WIN64)
    sprintf_s(db,128, "BLT Shell extension V%02d.%02d%c 64 bit version", VERS,SUBV, REL);    OutputDebugStringA(db);
    sprintf_s(db,128, "BLT Shell extension V%02d.%02d%c 32 bit version", VERS,SUBV, REL);    OutputDebugStringA(db);


When I switch to show thumbnails I see the version printed (using debugview) but no thumbnail.

The registration was ok

Loser Dd on Tue, 07 Oct 2014 06:22:18

I think you need to debug your code on windows8.1 enterprise.

FrancescoBLT on Tue, 07 Oct 2014 14:37:53

Hi Mr Shu

I make some progress.  I found that on Windows 8.1 Enterprise the IInitializeWithStream is requested (I print out the QueryInterface requests) so I implemented IInitializeWithStream too. The result are the calls to GetThumbnails as desired.  All goes ok (the function read first part of file and decompress image), because no error on debug is found, and the "Thumbnail created" is printed out,  But no thumbnail is displayed. Here is my code:

IFACEMETHODIMP BLTThumbnailProvider::GetThumbnail(UINT cx, HBITMAP *phbmp,
    WTS_ALPHATYPE *pdwAlpha)
#if DEBUG_LEVEL >1    
    sprintf_s(db,128, "GetThumbnail called (cx %ld)",cx); OutputDebugStringA(db);
    DWORD sz;
            sprintf_s(db,128, "GetThumbnail : Bad file name, using stream"); OutputDebugStringA(db);
            useStream = true;
        HRESULT hr = Load_BLT_File((wchar_t*)blt_filename,1);
           {   sprintf_s(db,128,"BLTThumbnailProvider::GetThumbnail Error loading file (%lx)",hr); OutputDebugStringA(db); return E_FAIL;}

          BITMAPINFO bmi = { sizeof(bmi.bmiHeader) };
        bmi.bmiHeader.biWidth = bwidth;
        bmi.bmiHeader.biHeight = -static_cast<LONG>(bheight);
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = ncompo*8;
        bmi.bmiHeader.biCompression = BI_RGB;
        sz = bwidth*bheight*ncompo;// These values are 150x100x3
        BYTE *pBits;
        HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS,
                  reinterpret_cast<void **>(&pBits), NULL, 0);
        hr = hbmp ? S_OK : E_OUTOFMEMORY;
        if (SUCCEEDED(hr))
            *phbmp = hbmp;
            *pdwAlpha =WTSAT_RGB;
            sprintf_s(db,128, "GetThumbnail : Thumbnail created"); OutputDebugStringA(db);
          { sprintf_s(db,128,"Error creating bitmap handle (%lx)",hbmp); OutputDebugStringA(db);  *phbmp = NULL;    }
        return S_OK;

in this code bwidth, bheight and ncompo are fixed (150, 100 and 3 respectively as reported in the comment). I can't figure out why doesn't display bitmap.  May be I should insert alpha component ? (That is a 32BPP bitmap is mandatory ?)


FrancescoBLT on Tue, 07 Oct 2014 15:47:14

Solved : The 32BPP bitmap is mandatory.  Implementing it all works.