Click here to Skip to main content
15,915,163 members
Articles / Desktop Programming / MFC
Article

Getting a CF_DIB or CF_METAFILEPICT from the clipboard and displaying it

Rate me:
Please Sign up or sign in to vote.
3.82/5 (8 votes)
11 Dec 2002CPOL 95.3K   43   7
Example code to display a CF_DIB or CF_METAFILEPICT from the clipboard

Introduction

I needed to display a bitmap from the clipboard which is in the CF_DIB format in one of my applications. The standard MSDN docs did not have any information on how to do this. Also, all the other clipboard articles here had code to write CF_DIB to the clipboard, but not read it. Also I already had some existing code to display a metafile from the clipboard, both of which may be of use.

// pDC is the DC to draw to
// metafile is a CRect to display the DIB/Metafile in
    CRect    metafile(0, 0, 100, 100);    // example location
    if (IsClipboardFormatAvailable(CF_METAFILEPICT))
    {
        // play a metafile from the clipboard if available
        GLOBALHANDLE    hGMem ;
        LPMETAFILEPICT    lpMFP ;
        OpenClipboard() ;
        hGMem = GetClipboardData(CF_METAFILEPICT) ;
        lpMFP = (LPMETAFILEPICT)GlobalLock(hGMem) ;
        pDC->SaveDC() ;
        pDC->SetMapMode(lpMFP->mm) ;
        pDC->SetViewportExt(metafile.Width(), metafile.Height()) ;
        pDC->SetViewportOrg(metafile.left, metafile.top) ;
        pDC->PlayMetaFile(lpMFP->hMF) ;
        VERIFY(pDC->RestoreDC(-1)) ;
        GlobalUnlock(hGMem) ;
        CloseClipboard() ;
    }
    if (IsClipboardFormatAvailable(CF_DIB))
    {
        // a DIB is in the clipboard, draw it out
        GLOBALHANDLE    hGMem ;
        LPBITMAPINFO    lpBI ;
        void*            pDIBBits;
    
        OpenClipboard() ;
        hGMem = GetClipboardData(CF_DIB) ;
        lpBI = (LPBITMAPINFO)GlobalLock(hGMem) ;
        // point to DIB bits after BITMAPINFO object
        pDIBBits = (void*)(lpBI + 1); 
        ::StretchDIBits(pDC->m_hDC,
            metafile.left, metafile.top, 
            metafile.Width(), metafile.Height(),
            0, 0, lpBI->bmiHeader.biWidth, 
            lpBI->bmiHeader.biHeight,
            pDIBBits, lpBI, DIB_RGB_COLORS, SRCCOPY);
        GlobalUnlock(hGMem) ;
        CloseClipboard() ;
    }

That's it! Enjoy!

License

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


Written By
Software Developer (Senior) Sirius Analytical Instruments
United Kingdom United Kingdom
A research and development programmer working for a pharmaceutical instrument company for the past 17 years.

I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)

I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

Comments and Discussions

 
GeneralTypical How People Who Post Here Dont Test It Pin
xox_c0bra_xox8-Sep-09 7:44
xox_c0bra_xox8-Sep-09 7:44 
GeneralPaste CF_METAFILEPICT in a rtf dialog box app Pin
Filomela24-Mar-04 22:07
Filomela24-Mar-04 22:07 
Generalbug Pin
Anonymous3-Nov-03 13:42
Anonymous3-Nov-03 13:42 
GeneralRe: bug Pin
Jesper Knudsen9-Dec-04 3:21
Jesper Knudsen9-Dec-04 3:21 
QuestionLocal copy of clipboard memory ? Pin
storep28-Oct-03 23:03
storep28-Oct-03 23:03 
Your example is excellent, because the code is short simple and it works !
Hoewever there is an important issue that is not mentioned :
If you want to procces the graphics imported from the clipboard you need a local copy of the imported memory block. That would be easy if you know the size of the clipboard contents but apparently there is no general function for this ?

You might thinh that it is the users own problem to know the size of the imported structure because you have to decide on (or check for) the type of object you paste.

BUT, when you as in your code import a DIB you do not know the size, and apperently there is no function for that either in VC++6.0.

Note that when you read from file the problem does not exist because the total size of the DIB (or file) is written in the FILEINFOHEADER. But the information in the FILEINFOHEADER is not part of the DIB !

It must be fair to say that it is simply a desig-flaw that the total size in bytes, is not part of the DIB-structure !

But since it is so, what do you do to retrive the size of a DIB, since it is quite complicated to calculate it from all the other parameters present in the INFOHEADER ?

AnswerRe: Local copy of clipboard memory ? Pin
Anonymous12-May-04 12:03
Anonymous12-May-04 12:03 
GeneralMr.Roger Allen, I need your help!!Come on... Pin
Chao Zuo6-Aug-03 0:17
Chao Zuo6-Aug-03 0:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.