Search code examples
vbams-accesswinapi

CopyMemory causes MS ACCESS crash - attempt to retrieve reference to IRibbonUI ribbon


There is a known issue that after losing reference to IRibbonUI ribbon object, there is no way to retrieve a reference to it. The only way is to restart the application (I am talking about MS Access)

An idea to bypass this issue in MS Excel came up by Rory A. (about 12 years ago...). can be seen here.

What I did, instead of saving the reference to the object in Excel table cell, I simply saved it in a table. When it came to the line of code where it attempts to copy the reference back to an access object it causes the application to crash. The function RetrieveObjRef is called after losing reference to ribbon. For testing, I needed to reach the case where I lose reference to ribbon. I simply hit the reset button in the VBA IDE.

Any help would be appreciated.

My code: Module #1 - the original place where we save reference to ribbon:

Public Sub OnRibbonLoad(ribbon As IRibbonUI)
        ...
        Set gobjRibbon = ribbon
        Set gobjMainRibbon = ribbon

In Module #2:

    Sub StoreObjRef(obj As Object)
    ...
    Dim strx As String
    #If VBA7 Then
        Dim longObj As LongPtr
    #Else
        Dim longObj As Long
    #End If
    
    longObj = ObjPtr(obj)
    strx = "DELETE * FROM ribbonRef"
    Call runsqlstr(strx)
    
    strx = "INSERT INTO ribbonRef (objRef) SELECT " & longObj
    Call runsqlstr(strx)
    ...
    End Sub
                           
    Sub RetrieveObjRef()
    ...
    Dim obj As Object
    #If VBA7 Then
        Dim longObj As LongPtr
    #Else
        Dim longObj As Long
    #End If
    longObj = Nz(dlookupado("objRef", "ribbonRef", , True), 0)
    
    If longObj <> 0 Then
        Call CopyMemory(obj, longObj, 4) ' This line causes application crash!!!'
        Set gobjRibbon = obj
        Set gobjMainRibbon = obj
    End If
    ...
    End Sub

In Module #3

    #If VBA7 Then
        Public Declare PtrSafe Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (Destination As Any, source As Any, ByVal length As LongPtr)
    #Else
        Public Declare Sub CopyMemory Lib "Kernel32" Alias "RtlMoveMemory" (Destination As Any, source As Any, ByVal length As Long)
    #End If

And finally, in Module #4:

        If gobjMainRibbon Is Nothing Then
            Call RetrieveObjRef
        End If
    
        Call StoreObjRef(gobjMainRibbon)

ribbonRef.objRef

I tried saving the reference value in access table ("ribbonRef"), I was expecting that if this worked for many others, why should it not work for me


Solution

  • Try using CopyMemory obj, longObj, LenB(longObj) - no need for Call