I am copying cells from an excel document to the clipboard so they can be inserted as an image elsewhere. The cells get copied to the clipboard fine, as I can paste the image manually after the code is run. However I cannot get ahold of the data. Here is my code:
tempWorkSheet.Range[tempWorkSheet.Cells[1, 1], tempWorkSheet.Cells[3, 3]].CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlPicture);
// returns true
var test = Clipboard.GetDataObject().GetDataPresent(DataFormats.EnhancedMetafile);
// returns true
var test2 = Clipboard.ContainsData(DataFormats.EnhancedMetafile);
// returns null
var test3 = Clipboard.GetData(DataFormats.EnhancedMetafile);
// returns null
var test4 = Clipboard.GetDataObject().GetData(DataFormats.EnhancedMetafile);
The data is stored as an EnhancedMetaFile
and I can see the data in there but I cannot pull it out. I am at my wits end trying to figure this out. Does anybody see something I am missing?
I saw this question posted but it did not help me much. I'm hoping somebody can.
I found a solution. The Clipboard.GetData(DataFormats.EnhancedMetafile)
call seems to be broken. But I managed to get it working using P/Invoke.
It's not the prettiest code, but it works, so for posterity here it is in all it's glory:
[DllImport("user32.dll", SetLastError = true)]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll")]
static extern IntPtr GetClipboardData(uint uFormat);
[DllImport("user32.dll", SetLastError = true)]
static extern bool CloseClipboard();
[DllImport("user32.dll")]
static extern bool EmptyClipboard();
[DllImport("gdi32.dll")]
static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, string lpszFile);
[DllImport("gdi32.dll")]
static extern bool DeleteEnhMetaFile(IntPtr hemf);
public Image GetMetaImageFromClipboard()
{
OpenClipboard(IntPtr.Zero);
IntPtr pointer = GetClipboardData(14);
string fileName = @"C:\Test\" + Guid.NewGuid().ToString() + ".emf";
IntPtr handle = CopyEnhMetaFile(pointer, fileName);
Image image;
using (Metafile metafile = new Metafile(fileName))
{
image = new Bitmap(metafile.Width, metafile.Height);
Graphics g = Graphics.FromImage(image);
EmptyClipboard();
CloseClipboard();
g.DrawImage(metafile, 0, 0, image.Width, image.Height);
}
DeleteEnhMetaFile(handle);
File.Delete(fileName);
return image;
}
Did you run the code from an STA thread? For example:
class Program
{
static void Main(string[] args)
{
RunInSta(() =>
{
var dataObject = Clipboard.GetDataObject();
foreach (string format in dataObject.GetFormats())
{
Console.WriteLine(format);
}
});
}
internal static void RunInSta(Action action)
{
Thread thread = new Thread(() => action());
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With