Jospehus Chou
Jospehus Chou

Reputation: 117

How to copy a picture from disk into the clipboard with win32?

It's easy to copy text into clipboard with win32 API, but I want to copy a picture from disk (for example, D:\1.jpg) into the clipborad.

I search many webpages and I can't find something useful. Please teach me how to do it.

And no MFC.

Upvotes: 1

Views: 1819

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

You can use Gdi+ to load the image, get HBITMAP, and set the clipboard data. Gdi+ is Unicode only, so if using old ANSI functions you have to convert the filename to wide char. Example in C++:

bool copyimage(const wchar_t* filename)
{
    bool result = false;
    Gdiplus::Bitmap *gdibmp = Gdiplus::Bitmap::FromFile(filename);
    if (gdibmp)
    {
        HBITMAP hbitmap;
        gdibmp->GetHBITMAP(0, &hbitmap);
        if (OpenClipboard(NULL))
        {
            EmptyClipboard();
            DIBSECTION ds;
            if (GetObject(hbitmap, sizeof(DIBSECTION), &ds))
            {
                HDC hdc = GetDC(HWND_DESKTOP);
                //create compatible bitmap (get DDB from DIB)
                HBITMAP hbitmap_ddb = CreateDIBitmap(hdc, &ds.dsBmih, CBM_INIT,
                    ds.dsBm.bmBits, (BITMAPINFO*)&ds.dsBmih, DIB_RGB_COLORS);
                ReleaseDC(HWND_DESKTOP, hdc);
                SetClipboardData(CF_BITMAP, hbitmap_ddb);
                DeleteObject(hbitmap_ddb);
                result = true;
            }
            CloseClipboard();
        }

        //cleanup:
        DeleteObject(hbitmap);  
        delete gdibmp;              
    }
    return result;
}

Note that Microsoft recommends using CF_DIB to set bitmap clipboard data, but that doesn't work with GDI+. This example uses CF_BITMAP instead.

Gdi+ uses standard GdiPlus.lib library. It needs to be initialized as follows:

#include <Windows.h>
#include <GdiPlus.h>

#pragma comment(lib, "GdiPlus")//Visual Studio specific

bool copyimage(const wchar_t* filename);

int main()
{
    //initialize Gdiplus once:
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    copyimage(L"d:\\1.jpg");

    Gdiplus::GdiplusShutdown(gdiplusToken);
}

Upvotes: 5

Related Questions