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:
Pasting Image from Excel 2003 Clipboard
and in my particular s开发者_开发技巧cenario 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...
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...
精彩评论