Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
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();
     
    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 15-Oct-12 11:53am
Rate this: bad
good
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
  Permalink  
Rate this: bad
good
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;
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 289
1 OriginalGriff 225
2 DamithSL 165
3 Kornfeld Eliyahu Peter 105
4 Peter Leow 105
0 OriginalGriff 7,355
1 DamithSL 5,254
2 Sergey Alexandrovich Kryukov 4,942
3 Maciej Los 4,906
4 Kornfeld Eliyahu Peter 4,514


Advertise | Privacy | Mobile
Web01 | 2.8.141223.1 | Last Updated 16 Oct 2012
Copyright © CodeProject, 1999-2014
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