Skip to content

Commit 38b376e

Browse files
committed
Add macCallByName
1 parent e6ee952 commit 38b376e

2 files changed

Lines changed: 71 additions & 16 deletions

File tree

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,5 @@ Before `08/07/2021` a change log was not kept. We have retrospectively gone back
360360
- 2025-08-08 `stdRibbon` FEATURE - Added `stdRibbon` which allows for the ribbon to be hidden or shown.
361361
- 2025-08-18 `stdRibbon` FEATURE - `stdRibbon` now supports Word. Additionally state detection is more robust.
362362
- 2025-09-25 `stdRibbon` FIX - Fix infinite recursion issue, now we error when state hasn't changed.
363-
- 2025-09-30 `stdRibbon` FIX - Mac compatibility layer for stdRibbon. Also fixed a bug related to the above change.
363+
- 2025-09-30 `stdRibbon` FIX - Mac compatibility layer for stdRibbon. Also fixed a bug related to the above change.3
364+
- 2025-10-01 `stdCallback` FIX - Added `macCallByName` for Mac compatibility.

src/stdCallback.cls

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,19 @@ Implements stdICallable
103103
'Const DISPID_COLLECT = -8
104104

105105
'Direct call convention of VBA.CallByName
106-
#If VBA7 Then
107-
'VBE7 is interchangable with msvbvm60.dll however VBE7.dll appears to always be present where as msvbvm60 is only occasionally present.
108-
Private Declare PtrSafe Function DispCallFunc Lib "oleAut32.dll" (ByVal pvInstance As LongPtr, ByVal offsetinVft As LongPtr, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As LongPtr, ByVal paValues As LongPtr, ByRef retVAR As Variant) As Long
109-
Private Declare PtrSafe Function rtcCallByName Lib "VBE7.dll" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As LongPtr, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal lcid As Long) As Long
106+
#If Mac Then
110107
#Else
111-
Private Enum LongPtr
112-
[_]
113-
End Enum
114-
Private Declare Function DispCallFunc Lib "oleAut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As LongPtr, ByVal paValues As LongPtr, ByRef retVAR as variant) As Long
115-
Private Declare Function rtcCallByName Lib "msvbvm60" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As LongPtr, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal lcid As Long) As Long
108+
#If VBA7 Then
109+
'VBE7 is interchangable with msvbvm60.dll however VBE7.dll appears to always be present where as msvbvm60 is only occasionally present.
110+
Private Declare PtrSafe Function DispCallFunc Lib "oleAut32.dll" (ByVal pvInstance As LongPtr, ByVal offsetinVft As LongPtr, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As LongPtr, ByVal paValues As LongPtr, ByRef retVAR As Variant) As Long
111+
Private Declare PtrSafe Function rtcCallByName Lib "VBE7.dll" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As LongPtr, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal lcid As Long) As Long
112+
#Else
113+
Private Enum LongPtr
114+
[_]
115+
End Enum
116+
Private Declare Function DispCallFunc Lib "oleAut32.dll" (ByVal pvInstance As Long, ByVal offsetinVft As Long, ByVal CallConv As Long, ByVal retTYP As Integer, ByVal paCNT As Long, ByVal paTypes As LongPtr, ByVal paValues As LongPtr, ByRef retVAR as variant) As Long
117+
Private Declare Function rtcCallByName Lib "msvbvm60" (ByRef vRet As Variant, ByVal cObj As Object, ByVal sMethod As LongPtr, ByVal eCallType As VbCallType, ByRef pArgs() As Variant, ByVal lcid As Long) As Long
118+
#End If
116119
#End If
117120

118121
#If Mac Then
@@ -427,9 +430,14 @@ Public Function RunEx(ByVal vArr As Variant) As Variant
427430
vArgs = vArr
428431

429432
'Call rtcCallByName
433+
Dim hResult As Long
430434
On Error GoTo ErrorInRTCCallByName
431-
Dim hr As Long: hr = rtcCallByName(vRet, This.Callback.oObject, StrPtr(This.Callback.sMethodName), This.Callback.iCallType, vArgs, &H409)
432-
On Error GoTo 0
435+
#If Mac Then
436+
Call macCallByName(vRet, This.Callback.oObject, This.Callback.sMethodName, This.Callback.iCallType, vArgs)
437+
#Else
438+
hResult = rtcCallByName(vRet, This.Callback.oObject, StrPtr(This.Callback.sMethodName), This.Callback.iCallType, vArgs, &H409)
439+
#End If
440+
On Error GoTo stdErrorWrapper_ErrorOccurred
433441
Else
434442
CriticalRaise "Error in rtcCallByName. Arguments supplied to RunEx needs to be an array."
435443
End If
@@ -481,12 +489,16 @@ Public Function RunEx(ByVal vArr As Variant) As Variant
481489

482490
'Call function
483491
Const CC_STDCALL = 5
484-
Dim hResult As Long
485-
hResult = DispCallFunc(0, .iMethodAddress, CC_STDCALL, .iReturnType, iParamCount, VarPtr(vType(0)), VarPtr(vPtr(0)), vRet)
492+
Dim hResult2 As Long
493+
#If Mac Then
494+
Call Err.Raise(1, "stdCallback", "Calling functions by pointer is not supported on Mac")
495+
#Else
496+
hResult2 = DispCallFunc(0, .iMethodAddress, CC_STDCALL, .iReturnType, iParamCount, VarPtr(vType(0)), VarPtr(vPtr(0)), vRet)
497+
#End If
486498
End With
487499

488-
If hResult < 0 Then
489-
Err.Raise hResult, "DispCallFunc", "Error when calling function pointer?"
500+
If hResult2 < 0 Then
501+
Err.Raise hResult2, "DispCallFunc", "Error when calling function pointer?"
490502
End If
491503

492504
Case Else
@@ -506,6 +518,48 @@ ErrorInRTCCallByName:
506518
CriticalRaise Err.Description & " (" & Err.Number & ")"
507519
End Function
508520

521+
#If Mac Then
522+
'Call a method on an object using the mac version of CallByName
523+
'@param o - The object to call the method on
524+
'@param p - The name of the method to call
525+
'@param v - The call type to use
526+
Private Sub macCallByName(ByRef vRet As Variant, ByVal o As Object, ByVal p As String, ByVal v As VbCallType, ByRef args() As Variant)
527+
Select Case UBound(args) - LBound(args) + 1
528+
Case 0: Call CopyVariant(vRet, CallByName(o, p, v))
529+
Case 1: Call CopyVariant(vRet, CallByName(o, p, v, args(0)))
530+
Case 2: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1)))
531+
Case 3: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2)))
532+
Case 4: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3)))
533+
Case 5: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4)))
534+
Case 6: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5)))
535+
Case 7: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6)))
536+
Case 8: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7)))
537+
Case 9: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8)))
538+
Case 10: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9)))
539+
Case 11: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10)))
540+
Case 12: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11)))
541+
Case 13: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12)))
542+
Case 14: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13)))
543+
Case 15: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14)))
544+
Case 16: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15)))
545+
Case 17: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16)))
546+
Case 18: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17)))
547+
Case 19: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18)))
548+
Case 20: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19)))
549+
Case 21: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20)))
550+
Case 22: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21)))
551+
Case 23: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22)))
552+
Case 24: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23)))
553+
Case 25: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24)))
554+
Case 26: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25)))
555+
Case 27: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26)))
556+
Case 28: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27)))
557+
Case 29: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28)))
558+
Case Else: Call CopyVariant(vRet, CallByName(o, p, v, args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29)))
559+
End Select
560+
End Sub
561+
#End If
562+
509563
Private Function Serialize(data As Variant) As String
510564
Select Case TypeName(data)
511565
Case "Integer", "Double", "Float", "Date"

0 commit comments

Comments
 (0)