Copy GDI+ Drawing To Clipboard

When I just joined this company, one of my fellow scientist asked me if there's any way to copy his sophisticated scientific plots to clipboard and he could paste the clipboard copy onto one of his office presentation. I searched msdn a little bit and found several ways to do it. Since he used GDI+ to draw the scientific plots, I implemented this by using Windows Meta File definition in memory.

First of all, we need a little helper to handle Windows Meta File format.

using System;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

public class ClipboardMetafileHelper
{
    [DllImport("user32.dll")]
    static extern bool OpenClipboard(IntPtr hWndNewOwner);
    [DllImport("user32.dll")]
    static extern bool EmptyClipboard();
    [DllImport("user32.dll")]
    static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
    [DllImport("user32.dll")]
    static extern bool CloseClipboard();
    [DllImport("gdi32.dll")]
    static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, IntPtr hNULL);
    [DllImport("gdi32.dll")]
    static extern bool DeleteEnhMetaFile(IntPtr hemf);

    // Metafile mf is set to an invalid state inside this function
    static public bool PutEnhMetafileOnClipboard(IntPtr hWnd, Metafile mf)
    {
        bool bResult = false;
        IntPtr hEMF, hEMF2;
        hEMF = mf.GetHenhmetafile(); // invalidates mf
        if (!hEMF.Equals(IntPtr.Zero))
        {
            hEMF2 = CopyEnhMetaFile(hEMF, new IntPtr(0));
            if (!hEMF2.Equals(IntPtr.Zero))
            {
                if (OpenClipboard(hWnd))
                {
                    if (EmptyClipboard())
                    {
                        IntPtr hRes = SetClipboardData(14 /*CF_ENHMETAFILE*/, hEMF2);
                        bResult = hRes.Equals(hEMF2);
                        CloseClipboard();
                    }
                }
            }
            DeleteEnhMetaFile(hEMF);
        }
        return bResult;
    }
}

Then create a meta file in memory. (So, there's no physical file on the hard disc. We're only using Meta File format.)

MemoryStream ms = new MemoryStream();
Graphics g = CreateGraphics();
IntPtr ipHdc = g.GetHdc();
Metafile mf = new Metafile(ms, ipHdc);
g.ReleaseHdc(ipHdc);
g.Dispose();

Get the Graphics and draw on it as GDI+ way.

Graphics g = Graphics.FromImage(mf);
g.DrawLine(Pens.Blue, new Point(10, 10), new Point(100, 100));
g.Dispose();

My coworker replaced the second line with his actual plotting function passing Graphics as parameter.
Finally, copy the meta file to clipboard.

ClipboardMetafileHelper.PutEnhMetafileOnClipboard(this.Handle, mf);

And you can paste it onto any windows application which supports clipboard.
I've tried MS Word and PowerPoint. It works perfectly!

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License