how do i copy a CImage DIB to clipboard
-
im trying to copy a cimage dib to the clipboard. the second memcpy fails with a read access violation. can anyone help?
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 ();
-
im trying to copy a cimage dib to the clipboard. the second memcpy fails with a read access violation. can anyone help?
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 ();
It fails because the memory allocated by GlobalAlloc is not enough. See, how you use sizeof(BITMAPINFO) + w * h * 3 value to allocate memory, and then you are trying to calculate the m_dwSizeImage value, which is much greater then requested. You have got two options: Either move this chunk of code after you have calculated the image size, so that your code becomes:
DWORD dwBytes = ((DWORD) w \* Bpp) / 32; if(((DWORD) w \* Bpp) % 32) { dwBytes++; } dwBytes \*= 4; unsigned long m\_dwSizeImage = dwBytes \* h; // no compression void\* pBits = tmpImage.GetBits(); HANDLE hData = ::GlobalAlloc (GMEM\_MOVEABLE, sizeof(BITMAPINFO) + m\_dwSizeImage); LPVOID pData = (LPVOID) ::GlobalLock (hData); LPBYTE p\_imagebits; p\_imagebits = (LPBYTE)pData + sizeof(BITMAPINFO); memcpy(pData,&bmInfo,sizeof(BITMAPINFO)); memcpy (p\_imagebits, pBits, m\_dwSizeImage);
Or, just use a solution[^] from Codeguru BTW, it looks like you have calculated the m_dwImageSize incorrectly anyway