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

Oriel Tzvi Shaer 6 Reputation points
2022-12-13T08:26:15.757+00:00

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:
269964-ribbonref.png

Windows development | Windows API - Win32
Microsoft 365 and Office | Access | Development
Developer technologies | Visual Basic for Applications
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Oriel Tzvi Shaer 6 Reputation points
    2022-12-13T11:06:00.86+00:00

    Answer I got here by Ike fixed my problem:
    Try using

    CopyMemory obj, longObj, LenB(longObj)  
    
    • no need for Call
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.