我正在尝试将一个已拖放到我的表单上的元文件中的注释数据,但是,此代码会生成错误:
附加信息:运行时遇到致命错误。错误的地址位于0xeb556610,位于线程0x2080。错误代码是0xc0000005。此错误可能是CLR中的错误,也可能是用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括COM-interop或PInvoke的用户封送错误,这可能会破坏堆栈。
我见过的每个代码示例都是关于从Metafile而不是元文件本身获取图像的。错误发生在DragDrop处理程序中的“Dim mf = Metafile”上,它永远不会到达枚举代码。
Private Sub Form1_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles Me.DragEnter
If e.Data.GetDataPresent(DataFormats.EnhancedMetafile, False) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Private Sub Form1_DragDrop(sender As Object, e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
If e.Data.GetDataPresent(DataFormats.EnhancedMetafile, False) Then
Dim mf As Metafile = e.Data.GetData(DataFormats.EnhancedMetafile, False)
Me.CreateGraphics().EnumerateMetafile(mf, New Point(0, 0), New Graphics.EnumerateMetafileProc(AddressOf MetafileCallback))
End If
End Sub
Private Function MetafileCallback(ByVal recordType As EmfPlusRecordType, ByVal flags As Integer, ByVal dataSize As Integer, ByVal data As IntPtr, ByVal callbackData As PlayRecordCallback) As Boolean
If recordType = EmfPlusRecordType.Comment Then
Debug.WriteLine("Got comment")
End If
End Function
答案 0 :(得分:1)
简短回答:你不能拖动图元文件。你不能。但是,您可以将它放在剪贴板上并使用User32.dll魔法获取它。
这里有get和put代码:
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class ClipboardMetafileHelper
<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:="IsClipboardFormatAvailable", _
SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function IsClipboardFormatAvailable(ByVal uFormat As Integer) 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:="GetClipboardData", _
SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function GetClipboardData(ByVal uFormat As Integer) 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("gdi32.dll", EntryPoint:="CopyEnhMetaFileA", _
SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function CopyEnhMetaFile(ByVal hemfSrc As IntPtr, ByVal hNULL As IntPtr) As IntPtr
End Function
<DllImport("gdi32.dll", EntryPoint:="DeleteEnhMetaFile", _
SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function DeleteEnhMetaFile(ByVal hemfSrc As IntPtr) As Boolean
End Function
Private Const CF_ENHMETAFILE As Integer = 14
' Metafile mf is set to a state that is not valid inside this function.
Public Shared Function PutEnhMetafileOnClipboard(ByVal hWnd As IntPtr, ByVal mf As Metafile) As Boolean
Dim bResult As Boolean = False
Dim hEMF, hEMF2 As IntPtr
hEMF = mf.GetHenhmetafile() ' invalidates mf
If Not hEMF.Equals(New IntPtr(0)) Then
hEMF2 = CopyEnhMetaFile(hEMF, New IntPtr(0))
If Not hEMF2.Equals(New IntPtr(0)) Then
If OpenClipboard(hWnd) Then
If EmptyClipboard() Then
Dim hRes As IntPtr
hRes = SetClipboardData(CF_ENHMETAFILE, hEMF2)
bResult = hRes.Equals(hEMF2)
CloseClipboard()
End If
End If
End If
DeleteEnhMetaFile(hEMF)
End If
Return bResult
End Function
Public Shared Function GetEnhMetafileOffClipboard(ByVal hWnd As IntPtr, ByRef mf As Metafile) As Boolean
Dim bResult As Boolean = False
Dim hEMF As IntPtr
If OpenClipboard(hWnd) Then
If IsClipboardFormatAvailable(CF_ENHMETAFILE) Then
hEMF = GetClipboardData(CF_ENHMETAFILE)
If Not hEMF.Equals(New IntPtr(0)) Then
mf = New Metafile(hEMF, True)
bResult = True
End If
End If
CloseClipboard()
End If
Return bResult
End Function
End Class