Get metafile from clipboard object

G

George Yefchak

Hi

I need to retrieve a metafile image from the clipboard and render it as a
bitmap in my application. In particular, an image will be placed on the
clipboard by pasting from PowerPoint (I really do need to do this!). The
original image is a bitmap, but PowerPoint doesn't place it on the clipboard
as such. A call to GetFormats() indicates that MetafilePict and
EnhancedMetaFile are available formats.

The following does NOT work:

Dim metaFile As System.Drawing.Imaging.Metafile

If data.GetDataPresent(DataFormats.MetafilePict) Then
obj = data.GetData(DataFormats.MetafilePict, True)
metaFile = CType(obj, System.Drawing.Imaging.Metafile)
....
End If
The GetDataPresent() test returns true, indicating there is a MetafilePict.
The GetData returns something (it's not "Nothing") but I can't figure out
what to do with it. The CType returns "Nothing" in metaFile.

Help?

Thanks,
--George


* George Yefchak
* Phone: 408-970-0419
* Cell: 408-981-5521
* E-mail: (e-mail address removed)
* Web: www.yefchak.com
 
C

Craig Vick [MSFT]

Hi George,

You may want to try using the type rather than the data format name. I'm
not sure why, but this seemed to work more reliably for me than using the
formats. The following works when I copy a picture from PowerPoint

Dim objData As DataObject = Clipboard.GetDataObject()

If objData.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
Dim bmp As System.Drawing.Bitmap =
CType(objData.GetData(GetType(System.Drawing.Bitmap)),
System.Drawing.Bitmap)
End If

I'll have to do a little research to find out the prescribed way to convert
the MemoryStream from the clipboard to a MetaFile.

Craig,
VB .Net Team
 
C

Craig Vick [MSFT]

Hi George,

I was able to get more information on your question. First of all, there
seems to be an issue getting apps in general and .NET apps to be able to
see each others metafiles when saved to the clipboard. Here's a KB article
that examines one half of this issue:
http://support.microsoft.com/?id=323530

There is a way to do what you want, but you have to use WinAPIs. Here's an
example (which you may want to refine).

1. Add a class named ClipboardAPI and add the following code to the class

Imports System.Runtime.InteropServices

Public Class ClipboardAPI

<DllImport("user32.dll", EntryPoint:="OpenClipboard", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenClipboard(ByVal hWnd As IntPtr) As Boolean
End Function

<DllImport("user32.dll", EntryPoint:="EmptyClipboard", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EmptyClipboard() As Boolean
End Function

<DllImport("user32.dll", EntryPoint:="SetClipboardData", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function SetClipboardData(ByVal uFormat As Integer, ByVal
hWnd As IntPtr) As IntPtr
End Function

<DllImport("user32.dll", EntryPoint:="CloseClipboard", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function CloseClipboard() As Boolean
End Function

<DllImport("user32.dll", EntryPoint:="GetClipboardData", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function GetClipboardData(ByVal uFormat As Integer) As
IntPtr
End Function

<DllImport("user32.dll", EntryPoint:="IsClipboardFormatAvailable", _
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function IsClipboardFormatAvailable(ByVal uFormat As
Integer) As Short
End Function
End Class

2. Add the following to your button click event

Const CF_ENHMETAFILE As Integer = 14

Dim henmetafile As IntPtr
Dim metaFile As System.Drawing.Imaging.Metafile

If ClipboardAPI.OpenClipboard(Me.Handle) Then
If ClipboardAPI.IsClipboardFormatAvailable(CF_ENHMETAFILE) <> 0
Then
henmetafile = ClipboardAPI.GetClipboardData(CF_ENHMETAFILE)
metaFile = New Metafile(henmetafile, True)
ClipboardAPI.CloseClipboard()
End If
End If

Hope this helps,
Craig VB.NET Team
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top