1

PHB 希望我为 Microsoft Word 创建一个功能区切换按钮:

  • 按下时,将编辑限制为填写表格并在没有密码的情况下保护文档。
  • 未按下时,取消保护文档(无密码)。

我有以下 customUI.xml:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="RibbonOnLoad">
    <commands>
        <command idMso="ProtectOrUnprotectDocument" onAction="ProtectOrUnprotectDocumentOnAction"/>
    </commands>
    <ribbon>
        <tabs>
            <tab id="LawTab" label="Law">
                <group id="ProtectGroup" label="Protect">
                    <toggleButton id="ToggleProtectionButton" imageMso="GreenBall" label="Protection" getPressed="ToggleProtectionButtonGetPressed" onAction="ToggleProtectionButtonOnAction"/>
                    <button id="InvalidateRibbonButton" imageMso="Refresh" label="Invalidate Ribbon" onAction="InvalidateRibbonButtonOnAction"/>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>

和以下 VBA 代码:

Private ribbon As IRibbonUI

Sub InvalidateRibbonButtonOnAction(control As IRibbonControl)
    ribbon.Invalidate
End Sub

Sub ProtectOrUnprotectDocumentOnAction(control As IRibbonControl, ByRef cancelDefault)
    ribbon.Invalidate
    cancelDefault = False
End Sub

Sub RibbonOnLoad(ActiveRibbon As IRibbonUI)
    Set ribbon = ActiveRibbon
End Sub

Sub ToggleProtectionButtonGetPressed(control As IRibbonControl, ByRef returnValue)
    returnValue = ActiveDocument.ProtectionType <> wdNoProtection
End Sub

Sub ToggleProtectionButtonOnAction(control As IRibbonControl, ByVal pressed As Boolean)
    If pressed Then
        ActiveDocument.Protect wdAllowOnlyFormFields
    Else
        ActiveDocument.Unprotect
    End If
End Sub

我可以重新调整内置 ProtectOrUnprotect 命令的用途,以便相应的内置按钮使功能区无效并因此更新我的自定义按钮,但如果我使用内置任务窗格(查看 > 限制编辑)或以编程方式(ActiveDocument.保护/取消保护),我的自定义按钮对更改一无所知。如何收听文档级事件以保护/取消保护,以便更新切换按钮的状态?

4

2 回答 2

2

如何强制内置按钮调用您的代码

总而言之,您可以通过将以下内容添加到功能区 XML(有关详细信息,请参阅链接)来覆盖内置的工作表保护按钮以使用您的代码(希望这会导致您的按钮切换):

<commands>
    <command idMso="ProtectOrUnprotectDocument" onAction="ToggleProtectionButtonOnAction"/>
</commands>
于 2014-04-14T21:57:03.323 回答
1

我认为 Blackhawk 的答案是正确的:覆盖内置命令的onAction过程。但是,他的 XML 示例适用于 MS Excel,不适用于 MS Word。这可以很容易地调整,但不幸的是,我不知道如何解决这个特殊问题:

但是如果我使用内置的 ProtectOrUnprotectDocument 按钮来保护/取消保护,我的自定义按钮将不知道更改。如何收听文档级事件以保护/取消保护,以便更新切换按钮的状态?

没有文档级别的事件,即使使用WithEvents响应文档更改的应用程序类ProtectionType(理论上您应该可以使用功能区.InvalidateControl方法)。

所以问题(和可能的解决方案)是为什么你需要一个切换按钮,当你可以简单地使用内置按钮并使用你自己的程序劫持它的功能来根据需要保护/取消保护时。您甚至可以将内置按钮放置在自定义菜单中。

但是,这看起来很有希望:

http://sourcedaddy.com/ms-excel/getting-and-changeing-control-values.html

修改

经过一些讨论和反复试验(你自己做了很多,并弄清楚了我做不到的),让我们试试这个对我有用的东西。

这是 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="ProtectOrUnprotectDocument" onAction="ToggleProtectionButtonOnAction" />
    </commands>
    <ribbon>
        <tabs>
            <tab id="LawTab" label="Law">
                <group id="ProtectGroup" label="Protect">
                    <toggleButton id="ToggleProtectionButton" imageMso="GreenBall" label="Protection" getPressed="ToggleProtectionButtonGetPressed" onAction="ToggleProtectionButtonOnAction"/>
                    <button id="InvalidateButton" imageMso="Refresh" label="Invalidate" onAction="InvalidateButtonOnAction"/>
                </group>
            </tab>
        </tabs>
    </ribbon>
</customUI>

我所做的是将命令和的自定义切换按钮 ,发送到同一个处理程序。然后我使用一些逻辑(似乎正在工作)选择性地使功能区无效,而布尔变量在整个过程和回调中捕获文档的保护状态。ProtectOrUnprotectDocumentToggleProtectionButtononAction

这是VBA:

Option Explicit
Dim ribbon As IRibbonUI
Dim protectButton As IRibbonControl
Dim IsProtected As Boolean

Sub InvalidateRibbonButtonOnAction(control As IRibbonControl)
'MsgBox "Invalidate"
    ribbon.Invalidate
End Sub

Sub RibbonOnLoad(ActiveRibbon As IRibbonUI)
'MsgBox "onLoad"
    Set ribbon = ActiveRibbon
    IsThisDocumentProtected
End Sub

Sub ToggleProtectionButtonGetPressed(control As IRibbonControl, ByRef returnValue)
'MsgBox "GetPressed"
    IsThisDocumentProtected
    returnValue = IsProtected
End Sub

Sub ToggleProtectionButtonOnAction(control As IRibbonControl, ByVal pressed As Boolean)
    IsThisDocumentProtected
    If pressed Then
        If Not IsProtected Then
            ActiveDocument.Protect wdAllowOnlyFormFields
        Else
            ActiveDocument.Unprotect
        End If
    Else
        If IsProtected Then
            ActiveDocument.Unprotect
        End If

    End If
    If control.Id = "ProtectOrUnprotectDocument" Then
    '    MsgBox "Got here!"
    '   This will force ribbon invalidate only for the native command
        ProtectOrUnprotectDocumentOnAction control, False
    End If
End Sub


''''' This procedure is NOT a callback, but is called from the callbacks:

Private Sub IsThisDocumentProtected()
'''' Assigns value to module-level boolean variable for use throughout the module
    IsProtected = ActiveDocument.ProtectionType <> wdNoProtection
End Sub

''''' This is NOT a callback, either, but is invoked only for particular control press:
Private Sub ProtectOrUnprotectDocumentOnAction(control As IRibbonControl, ByRef cancelDefault)
    ribbon.Invalidate
    cancelDefault = False
End Sub

限制

如果我使用内置任务窗格(查看 > 限制编辑)或以编程方式(ActiveDocument.Protect/Unprotect)保护/取消保护,我的自定义按钮将不知道更改。

这不适用于以编程方式应用的保护。至于 Review > Restrict Editing,我认为您只需要以onAction与我们在上面所做的相同的方式劫持该命令的过程,通过将另一个添加command到 XML 并将其引用到相同的onAction过程。

于 2014-04-15T14:34:53.663 回答