For those interested here is the VB net version of Michael's code:
Public NotInheritable Class PictureDispConverter
Shared ReadOnly iPictureDispGuid As System.Guid = GetType(stdole.IPictureDisp).GUID
'Shared ReadOnly HandleCollector As New HandleCollector("Icon handles", 1000)
' Converts IPictureDisp to Icon if it is possible
Public Shared Function PictureDispToIcon(pictureDisp As stdole.IPictureDisp) As Icon
Dim icon As Icon = Nothing
If pictureDisp IsNot Nothing AndAlso pictureDisp.Type = CType(3, Short) Then
icon = Icon.FromHandle(New IntPtr(pictureDisp.Handle))
End If
Return icon
End Function
' Converts IPictureDisp to Image if it is possible
Public Shared Function PictureDispToImage(pictureDisp As stdole.IPictureDisp) As Image
Dim image As Image = Nothing
If pictureDisp IsNot Nothing Then
If pictureDisp.Type = CType(1, Short) Then
Dim hpalette As IntPtr = New IntPtr(pictureDisp.hPal)
image = Image.FromHbitmap(New IntPtr(pictureDisp.Handle), hpalette)
End If
If pictureDisp.Type = CType(2, Short) Then
image = New Metafile(New IntPtr(pictureDisp.Handle), New WmfPlaceableFileHeader())
End If
End If
Return image
End Function
' Converts an Icon into a IPictureDisp
Public Shared Function ToIPictureDisp(icon As Icon) As stdole.IPictureDisp
Return OleCreatePictureIndirect(New PictDesc.Icon(icon), iPictureDispGuid, True)
End Function
' Converts an Image into a IPictureDisp
Public Shared Function ToIPictureDisp(image As Image) As stdole.IPictureDisp
Return OleCreatePictureIndirect(
If(TypeOf image Is Bitmap, New PictDesc.Bitmap(DirectCast(image, Bitmap)), New PictDesc.Bitmap(New Bitmap(image))),
iPictureDispGuid, True)
End Function
<DllImport("OleAut32.dll", PreserveSig:=False)>
Private Shared Function OleCreatePictureIndirect(pictDescIcon As PictDesc.Icon, ByRef iid As System.Guid, fOwn As Boolean) As stdole.IPictureDisp
End Function
<DllImport("OleAut32.dll", PreserveSig:=False)>
Private Shared Function OleCreatePictureIndirect(pictDescBitmap As PictDesc.Bitmap, ByRef iid As System.Guid, fOwn As Boolean) As stdole.IPictureDisp
End Function
Private NotInheritable Class PictDesc
Public Const PicTypeUninitialized As Short = -1
Public Const PicTypeNone As Short = 0
Public Const PicTypeBitmap As Short = 1
Public Const PicTypeMetafile As Short = 2
Public Const PicTypeIcon As Short = 3
Public Const PicTypeEnhMetafile As Short = 4
<StructLayout(LayoutKind.Sequential)>
Public Class Icon
Friend cbSizeOfStruct As Integer = Marshal.SizeOf(GetType(PictDesc.Icon))
Friend picType As Integer = PicTypeIcon
Friend hicon As IntPtr = IntPtr.Zero
Friend unused1 As Integer
Friend unused2 As Integer
Friend Sub New(icon As System.Drawing.Icon)
Me.hicon = icon.ToBitmap().GetHicon()
End Sub
End Class
<StructLayout(LayoutKind.Sequential)>
Public Class Bitmap
Friend cbSizeOfStruct As Integer = Marshal.SizeOf(GetType(PictDesc.Bitmap))
Friend picType As Integer = PicTypeBitmap
Friend hbitmap As IntPtr = IntPtr.Zero
Friend hpal As IntPtr = IntPtr.Zero
Friend unused As Integer
Friend Sub New(bitmap As System.Drawing.Bitmap)
Me.hbitmap = bitmap.GetHbitmap()
End Sub
End Class
End Class
End Class
And I believe there are two more minor edits to the original code needed (use 'System.Guid' instead of 'GUID' in both Picture and Bitmap variants of the OleCreatePictureIndirect Function):
<DllImport("OleAut32.dll", PreserveSig:=False)>
Private Shared Function OleCreatePictureIndirect(pictDescIcon As PictDesc.Icon, ByRef iid As System.Guid, fOwn As Boolean) As stdole.IPictureDisp
End Function
<DllImport("OleAut32.dll", PreserveSig:=False)>
Private Shared Function OleCreatePictureIndirect(pictDescBitmap As PictDesc.Bitmap, ByRef iid As System.Guid, fOwn As Boolean) As stdole.IPictureDisp
End Function
Dear @johnsonshiue
Could you, please, ask the Inventor team to make appropriate updates in VB Template included to SDK of further Inventor releases?