How to convert Icon/Bitmap to IPictureDisp without VisualBasic.Compatibility.VB6.Support.IconToIPicture?

By Philippe Leefsma

Q:

Is there another approach to convert an image to IPictureDisp than using the deprecated namespace method "Microsoft.VisualBasic.Compatibility.VB6.Support.IconToIPicture"?

A:

The following utility class lets you get rid of that namespace functionality

It’s pretty straightforward to use, juts call the static method “PictureDispConverter.ToIPictureDisp”, however even if the return type is the same, IPictureDisp, an image for a button needs to be created from an Icon resource and an image for a browser node, from a Bitmap resource.

Here is VB.Net code for that utility:

    Public NotInheritable Class PictureDispConverter

 

        <DllImport("OleAut32.dll",

            EntryPoint:="OleCreatePictureIndirect",

            ExactSpelling:=True, PreserveSig:=False)>

        Private Shared Function OleCreatePictureIndirect(

             ByVal picdesc As Object,

            ByRef iid As Guid,

             ByVal fOwn As Boolean) As stdole.IPictureDisp

        End Function

 

        Shared iPictureDispGuid As Guid = GetType(stdole.IPictureDisp).GUID

 

        Private NotInheritable Class PICTDESC

 

            Private Sub New()

            End Sub

 

            ‘Picture Types

            Public Const PICTYPE_UNINITIALIZED As Short = -1

            Public Const PICTYPE_NONE As Short = 0

            Public Const PICTYPE_BITMAP As Short = 1

            Public Const PICTYPE_METAFILE As Short = 2

            Public Const PICTYPE_ICON As Short = 3

            Public Const PICTYPE_ENHMETAFILE As Short = 4

 

           

            Public Class Icon

                Friend cbSizeOfStruct As Integer =

                    Marshal.SizeOf(GetType(PICTDESC.Icon))

                Friend picType As Integer = PICTDESC.PICTYPE_ICON

                Friend hicon As IntPtr = IntPtr.Zero

                Friend unused1 As Integer

                Friend unused2 As Integer

 

                Friend Sub New(ByVal icon As System.Drawing.Icon)

                    Me.hicon = icon.ToBitmap().GetHicon()

                End Sub

            End Class

 

            Public Class Bitmap

                Friend cbSizeOfStruct As Integer =

                    Marshal.SizeOf(GetType(PICTDESC.Bitmap))

                Friend picType As Integer = PICTDESC.PICTYPE_BITMAP

                Friend hbitmap As IntPtr = IntPtr.Zero

                Friend hpal As IntPtr = IntPtr.Zero

                Friend unused As Integer

 

                Friend Sub New(ByVal bitmap As System.Drawing.Bitmap)

                    Me.hbitmap = bitmap.GetHbitmap()

                End Sub

            End Class

        End Class

 

        Public Shared Function ToIPictureDisp(

            ByVal icon As System.Drawing.Icon) As stdole.IPictureDisp

            Dim pictIcon As New PICTDESC.Icon(icon)

            Return OleCreatePictureIndirect(pictIcon, iPictureDispGuid, True)

        End Function

 

        Public Shared Function ToIPictureDisp(

            ByVal bmp As System.Drawing.Bitmap) As stdole.IPictureDisp

            Dim pictBmp As New PICTDESC.Bitmap(bmp)

            Return OleCreatePictureIndirect(pictBmp, iPictureDispGuid, True)

        End Function

    End Class

 

You may also want to check this post from Mod The Machine blog, where my colleague Wayne took time to produce a full sample demonstrating how to use that in an Inventor add-in.

 

And here is the C# version:

    public sealed class PictureDispConverter

    {

        [DllImport("OleAut32.dll",

            EntryPoint = "OleCreatePictureIndirect",

            ExactSpelling = true,

            PreserveSig = false)]

        private static extern stdole.IPictureDisp

            OleCreatePictureIndirect(

                [MarshalAs(UnmanagedType.AsAny)] object picdesc,

                ref Guid iid,

                [MarshalAs(UnmanagedType.Bool)] bool fOwn);

 

        static Guid iPictureDispGuid = typeof(stdole.IPictureDisp).GUID;

 

        private static class PICTDESC

        {

            //Picture Types

            public const short PICTYPE_UNINITIALIZED = -1;

            public const short PICTYPE_NONE = 0;

            public const short PICTYPE_BITMAP = 1;

            public const short PICTYPE_METAFILE = 2;

            public const short PICTYPE_ICON = 3;

            public const short PICTYPE_ENHMETAFILE = 4;

 

            [StructLayout(LayoutKind.Sequential)]

            public class Icon

            {

                internal int cbSizeOfStruct =

                    Marshal.SizeOf(typeof(PICTDESC.Icon));

                internal int picType = PICTDESC.PICTYPE_ICON;

                internal IntPtr hicon = IntPtr.Zero;

                internal int unused1;

                internal int unused2;

 

                internal Icon(System.Drawing.Icon icon)

                {

                    this.hicon = icon.ToBitmap().GetHicon();

                }

            }

 

            [StructLayout(LayoutKind.Sequential)]

            public class Bitmap

            {

                internal int cbSizeOfStruct =

                    Marshal.SizeOf(typeof(PICTDESC.Bitmap));

                internal int picType = PICTDESC.PICTYPE_BITMAP;

                internal IntPtr hbitmap = IntPtr.Zero;

                internal IntPtr hpal = IntPtr.Zero;

                internal int unused;

 

                internal Bitmap(System.Drawing.Bitmap bitmap)

                {

                    this.hbitmap = bitmap.GetHbitmap();

                }

            }

        }

 

        public static stdole.IPictureDisp ToIPictureDisp(

            System.Drawing.Icon icon)

        {

            PICTDESC.Icon pictIcon = new PICTDESC.Icon(icon);

 

            return OleCreatePictureIndirect(

                pictIcon, ref iPictureDispGuid, true);

        }

 

        public static stdole.IPictureDisp ToIPictureDisp(

            System.Drawing.Bitmap bmp)

        {

            PICTDESC.Bitmap pictBmp = new PICTDESC.Bitmap(bmp);

 

            return OleCreatePictureIndirect(pictBmp, ref iPictureDispGuid, true);

    &
#160;  
}

<

p style=”line-height: normal;margin: 0in 0in 0pt” class=”MsoNormal”>    }


Comments

3 responses to “How to convert Icon/Bitmap to IPictureDisp without VisualBasic.Compatibility.VB6.Support.IconToIPicture?”

  1. Pavel Rybar Avatar
    Pavel Rybar

    I have tried this class in Visual STudio 2014 .NET 4.5.1, but the Marshal.SizeOf throws exception: no meaningful size or offset – is there any solution for this error?

  2. I used your C# code and it worked great! Got it working in under 5 minutes. Thanks for the post Philippe!

  3. Rossano Santos da Trindade Avatar
    Rossano Santos da Trindade

    How do I improve the image quality? When I export, the quality is very low…

Leave a Reply to Pavel RybarCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading