sancarn / stdVBA

VBA Standard Library - A Collection of libraries to form a common standard layer for modern VBA applications.
MIT License
293 stars 58 forks source link

Application.Run() Alternative #64

Closed ls-2037 closed 1 year ago

ls-2037 commented 1 year ago

I noticed in the stdCallback code there are comments indicating that an alternative to Application.Run() might exist. Is this possible? Not all VBA host applications provide an Application.Run() method, and it can be very limiting to what you can do and which libraries/code you can use.

sancarn commented 1 year ago

On windows you can use DispCallFunc to call a function by pointer. I could envision a stdCallback method like:

#if VBA7 then
  Public Function CreateFromPointer(ByVal ptr as longptr, Optional ByVal ct as VbCallType = vbMethod) as stdCallback
#else
  Public Function CreateFromPointer(ByVal ptr as long, Optional ByVal ct as VbCallType = vbMethod) as stdCallback
#end if
    set CreateFromPointer = new stdCallback
    Call CreateFromPointer.init(ParentType.Pointer, ptr, ct)
End Function

'... later ...

DispCallFunc ptr, 0, ...

Usage:

Dim cb as stdCallback: set cb = stdCallback.CreateFromPointer(AddressOf MyModule.MyProcedure)

'... later...

cb()

Would happily accept a PR for this. I have examples of using DispCallFunc already in stdCOM.


Edit: Upon further investigation this will be a lot more involved in terms of usage as well as in terms of building it. I will work on the addition and report back

sancarn commented 1 year ago

Added, there are some nuances to using pointers though.

https://github.com/sancarn/stdVBA/blob/master/tests/stdCallbackTests.bas#L50-L86 gives a good idea of what you need to be careful of. You can either supply the argument types or they can be predicted but they can't be wrong. Same with the return type. Similarly if variables are declared byref (or not declared at all) then you need to pass pointers in instead of the variable itself...

Ultimately, calling by pointer becomes very tricky. Hope it makes sense, let me know if it works for you in your other vba environments.