+ Reply to Thread
Results 1 to 5 of 5

Displaying custom ribbon image using callback

Hybrid View

ByteMarks Displaying custom ribbon... 04-25-2025, 06:08 AM
romperstomper Re: Displaying custom ribbon... 04-25-2025, 07:36 AM
ByteMarks Re: Displaying custom ribbon... 04-25-2025, 07:37 AM
Artik Re: Displaying custom ribbon... 04-26-2025, 09:00 PM
ByteMarks Re: Displaying custom ribbon... 04-28-2025, 05:19 AM
  1. #1
    Forum Expert ByteMarks's Avatar
    Join Date
    07-23-2018
    Location
    UK
    MS-Off Ver
    O365 32bit (Windows)
    Posts
    3,079

    Displaying custom ribbon image using callback

    I have this ribbon callback to deterimine the image of a button. As shown it's using the inbuild mso images, which works.

    Sub GetButtonImage(control As IRibbonControl, ByRef returnedVal)
        If a = b Then
            returnedVal = "Info"  
        Else
            returnedVal = "AnimationOnclick" 
        End If
    End Sub
    However, instead of using an mso image I want to use a custom image called "MyImage" that I've added to the XML.
    I've tested that MyImage works when hard-coded into the XML, but when trying to set returnedVal = "MyImage" no picture shows.

    So in this example, if a = b then no image is shown when it should show the custom image.
    Sub GetButtonImage(control As IRibbonControl, ByRef returnedVal)
        If a = b Then
            returnedVal = "MyImage"  
        Else
            returnedVal = "AnimationOnclick" 
        End If
    End Sub
    Last edited by ByteMarks; 04-25-2025 at 06:17 AM.

  2. #2
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    England
    MS-Off Ver
    365, varying versions/builds
    Posts
    22,008

    Re: Displaying custom ribbon image using callback

    As I recall, the only method Ron de Bruin ever had for this was extracting the images from an unzipped copy of the file and then loading them from disk. There didn't appear to be any way to simply refer to embedded ones directly.
    Everyone who confuses correlation and causation ends up dead.

  3. #3
    Forum Expert ByteMarks's Avatar
    Join Date
    07-23-2018
    Location
    UK
    MS-Off Ver
    O365 32bit (Windows)
    Posts
    3,079

    Re: Displaying custom ribbon image using callback

    I did it using GDI+ and having the images in a separate folder, but disappointed that there doesn't seem a way for VBA to reference images within the construct of the file.

    In a module:
    #If VBA7 Then
        ' 64-bit declaration using LongPtr
        Private Type GUID
            Data1 As Long
            Data2 As Integer
            Data3 As Integer
            Data4(0 To 7) As Byte
        End Type
    
        Private Type PICTDESC
            Size As Long
            Type As Long
            hPic As LongPtr
            hPal As LongPtr
        End Type
    
        Private Type GdiplusStartupInput
            GdiplusVersion As Long
            DebugEventCallback As LongPtr
            SuppressBackgroundThread As Long
            SuppressExternalCodecs As Long
        End Type
    
        Private Declare PtrSafe Function GdiplusStartup Lib "GDIPlus" (token As LongPtr, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As LongPtr = 0) As Long
        Private Declare PtrSafe Function GdipCreateBitmapFromFile Lib "GDIPlus" (ByVal filename As LongPtr, bitmap As LongPtr) As Long
        Private Declare PtrSafe Function GdipCreateHBITMAPFromBitmap Lib "GDIPlus" (ByVal bitmap As LongPtr, hbmReturn As LongPtr, ByVal background As LongPtr) As Long
        Private Declare PtrSafe Function GdipDisposeImage Lib "GDIPlus" (ByVal image As LongPtr) As Long
        Private Declare PtrSafe Function GdiplusShutdown Lib "GDIPlus" (ByVal token As LongPtr) As Long
        Private Declare PtrSafe Function OleCreatePictureIndirect Lib "oleaut32.dll" (PicDesc As PICTDESC, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long 'note oleault21
    #Else
        ' 32-bit declaration using Long
        Private Type GUID
            Data1 As Long
            Data2 As Integer
            Data3 As Integer
            Data4(0 To 7) As Byte
        End Type
    
        Private Type PICTDESC
            Size As Long
            Type As Long
            hPic As Long
            hPal As Long
        End Type
    
        Private Type GdiplusStartupInput
            GdiplusVersion As Long
            DebugEventCallback As Long
            SuppressBackgroundThread As Long
            SuppressExternalCodecs As Long
        End Type
    
        Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
        Private Declare Function GdipCreateBitmapFromFile Lib "GDIPlus" (ByVal filename As Long, bitmap As Long) As Long
        Private Declare Function GdipCreateHBITMAPFromBitmap Lib "GDIPlus" (ByVal bitmap As Long, hbmReturn As Long, ByVal background As Long) As Long
        Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal image As Long) As Long
        Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
        Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PICTDESC, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long 'note olepro32
    #End If
    
    Public Function LoadImage(ByVal strFName As String) As IPicture
        Dim uGdiInput As GdiplusStartupInput
        Dim hGdiPlus As LongPtr
        Dim hGdiImage As LongPtr
        Dim hBitmap As LongPtr
    
        uGdiInput.GdiplusVersion = 1
    
        If GdiplusStartup(hGdiPlus, uGdiInput) = 0 Then
            If GdipCreateBitmapFromFile(StrPtr(strFName), hGdiImage) = 0 Then
                GdipCreateHBITMAPFromBitmap hGdiImage, hBitmap, 0
                Set LoadImage = ConvertToIPicture(hBitmap)
                GdipDisposeImage hGdiImage
            End If
            GdiplusShutdown hGdiPlus
        End If
    End Function
    
    Public Function ConvertToIPicture(ByVal hPic As LongPtr) As IPicture
        Dim uPicInfo As PICTDESC
        Dim IID_IDispatch As GUID
        Dim IPic As IPicture
    
        Const PICTYPE_BITMAP = 1
    
        With IID_IDispatch
            .Data1 = &H7BF80980
            .Data2 = &HBF32
            .Data3 = &H101A
            .Data4(0) = &H8B
            .Data4(1) = &HBB
            .Data4(2) = &H0
            .Data4(3) = &HAA
            .Data4(4) = &H0
            .Data4(5) = &H30
            .Data4(6) = &HC
            .Data4(7) = &HAB
        End With
    
        With uPicInfo
            .Size = Len(uPicInfo)
            .Type = PICTYPE_BITMAP
            .hPic = hPic
            .hPal = 0
        End With
    
        OleCreatePictureIndirect uPicInfo, IID_IDispatch, True, IPic
    
        Set ConvertToIPicture = IPic
    End Function
    Usage
    Sub GetButtonImage(control As IRibbonControl, ByRef returnedVal)
        If a = b Then
            Set returnedVal = LoadImage("C:\myimages\MyImage.jpg")
        Else
            returnedVal = "AnimationOnclick" 
        End If
    End Sub
    Useful info here too
    Last edited by ByteMarks; 04-25-2025 at 07:59 AM.

  4. #4
    Forum Expert
    Join Date
    08-17-2007
    Location
    Poland
    Posts
    2,543

    Re: Displaying custom ribbon image using callback

    A simpler workaround to the problem (if that is acceptable) is to prepare two buttons with hard-assigned icons. In turn, the code sets the visibility of the corresponding button. E.g. XML:
    PHP Code: 
    <customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="RibbonOnLoad">
      <
    ribbon>
        <
    tabs>
          <
    tab id="customTab" label="My Tab">
            <
    group id="customGroup" label="My Group">
              <
    button 
                id
    ="myDynamicButton_1"
                
    label="Click Me"
                
    image="MyImage"
                
    getVisible="GetButtonVisible"
                
    size="large"
                
    onAction="MyButtonAction" />
              <
    button 
                id
    ="myDynamicButton_2"
                
    label="Click Me"
                
    imageMso="AnimationOnClick"
                
    getVisible="GetButtonVisible"
                
    size="large"
                
    onAction="MyButtonAction" />
            </
    group>
          </
    tab>
        </
    tabs>
      </
    ribbon>
    </
    customUI
    Of course, the MyImage icon is stored in an XML file.

    VBA:
    Option Explicit
    
    Dim MyRibbon As IRibbonUI
    Dim A As Long
    Dim B As Long
    Dim mboolVisible As Boolean
    
    
    Public Sub RibbonOnLoad(ribbon As IRibbonUI)
        Set MyRibbon = ribbon
    End Sub
    
    
    Public Sub GetButtonVisible(control As IRibbonControl, ByRef returnedVal)
        If A = B Then
            returnedVal = (control.ID = "myDynamicButton_1") '(with "MyImage" icon)
        Else
            returnedVal = (control.ID = "myDynamicButton_2") '(with "AnimationOnclick" icon)
        End If
    End Sub
    
    
    Public Sub MyButtonAction(control As IRibbonControl)
        mboolVisible = Not mboolVisible
        If mboolVisible Then
            A = 3: B = 4
        Else
            A = 3: B = 3
        End If
        
        Application.OnTime Now, "RibbonInvalidate"
    End Sub
    
    
    Sub RibbonInvalidate()
        Call MyRibbon.Invalidate
    End Sub
    Artik

  5. #5
    Forum Expert ByteMarks's Avatar
    Join Date
    07-23-2018
    Location
    UK
    MS-Off Ver
    O365 32bit (Windows)
    Posts
    3,079

    Re: Displaying custom ribbon image using callback

    Thanks Artik, that's a good workaround.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. 'Invalid image error :481' when displaying 7 charts or more as image
    By djemy1975* in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 11-02-2018, 02:26 AM
  2. Put VBA ribbon together with Custom UI Editor Ribbon
    By czarlando in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 01-23-2016, 05:46 AM
  3. Assistance with Custom Tab and Groups on Excel Office Ribbon using Custom UI Editor.
    By sdavison in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 01-15-2015, 06:13 AM
  4. [SOLVED] An alternative to the Add-Ins ribbon tab - Global Custom Ribbon Tab by Ken Puls
    By mc84excel in forum Excel Programming / VBA / Macros
    Replies: 7
    Last Post: 09-16-2014, 10:01 PM
  5. [SOLVED] Callback for Ribbon drop down
    By icyrius in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 08-28-2013, 04:28 PM
  6. Displaying and Updating Image Dynamically (ActiveX Image Control?)
    By VTHokie11 in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 11-02-2011, 10:57 AM
  7. [SOLVED] Hyperlink to an image in other worksheet, displaying entire image.
    By twilliams in forum Excel Formulas & Functions
    Replies: 0
    Last Post: 02-07-2006, 06:10 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1