在运行时自定义 PowerPoint 功能区

Posted

技术标签:

【中文标题】在运行时自定义 PowerPoint 功能区【英文标题】:Customizing the PowerPoint Ribbon at Run-Time 【发布时间】:2013-07-13 22:08:22 【问题描述】:

我正在开发一个 PowerPoint 加载项,并希望在加载项应用程序运行时暂时禁用某些功能区控件。

我开发了一个解决方案,当插件启用时可以正常工作,但这还不够,因为它禁用了一些常用的控件,如 SlideMaster、SlideSorter 等。

我正在使用 PowerPoint 2010。

这是一个格式正确的示例 XML:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <ribbon startFromScratch="false">
        <tabs>
            <tab idMso="TabView">
                <group idMso="GroupMasterViews" getVisible="GetVisible"/>
            </tab>
        </tabs>
    </ribbon>
</customUI>

这是一个示例回调,取自this SO answer:

Sub GetVisible(control As IRibbonControl, ByRef returnedVal As Boolean)
    If TrapFlag Then
        returnedVal = False ' control is hidden
    Else:
        returnedVal = True  ' control is not hidden
    End If
End Sub

当我导航到 View 功能区时,一条警报通知我:

由于您的安全设置,该宏无法找到或已被禁用。

大概这是指GetVisible 宏?我的宏设置是:

启用所有宏(不推荐) 信任对 VBA 项目对象模型的访问

到目前为止,我一直在努力解决我发现的问题,但到目前为止无法实施建议。大多数答案都是针对 Excel 的。我还没有真正找到任何特定于 PowerPoint 的内容,但我认为将代码从一个应用程序移植到另一个应用程序应该不会非常困难,因为我已经在 VBA 中为许多其他事情做到了这一点。

我也尝试过this 方法,但SetCustomUIApplicationPresentation 级别的PowerPoint 中不可用,也许它是唯一的或仅适用于Visual Studio?

【问题讨论】:

【参考方案1】:

经过相当多的反复试验,我相信我有一个实用的解决方案,虽然有些事情我不确定,我将在下面描述。

我已经在一个 PPTM 文件中测试了这个,它带有一个子例程来控制公共 TrapFlag 变量,该变量决定是否隐藏/禁用某些控件。我还在 PPAM 中对此进行了测试,该标志在应用程序启动时设置,not 在加载插件时设置。

这让我可以在运行时操作 RibbonUI。

这是 XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>`
   <customUI onLoad="RibbonOnLoad" xmlns="http://schemas.microsoft.com/office/2009/07/customui">
     <commands>
       <command idMso="ViewSlideSorterView" getEnabled="EnableControl"/>
       <command idMso="ViewNotesPageView" getEnabled="EnableControl"/>
       <command idMso="ViewSlideShowReadingView" getEnabled="EnableControl"/>
       <command idMso="ViewSlideMasterView" getEnabled="EnableControl"/>
       <command idMso="ViewHandoutMasterView" getEnabled="EnableControl"/>
       <command idMso="ViewNotesMasterView" getEnabled="EnableControl"/>
       <command idMso="WindowNew" getEnabled="EnableControl"/>
   </commands>
   <ribbon startFromScratch="false">
       <tabs>
           <tab idMso="TabView">
               <group idMso="GroupMasterViews" getVisible="VisibleGroup"/>
               <group idMso="GroupPresentationViews" getVisible="VisibleGroup"/>
           </tab>
       </tabs>
   </ribbon>

这是从 CustomUI Editor 应用程序生成的 VBA 回调,根据我的要求进行了修改。

Option Explicit
Public TrapFlag As Boolean
Public Rib As IRibbonUI
Public xmlID As String

Public Sub SetFlag()
Dim mbResult As Integer
    mbResult = MsgBox("Do you want to disable some controls on the Ribbon?", vbYesNo)
    If mbResult = vbYes Then
        TrapFlag = True
    Else:
        TrapFlag = False
    End If
End Sub

'Callback for customUI.onLoad
Sub RibbonOnLoad(ribbon As IRibbonUI)
    'MsgBox "onLoad"
    Set Rib = ribbon
End Sub

'I use this Callback for disabling some Controls:
'   ViewSlideSorterView
'   ViewNotesPageView
'   ViewSlideShowReadingView
'   ViewSlideMasterView
'   ViewHandoutMasterView
'   ViewNotesMasterView
'   WindowNew
Sub EnableControl(control As IRibbonControl, ByRef returnedVal)
    returnedVal = Not TrapFlag 'TrapFlag = True indicates the Application is running.
    'MsgBox ("GetEnabled for " & control.Id)
    'Debug.Print control.Id & " enabled = " & CStr(returnedVal)
    Call RefreshRibbon(control.Id)
End Sub

'I use this Callback for disabling/hiding some tab groups:
'   GroupMasterViews
'   GroupPresentationViews
Sub VisibleGroup(control As IRibbonControl, ByRef returnedVal)
    returnedVal = Not TrapFlag 'TrapFlag = True indicates the Application is running.
    'MsgBox "GetVisible for " & control.Id
    'Debug.Print control.Id & " enabled = " & CStr(returnedVal)
    Call RefreshRibbon(control.Id)
End Sub

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

一些不确定性

我仍然不完全确定 Ron deBruin 的某些代码的作用 (here),或者是否有必要。我已经做了一些测试,但我不确定在这种情况下公共变量 xmlID 是否必要。他以某种我无法理解的方式使用了它。 另外,我无法在标签group 上使用与我相同的回调 在 XML 中的 command 上使用,所以我使用标签 getEnabled 命令,但我必须为组使用getVisible。这些 绑定到回调函数EnableControlVisibleGroup,分别。无论如何,VisibleGroup 似乎 禁用组,因此在功能上是相同的。 我还相信getEnabled 标签会阻止对我禁用的那些命令的热键和编程访问。

【讨论】:

以上是关于在运行时自定义 PowerPoint 功能区的主要内容,如果未能解决你的问题,请参考以下文章

运行时自定义光标适配器错误,非法参数异常

使用DRF视图集时自定义action方法

添加附件时自定义 UITableViewCell 大小不正确

自定义白板和 powerpoint 共享 Lync 的功能或在自定义应用程序中重复使用

2021版吐血整理_专升本计算机文化基础—Powerpoint2010

构建 hiphop 时自定义 libevent 包的问题