Click here to Skip to main content
15,886,519 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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?


C++
CImage tmpImage = pDoc->m_imageArray[0];

int w = tmpImage.GetWidth();
int h = tmpImage.GetHeight();
int Bpp = tmpImage.GetBPP();

BITMAPINFOHEADER bmInfohdr;
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;
bmInfo.bmiColors[0].rgbBlue=255;


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);


memcpy(pData,&bmInfo,sizeof(BITMAPINFO));


DWORD dwBytes = ((DWORD) w * Bpp) / 32;

if(((DWORD) w * Bpp) % 32) {
   dwBytes++;
}
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

Have you given a look to Copying a DIB to the Clipboard[^] CP-Article?
It might help you
 
Share this answer
 
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;
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900