locked
Ribbon Custom Button Image Not Loading RRS feed

  • Question

  • I am working on a ribbon addin for Outlook 2010 using XML and VB callbacks (I have not used the ribbon designer) in Visual Studio 2010.

    What I want to do is add a custom image to a button loaded by another addin. Using the code below the image appears on a standard button but not on the button from the addin. The only difference seems to be using either the id or idQ properties, "idQ" does not work.

    Any help would be much appreciated.

     


    XML

    <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" xmlns:x1="MCSearch.Connect" xmlns:x2="VisionMerge.Connect" onLoad="Ribbon_OnLoad" loadImage="GetImage">
      <ribbon>
        <tabs>
     
     <tab idMso="TabReadMessage">

            <group idMso="GroupMailDelete" visible="false" />
            <group idMso="GroupRespond" visible="false" />
            <group idMso="GroupMoveActions" visible="false" />
            <group idQ="x2:IIRIS.Law" visible="false" />

            <group id="IIRIS.Law" label="IRIS Law" visible="true" insertBeforeMso="GroupRespond" autoScale="true">

              <button idQ="x2:SendSave.Email" image="SaveAndSend.jpg"/>         'this does NOT work
              <button id="Test" label ="Test"  image="SaveAndSend.jpg"/>     'this does work

            </group>

     </tab>
    </tabs>
    </ribbon>
    </customUI>

     


    'VB Callbacks

    Public Function GetImage(ByVal imageName As String) As stdole.IPictureDisp
            Return PictureConverter.ImageToPictureDisp(My.Resources.SaveAndSend)
    End Function


    Friend Class PictureConverter
            Inherits AxHost

            Private Sub New()
                MyBase.New(String.Empty)
            End Sub

            Public Shared Function ImageToPictureDisp(ByVal image As Image) As stdole.IPictureDisp
                Return CType(GetIPictureDispFromPicture(image), stdole.IPictureDisp)
            End Function
    End Class

    Tuesday, April 3, 2012 2:28 PM

Answers

  • Hi LCJ187,

    Thanks for posting in the  MSDN Forum.

    I recommend you to take a look following snippet.

    Imports System
    Imports System.Drawing
    Imports System.Collections.Generic
    Imports System.Runtime.InteropServices
    
    Public Module PictureDispConverter
    
        Public iPictureDispGuid As Guid = GetType(stdole.IPictureDisp).GUID
        Public Function ToIPictureDisp(ByVal ico As Icon) As stdole.IPictureDisp
    
            Dim pictIcon As New PICTDESC.Icon(ico)
            Return PictureDispConverter.OleCreatePictureIndirect(pictIcon, iPictureDispGuid, True)
        End Function
    
        Public Function ToIPictureDisp(ByVal picture As Image) As stdole.IPictureDisp
    
            Dim bm As Bitmap
            If TypeOf picture Is Bitmap Then
                bm = picture
            Else
                bm = New Bitmap(picture)
            End If
            Dim pictBit As New PICTDESC.Bitmap(bm)
            Return PictureDispConverter.OleCreatePictureIndirect(pictBit, iPictureDispGuid, True)
        End Function
    
    
        <DllImport("OleAut32.dll", EntryPoint:="OleCreatePictureIndirect", ExactSpelling:=True, PreserveSig:=False)> _
        Private Function OleCreatePictureIndirect(<MarshalAs(UnmanagedType.AsAny)> ByVal picdesc As Object, ByRef iid As Guid, ByVal fOwn As Boolean) As stdole.IPictureDisp
        End Function
    
        Private ReadOnly hCollector As New HandleCollector("Icon handles", 1000)
    
        Private Class PICTDESC
    
            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
    
            <StructLayout(LayoutKind.Sequential)> _
            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 = 0
                Friend unused2 As Integer = 0
    
                Friend Sub New(ByVal 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 = PICTDESC.PICTYPE_BITMAP
                Friend hbitmap As IntPtr = IntPtr.Zero
                Friend hpal As IntPtr = IntPtr.Zero
                Friend unused As Integer = 0
    
                Friend Sub New(ByVal bitmap As System.Drawing.Bitmap)
                    Me.hbitmap = bitmap.GetHbitmap()
                End Sub
            End Class
    
        End Class
    
    End Module

    I thinnk you need cast your image first.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us


    Thursday, April 5, 2012 10:12 AM

All replies

  • Customization of ribbon from one add-in cannot be changed from another add-in. So what you want to achieve is not possible using VSTO/OOM.
    Tuesday, April 3, 2012 2:36 PM
  • Hi LCJ187,

    Thanks for posting in the  MSDN Forum.

    I recommend you to take a look following snippet.

    Imports System
    Imports System.Drawing
    Imports System.Collections.Generic
    Imports System.Runtime.InteropServices
    
    Public Module PictureDispConverter
    
        Public iPictureDispGuid As Guid = GetType(stdole.IPictureDisp).GUID
        Public Function ToIPictureDisp(ByVal ico As Icon) As stdole.IPictureDisp
    
            Dim pictIcon As New PICTDESC.Icon(ico)
            Return PictureDispConverter.OleCreatePictureIndirect(pictIcon, iPictureDispGuid, True)
        End Function
    
        Public Function ToIPictureDisp(ByVal picture As Image) As stdole.IPictureDisp
    
            Dim bm As Bitmap
            If TypeOf picture Is Bitmap Then
                bm = picture
            Else
                bm = New Bitmap(picture)
            End If
            Dim pictBit As New PICTDESC.Bitmap(bm)
            Return PictureDispConverter.OleCreatePictureIndirect(pictBit, iPictureDispGuid, True)
        End Function
    
    
        <DllImport("OleAut32.dll", EntryPoint:="OleCreatePictureIndirect", ExactSpelling:=True, PreserveSig:=False)> _
        Private Function OleCreatePictureIndirect(<MarshalAs(UnmanagedType.AsAny)> ByVal picdesc As Object, ByRef iid As Guid, ByVal fOwn As Boolean) As stdole.IPictureDisp
        End Function
    
        Private ReadOnly hCollector As New HandleCollector("Icon handles", 1000)
    
        Private Class PICTDESC
    
            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
    
            <StructLayout(LayoutKind.Sequential)> _
            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 = 0
                Friend unused2 As Integer = 0
    
                Friend Sub New(ByVal 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 = PICTDESC.PICTYPE_BITMAP
                Friend hbitmap As IntPtr = IntPtr.Zero
                Friend hpal As IntPtr = IntPtr.Zero
                Friend unused As Integer = 0
    
                Friend Sub New(ByVal bitmap As System.Drawing.Bitmap)
                    Me.hbitmap = bitmap.GetHbitmap()
                End Sub
            End Class
    
        End Class
    
    End Module

    I thinnk you need cast your image first.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us


    Thursday, April 5, 2012 10:12 AM
  • Hi Tom_Xu MSFT and DamianD,

    Thanks for your help on this.

    Louis

    Thursday, April 5, 2012 4:24 PM