VBA IRibbonUI.Invalidate 导致 Excel 使用次数过多时崩溃

VBA IRibbonUI.Invalidate causes Excel to crash when used too many times

目前我正在处理使用多个插件的 Excel 文档。这些插件包含我计划在其他工作簿中使用的功能。一组功能负责定制功能区的某些功能:

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (destination As Any, source As Any, ByVal length As Long)
Private Const ribbonXMLAddress As String = "RibbonSaveLocation"
Private thisRibbon             As IRibbonUI

Public Sub SetRibbonPointer(ByVal ribbon As IRibbonUI)
    ribbonPointer = ObjPtr(ribbon)
End Sub

Public Sub UpdateRibbon()
    currentRibbon.Invalidate
End Sub

Private Property Get currentRibbon() As IRibbonUI
    If thisRibbon Is Nothing Then
        Set thisRibbon = ribbonObject
    End If
    
    Set currentRibbon = thisRibbon
End Property

Private Property Get ribbonPointer() As Long
    ribbonPointer = XMLTool.GetXMLContent(ribbonXMLAddress)
End Property

Private Property Let ribbonPointer(ByVal newPointer As Long)
    XMLTool.ChangeXMLContent ribbonXMLAddress, CStr(newPointer)
End Property

Private Property Get ribbonObject() As Object
    CopyMemory ribbonObject, ribbonPointer, 4
End Property

在我多次使用 UpdateRibbon 函数(例如 6 - 9 次)之前,代码工作正常。之后 Excel 关闭并重新打开 Excel 报告发现问题并想要恢复文件。

我立即 window 测试了代码几次以确保结果一致:验证功能区 9 次后 Excel 崩溃。 我已经在互联网上进行了搜索,但找不到解决此问题的方法。 需要明确的是:功能区功能位于加载项中,而不是与功能区本身位于同一工作簿中。

谁能告诉我导致崩溃的原因或如何防止崩溃? (顺便说一句,不使功能区失效不是解决方案 :))提前致谢。

您是否尝试过更改指针的长度?即,而不是

CopyMemory ribbonObject, ribbonPointer, 4

尝试使用指针长度:

  CopyMemory ribbonObject, ribbonPointer, IntPtr.Size

您需要避免使用功能区代码中的 CopyMemory 调用 API:

Private Property Get ribbonObject() As Object
    CopyMemory ribbonObject, ribbonPointer, 4
End Property

这不是为了以这种方式工作。而且,它是不支持的场景。


Fluent UI 在以下文章中有深入的描述:

我可能来晚了一点。 我 运行 也遇到了这个问题!

而不是这个...

Public Sub UpdateRibbon()
    currentRibbon.Invalidate
End Sub

试试这个...

Public Sub UpdateRibbon()
    thisRibbon.Invalidate
End Sub

这似乎适合我。