Changing RibbonButton.ImageMso at runtime doesn't work :(

Add-in Express™ Support Service
That's what is more important than anything else

Changing RibbonButton.ImageMso at runtime doesn't work :(
 
Alexander H.




Posts: 6
Joined: 2011-02-27
Hi,

I hope the following is a bug and not a feature ... ;)

I can't change the icon of a RibbonButton at runtime.

I initialize my button as follows:
RibbonButtonXY.ImageMso = "GroupMailMergeStart"

At runtime I want to change the caption and the ImageMso of my RibbonButtonXY.
Only the caption is changing but not the icon.

Any idea?
Posted 03 Mar, 2011 09:09:08 Top
Eugene Astafiev


Guest


Hi Alexander,

You are on the wrong avenue: this is not a bug. The Ribbon UI is a static thing from birth. Please read more about this in the http://www.add-in-express.com/docs/net-ribbon-components.php section of the online documentation (see the How Ribbon controls are created? and Properties and events of Ribbon components parts).
Posted 03 Mar, 2011 09:50:28 Top
Heinz-Josef Bomanns




Posts: 206
Joined: 2008-02-28
Hi Alexander,

>You are on the wrong avenue

Sorry for beeing a smart-ass again, but it is possible to change 'imageMso' at runtime, i've used that for years in my old VB6 add ins, it's just a combination of 'getImage="GetImage"' and 'MyRibbon.InvalidateControl "MyControl". I've posted the very same problem as Alexander H., please have a look at this thread and ask Andrei how far they are with 'looking into it':

http://www.add-in-express.com/forum/read.php?FID=5&TID=7542&MID=37915

If we can change the caption, why not the image? I see no technical reason and Microsoft usses it all the time in all office apps...
__________________
Greetings, HJB
Posted 06 Mar, 2011 22:01:47 Top
Eugene Astafiev


Guest


Hi Heinz-Josef,

No, it is not. You are not allowed to set the ImageMso property of the ribbon control in the PropertyChanging event handler. Please note that the ImageMso property is set via the imageMso attribute in the XML markup (not a callback function, for example, the getVisiable callback and etc.). However, you can change the image property of your ribbon controls using the getImage callback.

Anyway, could you please share a sample VB6 project which does the trick? I will take a look at it.
Posted 07 Mar, 2011 05:04:41 Top
Heinz-Josef Bomanns




Posts: 206
Joined: 2008-02-28
Hi Eugene,

>Please note that the ImageMso property is set via the imageMso attribute in the XML markup
>(not a callback function, for example, the getVisiable callback and etc.)

Yeep, but if you specify for e.g. '<button id="btnBla" label="Bla" getImage= "GetImage" />' the 'GetImage()' function has to return a valid 'imageMso'. So with using 'MyRibbon.InvalidateControl "btnBla"' you can change the displayed image by specifying another 'imageMso':

Public Function GetImage(Ctrl As IRibbonControl) As String

  On Error Resume Next
  If Ctrl.id = "btnZAEXPL" Or Ctrl.id = "btnZAINSP" Then
    GetImage = "Paste"
  ElseIf Left$(Ctrl.id, 3) = "mnu" Then
    GetImage = "AttachItem"
  ElseIf InStr(Ctrl.id, "btnOption") <> 0 Then
    GetImage = "PropertySheet"
  Else
    GetImage = "HappyFace"
  End If 'Ctrl.ID?
  
End Function 'GetImage


This is no trick, it's the way Microsoft designed it?
__________________
Greetings, HJB
Posted 10 Mar, 2011 21:15:56 Top
Eugene Astafiev


Guest


Hi Heinz-Josef,

Please take a look at the Loading Images section of the http://msdn.microsoft.com/en-us/library/aa338202%28v=office.12%29.aspx article. It states:

To supply the button's image, Office calls the GetImage function. It passes the parameter "mypic.jpg" and expects an IPictureDisp object in return.


I.e. the GetImage callback should return an IPictureDisp object (not string).
Posted 11 Mar, 2011 06:19:55 Top
Heinz-Josef Bomanns




Posts: 206
Joined: 2008-02-28
Hi Eugene,

'GetImage' - which is just the name of a function, you can it also call it 'MyImageDeliveryFunction' - is used in two ways: One if you specify a global "loadImage" like this:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" 
  [B]loadImage="GetImage"[/B]>


In this case it has to return an IPictureDisp. The other way is like i use it for specific elements for e.g. with

'<button id="btnBla" label="Bla" [B]getImage= "GetImage"[/B] />' 


In Part 2 of the mentioned WhitePaper you can read:

button

Represents a button control.

Attributes

Common: description, enabled, getDescription, getEnabled, [B]getImage[/], getImageMso, getKeytip, getLabel, getScreentip, getShowImage, getShowLabel, getSize, getSupertip, getVisible, id, idMso, idQ, image, imageMso, insertAfterMso, insertAfterQ, insertBeforeMso, insertBeforeQ, keytip, label, onAction, screentip, showImage, showLabel, size, supertip, tag, visible


If you use this, the 'GetImage' or whatever the function is named, has to return an 'imageMso' like 'FileOpen', 'Paste', 'HappyFace'...

The Ribbon UI supports the use of dynamic images from the very beginning, but unfortunatly it's not implemented in the 'PropertyChange' event of ADX. It could be simply added like it is now implemented for 'ADXRibbonControlPropertyType.Caption', 'ADXRibbonControlPropertyType.Enabled' and so on...
__________________
Greetings, HJB
Posted 11 Mar, 2011 23:46:40 Top
Eugene Astafiev


Guest


Hi Heinz-Josef,

You are on the wrong avenue. The getImage callback should return an instance of the IPictureDisp interface. Moreover, according to the http://msdn.microsoft.com/en-us/library/aa722523%28v=office.12%29.aspx article a possible declaration is:

C#: IPictureDisp GetImage(IRibbonControl control)

VBA: Sub GetImage(control As IRibbonControl, ByRef image)

C++: HRESULT GetImage([in] IRibbonControl *pControl, [out, retval] IPictureDisp ** ppdispImage)

Visual Basic: Function GetImage(control as IRibbonControl) as IPictureDisp


Also I have found the following in MSDN:

The OnGetImage callback updates the image in the button to reflect the last application launched. When we defined our customization, we used images included with Office in the imageMso attribute. However, you may have noticed that there is a getImage callback, but not a getImageMso callback. So how can we load a built-in image dynamically? Well, it turns out that while there isn't a getImageMso callback, there is a GetImageMso method! And, this method was added on the CommandBars object of all places. This method returns the image for a named image that is included with Office as you would define in the imageMso attribute. So, we can simply use this method to retrieve the image from Office.

Sub OnGetImage(ctl As IRibbonControl, ByRef Image)
' default to calculator
If (mstrImage = "") Then
mstrImage = "Calculator"

' set the image
Set Image = CommandBars.GetImageMso(mstrImage, 16, 16)
End Sub


Please read more about this in the
http://msdn.microsoft.com/en-us/library/dd548011%28v=office.12%29.aspx article in MSDN.
Posted 12 Mar, 2011 07:44:44 Top
Heinz-Josef Bomanns




Posts: 206
Joined: 2008-02-28
Hi Eugene,

http://www.accessribbon.de/en/?Access_-_Ribbons:Callbacks:getImage

getImage

Sets a IPictureDisp object or a ImageMso to the ribbon control.


Another example here:

http://www.accessribbon.de/en/?Access_-_Ribbons:User_Defined_Icons___Pictures_In_Ribbon_Controls

Thats the way we use it in a dozend VB6 add ins and it works perfectly. The Ribbon UI supports it, PropertyChanged not...
__________________
Greetings, HJB
Posted 13 Mar, 2011 12:38:27 Top
Eugene Astafiev


Guest


Hi Heinz-Josef,

This is not documented feature of the Ribbon extensibility. As you may see it was not described in the Ribbon official guide (I mean MSDN). However, I would recommend using the PropertyChanging event instead (note that you need specify the initial image). Does it work for you?
Posted 14 Mar, 2011 09:20:54 Top