Answered by:
Ribbon Custom Button Image Not Loading

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 CallbacksPublic Function GetImage(ByVal imageName As String) As stdole.IPictureDisp
Return PictureConverter.ImageToPictureDisp(My.Resources.SaveAndSend)
End Function
Friend Class PictureConverter
Inherits AxHostPrivate Sub New()
MyBase.New(String.Empty)
End SubPublic Shared Function ImageToPictureDisp(ByVal image As Image) As stdole.IPictureDisp
Return CType(GetIPictureDispFromPicture(image), stdole.IPictureDisp)
End Function
End ClassTuesday, 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