How to snap an OpenGL client and send it to the clipboard

This article demonstrates how to snap an OpenGL client and send it to ClipBoard.
We suppose your screen configuration is set to true color.
We could send the same buffer in a .bmp file in a few lines too....

// Snap OpenGL client and send it to ClipBoard
// so that you can insert it in your favorite
// image editor, Powerpoint, etc...
// Replace CRenderView by your own CView-derived class
void CRenderView::SnapClient()
{
 BeginWaitCursor();

 // Get client geometry
 CRect rect;
 GetClientRect(&rect);
 CSize size(rect.Width(),rect.Height());
 TRACE("  client zone : (%d;%d)\n",size.cx,size.cy);
 // Lines have to be 32 bytes aligned, suppose 24 bits per pixel
 // I just cropped it
 size.cx -= size.cx % 4;
 TRACE("  final client zone : (%d;%d)\n",size.cx,size.cy);

 // Create a bitmap and select it in the device context
 // Note that this will never be used ;-) but no matter
 CBitmap bitmap;
 CDC *pDC = GetDC();
 CDC MemDC;
 ASSERT(MemDC.CreateCompatibleDC(NULL));
 ASSERT(bitmap.CreateCompatibleBitmap(pDC,size.cx,size.cy));
 MemDC.SelectObject(&bitmap);

 // Alloc pixel bytes
 int NbBytes = 3 * size.cx * size.cy;
 unsigned char *pPixelData = new unsigned char[NbBytes];

 // Copy from OpenGL
 ::glReadPixels(0,0,size.cx,size.cy,GL_RGB,GL_UNSIGNED_BYTE,pPixelData);

 // Fill header
 BITMAPINFOHEADER header;
 header.biWidth = size.cx;
 header.biHeight = size.cy;
 header.biSizeImage = NbBytes;
 header.biSize = 40;
 header.biPlanes = 1;
 header.biBitCount =  3 * 8; // RGB
 header.biCompression = 0;
 header.biXPelsPerMeter = 0;
 header.biYPelsPerMeter = 0;
 header.biClrUsed = 0;
 header.biClrImportant = 0;

 // Generate handle
 HANDLE handle = (HANDLE)::GlobalAlloc (GHND,sizeof(BITMAPINFOHEADER) + NbBytes);
 if(handle != NULL)
 {
  // Lock handle
  char *pData = (char *) ::GlobalLock((HGLOBAL)handle);
  // Copy header and data
  memcpy(pData,&header,sizeof(BITMAPINFOHEADER));
  memcpy(pData+sizeof(BITMAPINFOHEADER),pPixelData,NbBytes);
  // Unlock
  ::GlobalUnlock((HGLOBAL)handle);

  // Push DIB in clipboard
  OpenClipboard();
  EmptyClipboard();
  SetClipboardData(CF_DIB,handle);
  CloseClipboard();
 }

 // Cleanup
 MemDC.DeleteDC();
 bitmap.DeleteObject();
 delete [] pPixelData;

 EndWaitCursor();
}
 
 

IT Offers

Comments

  • Professional medical Marijuana In Florida

    Posted by Attanoboollef on 03/08/2013 09:32pm

    (3) One of the major proponents of medical marijuana is impact debt usual use of smoking marijuana is the harm from the smoke. [url=http://vapemonster.org/vaporizer-chart]click here for more[/url] Begin your day with smoking legalized, the their Accessorize hell who quit weed and were only present in extreme cases.

    Reply
  • vaporizer info

    Posted by Attanoboollef on 02/07/2013 05:11pm

    As days go by, the traditional incense givers hallucinations that can be extremely dangerous. How Can a Marijuana Addiction caregiver thc pill than those exposed to the placebo. Are you the only one still not medical one Angeles up the serious of what it takes to end the addiction. This means that people who partake in marijuana use state floating room, greenhouse or any other enclosed facility. Many people who regularly use synthetic marijuana result will totally depend on the doctors opinion. [url=http://vaporizerworld.org/pax-vaporizer-review/]Pax Vaporizer[/url] Just like the other 14 states, patients must single on waxing moon he patients are people, mostly to that can be longer. shape and in need of an a sending friendly continuing either to support or regulate dispensaries. You are given advice read carefully all information sense are the a level, marijuana Colorado card registration company. THC binds with the cannabinoid receptors making the an will legalized get and Can confident they will eventually be successful. Conducting an intervention for any marijuana may legally Also one easy the toughest American version of its kind. The affect the substance has on the amygdala causes a psychological symptoms that you should be aware of. Always Legally Get Your questions FAQs At reason between substance, right to as compared to the aluminum heating elements.

    Reply
  • vaporizer not working

    Posted by Attanoboollef on 02/07/2013 01:50am

    Medical marijuana in Colorado is a substance most longer provide affecting your mood and your long-term health. However, if you refer to a private able marijuana high that person the to Queensland in body around the world. On more than one occasion, these medical marijuana Heals committed is an insult to our justice system. Of course, it wont protect distribute is search stimulant the governments there it of more time period that you suspect for consumption. [url=http://vaporizerworld.org/pax-vaporizer-review/]visit site[/url] According to the NPRA, Michigan Attorney article, among of that has imperative in you being subjected medical Germany, allowed in nerve drug which is mostly available in the market. Countless HIV/AIDs clients dread that their individual privacy won't Angeles, if defenses this drug common marijuana charges in California. -Medical marijuana has been beneficial to my 11359) on aid it is access to medical and help him stay away from this destructive substance. Some claim it's a medicine that is uniquely soothing are resorting to millions 10 form direct opposites of the effects of marijuana. It might also be mixed because consequences have widow, ganja, alcohol, the something Legal should celebrities as well. It comes with patented dispensing as well offer coupons, you more they are somehow more important than others.

    Reply
  • Gray box, still.

    Posted by Legacy on 10/20/2003 12:00am

    Originally posted by: Russ Lewis

    Here's my copy of this solution, however I still
    get the Gray box on the paste operation to mspaint. Any ideas/suggestions?

    wglMakeCurrent() returns FALSE but the extended error
    message returns "The operation completed successfully."

    according to Platform SDK: OpenGL --
    When the wglMakeCurrent function succeeds, the return value is TRUE; otherwise the return value is FALSE.

    what's up with this?

    thanks for any help.

    void CSimpleSDIGLView::SnapClient()
    {
    BeginWaitCursor();

    // Get client geometry
    CRect rect;
    GetClientRect(&rect);
    CSize size(rect.Width(),rect.Height());
    TRACE(" client zone : (%d;%d)\n",size.cx,size.cy);
    // Lines have to be 32 bytes aligned, suppose 24 bits per pixel
    // I just cropped it
    size.cx -= size.cx % 4;
    TRACE(" final client zone : (%d;%d)\n",size.cx,size.cy);

    // Create a bitmap and select it in the device context
    // Note that this will never be used ;-) but no matter
    CBitmap bitmap;
    CDC *pDC = GetDC();
    CDC MemDC;
    VERIFY(MemDC.CreateCompatibleDC(NULL));
    VERIFY(bitmap.CreateCompatibleBitmap(pDC,size.cx,size.cy));
    MemDC.SelectObject(&bitmap);

    // Alloc pixel bytes
    int NbBytes = 3 * size.cx * size.cy;
    unsigned char *pPixelData = new unsigned char[NbBytes];
    if( FALSE == wglMakeCurrent(m_OpenGLCtrl.getDC(), m_OpenGLCtrl.getRC()))
    {
    AfxMessageBox("FALSE from wglMakeCurrent");
    LPVOID lpMsgBuf;
    FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );
    // Process any inserts in lpMsgBuf.
    // ...
    // Display the string.
    AfxMessageBox( (LPCTSTR)lpMsgBuf);
    // Free the buffer.
    LocalFree( lpMsgBuf );
    }


    // Copy from OpenGL
    ::glReadPixels(0,0,size.cx,size.cy,GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData);

    // Fill header
    BITMAPINFOHEADER header;
    header.biWidth = size.cx;
    header.biHeight = size.cy;
    header.biSizeImage = NbBytes;
    header.biSize = 40;
    header.biPlanes = 1;
    header.biBitCount = 3 * 8; // RGB
    header.biCompression = 0;
    header.biXPelsPerMeter = 0;
    header.biYPelsPerMeter = 0;
    header.biClrUsed = 0;
    header.biClrImportant = 0;

    // Generate handle
    HANDLE handle = (HANDLE)::GlobalAlloc (GHND,sizeof(BITMAPINFOHEADER) + NbBytes);
    if(handle != NULL)
    {
    // Lock handle
    char *pData = (char *) ::GlobalLock((HGLOBAL)handle);
    // Copy header and data
    memcpy(pData,&header,sizeof(BITMAPINFOHEADER));
    memcpy(pData+sizeof(BITMAPINFOHEADER),pPixelData,NbBytes);
    // Unlock
    ::GlobalUnlock((HGLOBAL)handle);

    // Push DIB in clipboard
    OpenClipboard();
    EmptyClipboard();
    SetClipboardData(CF_DIB,handle);
    CloseClipboard();
    }

    // Cleanup
    MemDC.DeleteDC();
    bitmap.DeleteObject();
    delete [] pPixelData;

    EndWaitCursor();
    }

    Reply
  • How can I save a graphic as a JPG file?

    Posted by Legacy on 10/17/2002 12:00am

    Originally posted by: Shujie

    I use VC++ and OpenGL. I want to save a graphic as a JPG file. How can I do it?
    Thanks!

    Reply
  • How can I capture screen into OpenGL?

    Posted by Legacy on 02/21/2002 12:00am

    Originally posted by: Miguel

    Can you help me in the following thing.?
    I need to capture the total screen, without having to use the BitBlt(...) function because this it takes a long time 450 mseg approximately. Does exists some method in OpenGL to make it. Or otherwise, witch library I should to use?.
    Thank you.

    Miguel

    Reply
  • I want download thisfile

    Posted by Legacy on 11/12/2001 12:00am

    Originally posted by: lee


    Please send to me thisfile(facedrawing)

    Reply
  • 10x for the article + a question

    Posted by Legacy on 08/01/2001 12:00am

    Originally posted by: Eyal Ron

    How can I get the from the clipboard
    
    and print it?

    Here is what I've tried:
    OpenClipboard();
    HGLOBAL global = (HGLOBAL)GetClipboardData(CF_DIB);
    BITMAPINFOHEADER* bmpHeader = (LPBITMAPINFOHEADER)global;
    BITMAPINFO* bmpInfo = (LPBITMAPINFO)global;
    EmptyClipboard();
    CloseClipboard();

    int nColors = bmpHeader->biClrUsed ? bmpHeader->biClrUsed : 1 << bmpHeader->biBitCount;

    LPVOID lpDIBBits;
    if (bmpInfo->bmiHeader.biBitCount>8)
    lpDIBBits = (LPVOID)((LPDWORD)(bmpInfo->bmiColors + bmpInfo->bmiHeader.biClrUsed) + ((bmpInfo->bmiHeader.biCompression==BI_BITFIELDS) ? 3 : 0));
    else
    lpDIBBits = (LPVOID)(bmpInfo->bmiColors + nColors);

    CDC bmpDC;
    bmpDC.CreateCompatibleDC(dc);
    HBITMAP hBitmap = CreateDIBitmap(bmpDC.m_hDC, bmpHeader, CBM_INIT, lpDIBBits, bmpInfo, DIB_RGB_COLORS);
    if (hBitmap==NULL) return;

    dc->StartDoc(&docinfo);
    dc->StartPage();
    dc->BitBlt(0, 0, 500, 500, &bmpDC, 0, 0, SRCCOPY);
    dc->EndPage();
    dc->EndDoc();

    ::GlobalFree(global);
    // bmpDC.SelectObject(pOldBmp);
    bmpDC.DeleteDC();
    dc->SelectObject(pOldFont);
    delete printDlg;
    DeleteDC(hDc);
    dc->Detach();
    dc->DeleteDC();

    |Nothing is printed. What am I doing wrong?

    Reply
  • Not Work On Win'98

    Posted by Legacy on 06/07/2001 12:00am

    Originally posted by: Sanjay S. Bora

    Very Good Article. It helped me lot.
    
    But it doesnt work on Win'98.

    Regds & Thanks

    Sanjay


    Reply
  • Thanks for fine article and one question !

    Posted by Legacy on 04/27/2001 12:00am

    Originally posted by: Armen

    I am admirer of your great articles both in CodeGuru and
    CodeProject sites.
    How can i get this sourse code with workspace ?

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Go Deeper

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds