使用GDI+加载32位的位图或者PNG图片(具有透明通道)

#include <windows.h>
#include <gdiplus.h>

HBITMAP LoadBitmapFromResource(DWORD ResourceID, bool transparent = true)
{
    HANDLE hGlobal = NULL;
    ULONG_PTR GDIToken = 0;
    Gdiplus::Image* Img = NULL;
    Gdiplus::GdiplusStartupInput GDIStartInput = NULL;


    Gdiplus::GdiplusStartup(&GDIToken, &GDIStartInput, NULL);

    HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(ResourceID), "BINARY");
    if (!hResource) {return NULL;}

    HGLOBAL hFileResource = LoadResource(NULL, hResource);
    if (!hFileResource) {return NULL;}

    LPVOID lpFile = LockResource(hFileResource);
    if (!lpFile) {return NULL;}

    DWORD dwSize = SizeofResource(NULL, hResource);
    if (!dwSize) {return NULL;}

    void* data = LockResource(hFileResource);
    if (!data) {return NULL;}

    IStream* pStream = NULL;
    hGlobal = GlobalAlloc(GMEM_FIXED, dwSize);

    memcpy(hGlobal, data, dwSize);
    UnlockResource(hFileResource);
    FreeResource(hFileResource);

    if (CreateStreamOnHGlobal(hGlobal, true, &pStream) == S_OK)
    {
        Img = new Gdiplus::Image(pStream, false);
        pStream->Release();
        GlobalFree(hGlobal);
        hGlobal = NULL;

        HBITMAP hBitmap = NULL;
        static_cast<Gdiplus::Bitmap*>(Img)->GetHBITMAP(transparent ? Gdiplus::Color::Transparent : Gdiplus::Color(0, 0, 0), &hBitmap);

        delete Img;
        Gdiplus::GdiplusShutdown(GdiImage::GDIToken);
        GDIStartInput = NULL;
        GDIToken = 0;

        return hBitmap;
    }

    GlobalFree(hGlobal);
    hGlobal = NULL;
    Gdiplus::GdiplusShutdown(GdiImage::GDIToken);
    GDIStartInput = NULL;
    GDIToken = 0;

    return NULL;
}

最后会返回可操作的hBitmap句柄

另附上异曲同工的代码:

Gdiplus::Bitmap *loadimage(HINSTANCE hinst, const wchar_t* name)
{
    auto hres = FindResource(hinst, name, RT_RCDATA);
    if(!hres) 
        return nullptr;//resource not found

    if(auto size = SizeofResource(hinst, hres))
        if(auto data = LockResource(LoadResource(hinst, hres)))
            if(auto stream = SHCreateMemStream((const BYTE*)data, size))
            {
                auto *bmp = new Gdiplus::Bitmap(stream);
                if(!bmp)
                {
                    //wrong input, or gdiplus was not initialized
                }
                stream->Release();
                return bmp;
            }

    return nullptr;
}

...
auto gimg = loadimage(hinst, MAKEINTRESOURCE(ID_PNG1));
Gdiplus::Color clr = Gdiplus::Color::Transparent;
gimg->GetHBITMAP(Gdiplus::Color::Transparent, &bitmap);
ImageList_AddMasked(himage, bitmap, 0));
DeleteObject(bitmap);
//资源定义应如下所示:

ID_PNG1 RCDATA "file.png"
//确保初始化Gdiplus:

struct gdiplus_init
{
    Gdiplus::GdiplusStartupInput tmp;
    ULONG_PTR token;
    gdiplus_init(){ Gdiplus::GdiplusStartup(&token, &tmp, NULL); }
    ~gdiplus_init(){ Gdiplus::GdiplusShutdown(token); }
} gdipls_init;

附上代码链接:https://stackoverflow.com/questions/58751417/how-can-i-add-a-transparent-png-as-a-toolbar-icon

       https://stackoverflow.com/questions/58749796/win32-unable-to-add-custom-toolbar-icon-having-transparency

猜你喜欢

转载自www.cnblogs.com/strive-sun/p/11819982.html