Kibou
Kibou

Reputation: 63

Powerpoint VBA/Macro: Deactivate (Grey out) Button on Ribbon, if no shape is selected

I have a macro in Powerpoint that gives me Information of a Shape. To bypass the error if no shape is selected I insert an errormask. However, this is very annoying.

Is it therefore possible to grey out the button if e.g. no Shape is selected. That way the user would npot even have a chance to click it.

Custom UI XML: http://pastebin.com/T6NQ8WF8

Upvotes: 0

Views: 3229

Answers (1)

David Zemens
David Zemens

Reputation: 53663

Assuming you are using a 2007+ version of PowerPoint, the only way to manipulate the ribbon controls, buttons, etc., is through ribbon extensibility. It is possible to do this at run-time, with a vba hook, but it is much more difficult than in previous versions of PowerPoint where you could just use VBA to manipulate the controls' .Enabled or .Visible properties.

Here is an example of using ribbon extensibility to customize the ribbon at run-time. As you can see, it is not easy. I will show this in Option 2, below.

In this case, you have an error condition that you can easily identify using the .Type property of the Selection.ShapeRange. I think that attempting to conditionally disable this button at run-time (Option 2, below) is probably more trouble than it is worth.

Update

Is there a setting that greys your all buttons that don't have an effect.

No. The macros are the "effect", even if the result of the macro is that no action is performed. What you are asking is whether there is a setting which can compile and interpret your macros, determine whether that macro performs "an action" (e.g., manipulates a shape, changes a property assignment, etc.) and then disable buttons based on this determination. There is no such setting.

OPTION 1 -- Simply Do Not Display the MsgBox; Perform No Action if Invalid Selection

I will make some edits to clean up your code and use a better method of avoiding that error:

Sub Infos()

   Dim n as String
   Dim w as String
   Dim h as String
   Dim l as String
   Dim T as String

   With ActiveWindow.Selection.ShapeRange
   Select Case .Type
        Case 0
            'MsgBox ("No shape selected.")
            Exit Sub
        Case Else
            n = .Name
            w = .Width
            h = .Height
            l = .Left
            T = .Top

            MsgBox "Name: " & n & Chr$(CharCode:=13) & "Länge: " & w & _
                   Chr$(CharCode:=13) & "Höhe: " & h & Chr$(CharCode:=13) & _
                   "Linkeposition: " & l & Chr$(CharCode:=13) & "Höhenposition: " & T
    End Select
End Sub

OPTION 2 -- Use an Application Event Handler and Manipulate Ribbon at Run-Time

I mentioned that this is not easy. I uploaded an example file to Google Docs Presentation1.pptm. This should get you started. You can see now how much difficult this method is. If you are creating a PPAM/Add-In file, there are further considerations and complexities you may encounter. Good luck!

There are several errors in your code.

1. Your XML is not valid when I check in Custom UI Editor. I edited it here:

http://pastebin.com/SpG0Rtqq

2. Your Infos macro contains errors. You omit the End With statement, also, your n assignment will fail (and the rest of them will produce strange result) if the selection is multiple shapes. You can fix that by:

n = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Name)
w = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Width)
h = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Height)
l = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Left)
T = IIf(.ShapeRange.Count > 1, "Multiple shapes", .ShapeRange(1).Top)

Once you have fixed those components...

Add a module called mod_EventHandler, which includes this code. This will create an application event-handler class object, cEventClass:

Option Explicit
Public cPPTObject As New cEventClass
Public TrapFlag As Boolean

Sub TrapEvents()
'Creates an instance of the application event handler
If TrapFlag = True Then
   MsgBox "Relax, my friend, the EventHandler is already active.", vbInformation + vbOKOnly, "PowerPoint Event Handler Example"
   Exit Sub
End If
   Set cPPTObject.PPTEvent = Application
   TrapFlag = True
End Sub

Sub ReleaseTrap()
If TrapFlag = True Then
   Set cPPTObject.PPTEvent = Nothing
   Set cPPTObject = Nothing
   TrapFlag = False
End If
End Sub

Since we need this class object, add a class module to your PowerPoint file, named cEventClass. In this module, put this code below. This code forces a refresh of the ribbon. This procedure implicitly calls the EnabledBtInfo subroutine, which then tests if the current selection is Shape(s).

Option Explicit
Public WithEvents PPTEvent As Application
Private Sub PPTEvent_WindowSelectionChange(ByVal Sel As Selection)
    'Force refresh of the "btInfo" button:
    RefreshRibbon "btInfo"
End Sub

And finally, another standard code module with this code to control the Button's visibility/enabled. Note that EnabledBtInfo is the VBA Hook for this button, and it tests whether Selection is shapes, before refreshing the ribbon:

Option Explicit
Public Rib As IRibbonUI
Public xmlID As String

'Callback for customUI.onLoad
Sub RibbonOnLoad(ribbon As IRibbonUI)
    TrapEvents  'instantiate the event handler
    Set Rib = ribbon
End Sub

Sub EnabledBtInfo(control As IRibbonControl, ByRef returnedVal)
    'Check the ActiveWindow.Selection.ShapeRange
    returnedVal = (ActiveWindow.Selection.Type = ppSelectionShapes)
    Call RefreshRibbon(control.Id)
End Sub

Sub RefreshRibbon(Id As String)
    xmlID = Id
    If Rib Is Nothing Then
        MsgBox "Error, Save/Restart your Presentation"
    Else
        Rib.Invalidate
    End If
End Sub

When a shape(s) is selected, the magnifying glass icon is enabled:

enter image description here

When shape(s) is not selected, button is disabled:

enter image description here

And finally, when multiple shapes are selected:

enter image description here

Upvotes: 1

Related Questions