Search code examples
winapigdi

Create HBitmap in IExtractImage


I'm developping a thumbnail creator as a shell extension.

To do that, I choosed to implement interface IExtractImage.

My dll is loaded and correctly called, but, the thumbnail is always black, instead of being red.

What am I missing?

class MyShellPreview : public IExtractImage, IPersistFile

    // set by IExtractImage::GetLocation
    SIZE m_size;


    IFACEMETHODIMP Extract(HBITMAP *phBmpImage)
    {
        size_t size = m_size.cx * m_size.cy * 3;

        // alloc buffer
        BYTE *buffer = (BYTE*)malloc(size);

        // fill buffer
        for (k = i = 0; i < m_size.cx; ++i)
        {
            for (j = 0; j < m_size.cy; ++j, ++k)
            {
                buffer[k] = 128;
                buffer[k+1] = 0;
                buffer[k+2] = 0;
            }
        }

        *phBmpImage = CreateBitmap(m_size.cx, m_size.cy, 3, 8, buffer);

        free(buffer);

        return S_OK;
    }        
};

I know that for performance reason, I should use CreateCompatibleBitmap and SetDIBits, but I'm not sure from where I should get an HDC.


Solution

  • As pointed on comments, the solution was to use:

    • 32 bits images
    • 1 color plane


    class MyShellPreview : public IExtractImage, IPersistFile
    
        // set by IExtractImage::GetLocation
        SIZE m_size;
    
        IFACEMETHODIMP Extract(HBITMAP *phBmpImage)
        {
            size_t size = m_size.cx * m_size.cy * 4;
    
            // alloc buffer
            BYTE *buffer = (BYTE*)calloc(size, 1);
    
            // fill buffer
            for (k = i = 0; i < m_size.cx; ++i)
            {
                for (j = 0; j < m_size.cy; ++j, k+=4)
                {
                    buffer[k] = 128;                    
                }
            }
    
            *phBmpImage = CreateBitmap(m_size.cx, m_size.cy, 1, 24, buffer);
    
            free(buffer);
    
            return S_OK;
        }        
    };