Click here to Skip to main content
13,253,863 members (67,075 online)
Rate this:
Please Sign up or sign in to vote.
See more:
hi. im trying to copy a CImage to the clipboard. this is what I've got. I get a read access violation on the second memcpy (which is supposed to be copying the bits of the image). how do i copy a CImage to the clipboard?

    CImage tmpImage = pDoc->m_imageArray[0];
    int w = tmpImage.GetWidth();
    int h = tmpImage.GetHeight();
    int Bpp = tmpImage.GetBPP();
    bmInfohdr.biSize = sizeof(BITMAPINFOHEADER);
    bmInfohdr.biWidth = w;
    bmInfohdr.biHeight = -h;
    bmInfohdr.biPlanes = 1;
    bmInfohdr.biBitCount = Bpp;
    bmInfohdr.biCompression = BI_RGB;
    bmInfohdr.biSizeImage = w*h*Bpp;
    bmInfohdr.biXPelsPerMeter = 0;
    bmInfohdr.biYPelsPerMeter = 0;
    bmInfohdr.biClrUsed = 0;
    bmInfohdr.biClrImportant = 0;
    BITMAPINFO bmInfo;
    bmInfo.bmiHeader = bmInfohdr;
    void* pBits = tmpImage.GetBits();
    HANDLE hData = ::GlobalAlloc (GMEM_MOVEABLE, sizeof(BITMAPINFO) + w * h * 3);
    LPVOID pData = (LPVOID) ::GlobalLock (hData);
    LPBYTE p_imagebits;
    p_imagebits  = (LPBYTE)pData + sizeof(BITMAPINFO);
    DWORD dwBytes = ((DWORD) w * Bpp) / 32;
    if(((DWORD) w * Bpp) % 32) {
    dwBytes *= 4;
    unsigned long m_dwSizeImage = dwBytes * h; // no compression
    memcpy (p_imagebits, pBits, m_dwSizeImage);
    ::GlobalUnlock (hData);
    COleDataSource* pods = new COleDataSource;
    pods->CacheGlobalData (CF_DIB, hData);
    pods->SetClipboard ();
Posted 15-Oct-12 11:53am
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Have you given a look to Copying a DIB to the Clipboard[^] CP-Article?
It might help you
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

You are calculating the correct image size (knowing that scan lines are DWORD aligned) and store it in m_dwSizeImage (may be also stored in bmInfohdr.biSizeImage). But you did not use this size when allocating the global memory. Depending on the image width, m_dwSizeImage may be greater than w * h * 3 (or it is always greater when Bpp is 32), resulting in the access violation.

There is another error with the color table / usage of BITMAPINFO:
If the DIB has no color table (Bpp > 8), you must not allocate space for it. Otherwise, the size of the color table must be calculated and allocated. The BITMAPINFO structure contains only one color entry as placeholder.

So you should move the image size calculation code on top of the allocation and use something like this (note the usage of BITMAINFOHEADER instead of BITMAPINFO):
SIZE_T dwColTableLen = (Bpp <= 8) ? (1 << Bpp) * sizeof(RGBQUAD) : 0;
HANDLE hData = ::GlobalAlloc(GMEM_MOVEABLE, 
    sizeof(BITMAPINFOHEADER) + dwColTableLen + m_dwSizeImage);
if (dwColTableLen)
    LPBYTE lpColorTable = (LPBYTE)pData + sizeof(BITMAPINFOHEADER);
    // pColors must point to the source color table
    memcpy(lpColorTable, pColors, dwColTableLen);
p_imagebits  = (LPBYTE)pData + sizeof(BITMAPINFOHEADER) + dwColTableLen;

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web01 | 2.8.171114.1 | Last Updated 16 Oct 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100