views:

17

answers:

1

I'm trying to get access to Excel 2003 Chart copied into the clipboard.

The chart image pastes fine into mspaint or wordpad.

The problem is that I don't see the chart's data on my System.Windows.Forms.Clipboard object.

I've read the following post:

http://stackoverflow.com/questions/1405756/pasting-image-from-excel-2003-clipboard

and in my particular scenario the only time the PNG, JFIF, or GIF formats appear as formats on the clipboard DataObject is when I go to the Excel clipboard manager (in the Excel application) and re-copy the chart again while it's open.

That is, if I clear my clipboard, open Excel 2003, create a chart, right click it, hit Copy, then check Clipboard.GetDataObject().GetFormats(), all I see is:

Clipboard.GetDataObject().GetFormats()
{string[6]}
    [0]: "EnhancedMetafile"  // is null
    [1]: "Embed Source"  // is a MemoryStream of about 10KB which seems to be an OLE representation for the whole workbook
    [2]: "Object Descriptor" // a very short (10 bytes) MemoryStream
    [3]: "Link Source" // a very short (10 bytes) MemoryStream
    [4]: "Link Source Descriptor"  // a very short (10 bytes) MemoryStream
    [5]: "Link"  // null 

If I open the Excel Clipboard Manager under the Edit > Office Clipboard then copy the same chart, even though Clipboard.ContainsImage() returns false, I see:

Clipboard.GetDataObject().GetFormats()
{string[10]}
    [0]: "Office Drawing Shape Format"
    [1]: "MetaFilePict"
    [2]: "EnhancedMetafile"
    [3]: "PNG+Office Art"  // can read with Image.FromStream
    [4]: "JFIF+Office Art"  // can read with Image.FromStream
    [5]: "GIF+Office Art"  // can read with Image.FromStream
    [6]: "PNG" // can read with Image.FromStream
    [7]: "JFIF" // can read with Image.FromStream
    [8]: "GIF" // can read with Image.FromStream
    [9]: "ActiveClipBoard"

and can get at any one of the image formats there as a MemoryStream without any problems.

I need this to work without having to open the Excel Clipboard Manager. It works fine on 2007 and 2010 (which also includes a regular Bitmap format for my convenience so that Clipboard.ContainsImage() returns true)...

I've verified this behavior on multiple workstations.

I'm thinking next steps may be to get at the native System.Runtime.InteropServices.ComTypes.IDataObject or worse yet get a handle on the COM object for the running instance of Excel......but I'd rather not have to.

Thanks for any help...

A: 

Wow....well I hope this helps someone else....

I had the random idea to try the WPF clipboard object (System.Windows.Clipboard) before resorting to going straight to OLE32.dll....

Lo and behold...

System.Windows.Clipboard.GetDataObject().GetFormats()
{string[7]}
    [0]: "EnhancedMetafile"
    [1]: "System.Drawing.Imaging.Metafile"
    [2]: "Embed Source"
    [3]: "Object Descriptor"
    [4]: "Link Source"
    [5]: "Link Source Descriptor"
    [6]: "Link"

sure enough:

System.Windows.Clipboard.GetData(System.Windows.Clipboard.GetDataObject().GetFormats()[0])
    {System.Drawing.Imaging.Metafile}

and so...

((Image)System.Windows.Clipboard.GetData(System.Windows.Clipboard.GetDataObject().GetFormats()[0])).Save("C:\\test1.jpg")
    base {System.Drawing.Image}: {System.Drawing.Imaging.Metafile}

works like magic...

I suspect going straight for the OLE32.dll would have worked too, since both Windows Forms and WPF's Clipboard APIs go there anyway...

JeffN825