dcsimg
Results 1 to 21 of 21

Thread: Has anyone had any success implementing IDispatch / IDispatchEx?

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2019
    Posts
    16

    Has anyone had any success implementing IDispatch / IDispatchEx?

    Recently I've found myself wanting to implement the IDispatchEx interface which would allow me to create objects 'on the fly'. The core benefit of which is for syntax sugar:

    Code:
    Dim person as object
    set person = new CDynamic
    person.age = 22
    person.hair.color = "brown"
    person.hair.style = "shaggy"
    Or even, a less ambitious dynamic IDispatch implementation:

    Code:
    Dim person as object
    set person = new CDynamic
    person.addProperties("age","hair")
    set person.hair = new CDynamic
    person.hair.addProperties("color","style")
    
    '...
    
    person.age = 22
    person.hair.color = "brown"
    person.hair.style = "shaggy"
    This would be really handy as a developer's tool, especially in making dev friendly frameworks without bloating the codebase too much. Recently I've been trying to implement these interfaces using IFauxInterface but before I pursue this any further I figured I'd ask here to see if anyone else has tried / got anywhere with this?

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,234

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Search this forum for the keyword: CreateStdDispatch.

    In my recent codebank submission, I apply the API quite a bit to create COM objects on the fly. But "the trick" posted some examples which may fall into what you are attempting (search for that keyword to find his posts).

    CreateStdDispatch can be quite complex, has limitations, and documentation/examples in the wild are sparse.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3
    Frenzied Member
    Join Date
    Sep 2012
    Posts
    1,597

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?


  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,234

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    @dreammanor. I think the OP wants to include ability to get/set properties and methods.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5
    Frenzied Member
    Join Date
    Sep 2012
    Posts
    1,597

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Yes, he wants VB6 to gain the ability of JavaScript-like dynamic properties (even dynamic objects). If this can be achieved, the capabilities of VB6 will increase dramatically.

    Edit:
    I've been researching scripting languages (mainly JavaScript) recently. The ability of JavaScript to dynamically create objects is really useful.
    Last edited by dreammanor; Jun 20th, 2019 at 08:27 PM.

  6. #6

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Apr 2019
    Posts
    16

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by LaVolpe View Post
    Search this forum for the keyword: CreateStdDispatch.

    In my recent codebank submission, I apply the API quite a bit to create COM objects on the fly. But "the trick" posted some examples which may fall into what you are attempting (search for that keyword to find his posts).

    CreateStdDispatch can be quite complex, has limitations, and documentation/examples in the wild are sparse.
    Ah you are totally right! I recall coming across CreateStdDispatch a few weeks ago, remember thinking "Man this looks like it'll do what I need it to". I think I chickened out after seeing the total lack of documentation and examples though lol...

    Thanks! This will be a super great basis to work off of! Should make it pretty easy Thanks!

  8. #8
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,329

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by LaVolpe View Post
    @dreammanor. I think the OP wants to include ability to get/set properties and methods.
    I thought, that was exactly what example-folder 7 (Dynamic usage of vbIDispatch) of the "vbFriendlyInterfaces"-Demo contains.

    Here the complete Code of that "Dyn-Props-Demo" as it exists in fTest.frm:
    Code:
    Private Sub Form_Click()
      AutoRedraw = True: Cls
    
      Dim PS As New cPropStorage
    
      With PS.Props 'PS.Props will accept any Property-Name you throw at it, to "store things" (As Variant)
        .foo = "foo"
        .bar = "bar"
        .foobar = .foo & .bar '<- read-out-test for the dynamic props .foo and .bar
        .SomeLong = 123 'fill-in some long...
        .SomeLong = 456 '<- and now test for over-writing an existing Value under the same PropertyName
        Set .TheForm = Me 'test for storing an Object-Reference (in this case in .TheForm)
    
        'Ok, now the Test-PrintOuts for the above
        Print "foo: "; .foo
        Print "bar: "; .bar
        Print "foobar: "; .foobar
        Print "SomeLong: "; .SomeLong
        Print "TheForm.Caption: "; .TheForm.Caption
      End With
    End Sub
    And here the complete Code of cPropStorage.cls, which provides that dynamic IDispatch-Implementation:
    Code:
    Option Explicit
     
    Implements vbIUnknown
    Implements vbIDispatch
     
    Private mDict As New Scripting.Dictionary, VStorage() As Variant
     
    Public Function Props() As Object 'our IDispatch-supporting DispObject, which allows LateBound Method-Calling "per Dot"
      vbI.NewInstance vbI.pVT(vtbl_IDispatch), Me, VarPtr(Props)
    End Function
     
    '************* IUnknown-Implementation *****************
    Private Sub vbIUnknown_QueryInterface(UserData As Long, ByVal pVTable As Long, RefCount As Long, sReqIID As String, Unk As stdole.IUnknown)
      If vbI.IIDsEqual(sReqIID, vbI.sIID_IDispatch) Then RefCount = RefCount + 1
    End Sub
    Private Sub vbIUnknown_Terminate(UserData As Long, ByVal pVTable As Long)
    End Sub
    
    '************* IDispatch-Implementation ****************
    Private Function vbIDispatch_GetIDForMemberName(UserData As Long, ByVal pVTable As Long, MemberName As String) As Long
      If mDict.Exists(MemberName) Then
        vbIDispatch_GetIDForMemberName = mDict(MemberName)
      Else
        mDict.Add MemberName, mDict.Count + 1
        vbIDispatch_GetIDForMemberName = mDict.Count
        ReDim Preserve VStorage(1 To mDict.Count)
      End If
    End Function
    Private Function vbIDispatch_Invoke(UserData As Long, ByVal pVTable As Long, ByVal DispID As Long, ByVal CallType As VbCallType, VResult As Variant, ParamArray P() As Variant) As vbInterfaces.HRESULT
      If DispID < 1 Or DispID > mDict.Count Then vbIDispatch_Invoke = DISP_E_MEMBERNOTFOUND: Exit Function
      
      If CallType And (VbGet Or VbMethod) Then 'handle the read-out-requests
        If IsObject(VStorage(DispID)) Then Set VResult = VStorage(DispID) Else VResult = VStorage(DispID)
      ElseIf CallType = VbLet Then
        VStorage(DispID) = P(0)
      ElseIf CallType = VbSet Then
        Set VStorage(DispID) = P(0)
      End If
    End Function
    So that's the easy way, as the vbFriendlyInterfaces.dll provides it (in a generically usable fashion).

    Olaf

  9. #9
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,329

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Well, and for those who want to add such stuff in a "super-easy" way, there's always IActiveScripting-interfaces,
    which would then allow even simple Function-adding in a dynamic fashion.

    Into an empty VB-Project with a Form1 - add a new Class with its default-name Class1 - and paste the following:
    Code:
    Option Explicit
    
    Private SC As Object
    
    Private Sub Class_Initialize()
      Set SC = CreateObject("MSScriptControl.ScriptControl")
          SC.Language = "VBScript"
          SC.AddCode "Public foo: foo = ""foo"""
          SC.AddCode "Public bar: bar = ""bar"""
    End Sub
    
    Public Function Dyn() As Object
      Set Dyn = SC.CodeObject
    End Function
    
    Public Sub AddProp(PropName$, Optional InitVal)
      SC.AddCode "Public " & PropName: If IsMissing(InitVal) Then Exit Sub
      If IsObject(InitVal) Then CallByName Dyn, PropName, VbSet, InitVal Else _
                                CallByName Dyn, PropName, VbLet, InitVal
    End Sub
    Public Sub AddFunc(FuncName$, Code$, Optional ParamList$)
      SC.AddCode "Function " & FuncName & "(" & ParamList & ")" _
                  & vbCrLf & Code & vbCrLf & "End Function"
    End Sub
    Ok, and here's appropriate Test-Code for the Form:
    Code:
    Option Explicit
     
    Private Sub Form_Load()
      Dim C1 As New Class1
      
      With C1.Dyn
        Debug.Print .foo, .bar 'those were ensured already at class_initialize
        
        C1.AddFunc "foobar", "foobar=foo+bar" 'add a new method
        Debug.Print foo, .bar, .foobar
        
        .foo = 1: .bar = 2 'Prop-Value-changes
        Debug.Print .foo, .bar, .foobar
        
        C1.AddProp "baz", "baz" 'add two more new properties
        C1.AddProp "Form", Me
        Debug.Print .baz, .Form.Caption
      End With
    End Sub
    Et voilą - there it is - a dynamically expandable Dispatch-Prop...

    Olaf

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Apr 2019
    Posts
    16

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by Schmidt View Post
    ...
    So that's the easy way, as the vbFriendlyInterfaces.dll provides it (in a generically usable fashion).
    Olaf
    Hi Olaf,

    Gotta say your vbFriendlyInterfaces dll does indeed look very nice! That said I'm not sure if you can easily attach methods to your IDispatch implementation without implementing TypeInfo also. (Although this is untested from me as of right now)

    Regardless, in my particular use case, I want to (as and where possible) steer away from using any external DLLs, (easier distribution). I'm also trying to steer away from ScriptControl specifically who's VBScript evaluation is actually disabled on most computers I have used, and whos JScript is unlikely to be supported forever either.

    This is why I was initially looking into IFauxInterface as this quite literally builds the implementation within VB. That said the DLL version is very neat. Perhaps if the worst comes to the worst I can download the dll at runtime to Appdata.

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,329

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by sancarn View Post
    Gotta say your vbFriendlyInterfaces dll does indeed look very nice!
    That said I'm not sure if you can easily attach methods to your IDispatch implementation without implementing TypeInfo also.
    (Although this is untested from me as of right now)
    Since Properties are already "Methods" the Implementation of a "true Function" is of course equally possible:
    Why not make a fast test with the Demo 7-Code:

    At the top of vbIDispatch_GetIDForMemberName add a new, single line:
    Code:
    Private Function vbIDispatch_GetIDForMemberName(UserData As Long, ByVal pVTable As Long, MemberName As String) As Long
      If UCase$(MemberName) = "MYFUNC" Then vbIDispatch_GetIDForMemberName = 10000: Exit Function
      ...
    At the top of vbIDispatch_Invoke add a new, single line:
    Code:
    Private Function vbIDispatch_Invoke(UserData As Long, ByVal pVTable As Long, ByVal DispID As Long, ByVal CallType As VbCallType, VResult As Variant, ParamArray P() As Variant) As vbInterfaces.HRESULT
      If DispID = 10000 Then VResult = Join(P, "_"): Exit Function 'MyFunc Joins all passed Params with an UnderScore-Char
      ...
    And that's it... "MyFunc" was successfully implemented (without any extra TypeInfos).
    You can test it in the Form within the With-Block by doing:
    Debug.Print .MyFunc("abc", 1, 2, 3, "xyz") '<-- returns and Prints out: abc_1_2_3_xyz


    Quote Originally Posted by sancarn View Post
    Regardless, in my particular use case, I want to (as and where possible) steer away from using any external DLLs, (easier distribution). I'm also trying to steer away from ScriptControl specifically who's VBScript evaluation is actually disabled on most computers I have used, and whos JScript is unlikely to be supported forever either.
    Did you really deactivate VBScript on your Computer(s)?
    If yes, how did you do that - and why did you leave JScript alone in that case?

    Im asking, because a "deactivated VBScript" usually leaves the vbscript.dll untouched in the System32 or SysWOW64 folders
    (if you remove them, there's a good chance MS will re-install them on the next system-update or system-check).

    And I've mentioned IActiveScript in my first post, because when you implement these Scripting-interfaces by hand,
    you will not need the MS-ScriptControl - but only an installed vbsript.dll or jscript.dll in the SysFolder.

    I still consider that solution the most promising one for your case, because when you think about it:
    - dynamic properties are easy also with other methods (e.g. via vbFriendlyInterfaces.dll)
    - but for "true dynamic functions" which do a bit more than "single-line math-ops or concats" to produce a result,
    .. you'll need either a dynamic compiler, or an interpreter ... period.
    - the Scripting-stuff is also interesting because it comes in both: 32Bit- and a 64Bit implementations (preinstalled on the system)
    - also - you're not restricted to VBScript - the jscript.dll can provide basically the same stuff I've demonstrated with VbScript in my example

    Olaf

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Apr 2019
    Posts
    16

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by Schmidt View Post
    And that's it... "MyFunc" was successfully implemented (without any extra TypeInfos).
    Lol well that's cheating! But indeed you can do that.

    Quote Originally Posted by Schmidt View Post
    Did you really deactivate VBScript on your Computer(s)?
    I did not do anything of the sort. On all systems I have used the following code:

    Code:
    Dim sc as object: set sc = CreateObject("MSScriptControl.ScriptControl")
    sc.Language = "VBScript"
    I have got the error.

    Code:
    Run-time error '380': A script engine for the specified language can not be created
    JScript seems to work, not sure why, but yeah... To be fair, both times I tried this on Win10 computers, so that might also have something to do with it... If one doesn't have to rely on MSScriptControl.ScriptControl then perhaps that is indeed an option also.


    Quote Originally Posted by Schmidt View Post
    - but for "true dynamic functions" which do a bit more than "single-line math-ops or concats" to produce a result,
    .. you'll need either a dynamic compiler, or an interpreter ... period.
    Yep I was actually planning on implementing a VB6-like language --> Bytecode compiler + interpreter. Preferably something that would allow syntax customisation. Mainly for Lambda expressions...

    Anyway.

    I'll definitely be giving all the suggestions a go and ultimately it'll be which ever is more optimal (performance wise). This is a pretty fundamental piece of the architecture of the API so I want it to be as fast as possible. So thanks all for suggestions!

  13. #13
    New Member
    Join Date
    Mar 2019
    Posts
    4

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Sancarn, I've not tested every tutorial module, but the fast majority of Olaf's vbFriendly interface's examples work perfectly from the VBA IDE (with just a couple of minor tweaks to cover the differences in the langauges). I also dont think you need the ITypelib reference explicitly in your code, since (Olaf correct me if i'm wrong) you are really directly inserting the desired IID at runtime to ensure the correct type association by the machine?

  14. #14
    Addicted Member
    Join Date
    Nov 2013
    Posts
    177

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by Schmidt View Post
    Well, and for those who want to add such stuff in a "super-easy" way, there's always IActiveScripting-interfaces,
    which would then allow even simple Function-adding in a dynamic fashion.

    Into an empty VB-Project with a Form1 - add a new Class with its default-name Class1 - and paste the following:
    Code:
    Option Explicit
    
    Private SC As Object
    
    Private Sub Class_Initialize()
      Set SC = CreateObject("MSScriptControl.ScriptControl")
          SC.Language = "VBScript"
          SC.AddCode "Public foo: foo = ""foo"""
          SC.AddCode "Public bar: bar = ""bar"""
    End Sub
    
    Public Function Dyn() As Object
      Set Dyn = SC.CodeObject
    End Function
    
    Public Sub AddProp(PropName$, Optional InitVal)
      SC.AddCode "Public " & PropName: If IsMissing(InitVal) Then Exit Sub
      If IsObject(InitVal) Then CallByName Dyn, PropName, VbSet, InitVal Else _
                                CallByName Dyn, PropName, VbLet, InitVal
    End Sub
    Public Sub AddFunc(FuncName$, Code$, Optional ParamList$)
      SC.AddCode "Function " & FuncName & "(" & ParamList & ")" _
                  & vbCrLf & Code & vbCrLf & "End Function"
    End Sub
    Ok, and here's appropriate Test-Code for the Form:
    Code:
    Option Explicit
     
    Private Sub Form_Load()
      Dim C1 As New Class1
      
      With C1.Dyn
        Debug.Print .foo, .bar 'those were ensured already at class_initialize
        
        C1.AddFunc "foobar", "foobar=foo+bar" 'add a new method
        Debug.Print foo, .bar, .foobar
        
        .foo = 1: .bar = 2 'Prop-Value-changes
        Debug.Print .foo, .bar, .foobar
        
        C1.AddProp "baz", "baz" 'add two more new properties
        C1.AddProp "Form", Me
        Debug.Print .baz, .Form.Caption
      End With
    End Sub
    Et voilą - there it is - a dynamically expandable Dispatch-Prop...

    Olaf
    Hi Olaf,

    I am trying to use your code in x64bit windows but the ScriptControl no longer works in x64bit.

    Do you have any suggestions ?

    Regards.

  15. #15
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,323

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by JAAFAR View Post
    I am trying to use your code in x64bit windows but the ScriptControl no longer works in x64bit.
    I don't know where you got that idea. It works fine on the 64bit PC I just tried it on.

  16. #16
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,329

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by dilettante View Post
    I don't know where you got that idea. It works fine on the 64bit PC I just tried it on.
    Sure...

    @JAAFAR
    Judging from your last postings, you're probably trying to use it from within a 64Bit-Process (as e.g. "64Bit-Excel-VBA").

    First option:
    ...use the 32Bit-Script-COMponent with COM-Marshaling (either via ActiveX-Exe-Instancing or the DllSurrogate-mechanism).

    Second option:
    ...google for VB6-implementations of the IActiveScripting-interfaces (there are a few out there) -
    and adapt these sources for VBA-64.

    Olaf

  17. #17
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,323

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    VBA questions belong in the Office Development forum.

  18. #18
    Addicted Member
    Join Date
    Nov 2013
    Posts
    177

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by dilettante View Post
    I don't know where you got that idea. It works fine on the 64bit PC I just tried it on.
    Sorry, I meant to say 64bit process not 64 OS.

  19. #19
    Addicted Member
    Join Date
    Nov 2013
    Posts
    177

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by dilettante View Post
    VBA questions belong in the Office Development forum.
    I know I am not supposed to ask questions related to vba in this forum but the truth is I hardly ever get any answers when I post in the Office Developent section.... Despite me not using vb6, most of my questions in this forum are API related.

    Regards.

  20. #20
    Addicted Member
    Join Date
    Nov 2013
    Posts
    177

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Quote Originally Posted by Schmidt View Post
    Sure...

    @JAAFAR
    Judging from your last postings, you're probably trying to use it from within a 64Bit-Process (as e.g. "64Bit-Excel-VBA").

    First option:
    ...use the 32Bit-Script-COMponent with COM-Marshaling (either via ActiveX-Exe-Instancing or the DllSurrogate-mechanism).

    Second option:
    ...google for VB6-implementations of the IActiveScripting-interfaces (there are a few out there) -
    and adapt these sources for VBA-64.

    Olaf
    Thank you very much.

    The second option sounds interesting... I'll look into it and see if I can make it work for me.

    Regards.

  21. #21
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    33,932

    Re: Has anyone had any success implementing IDispatch / IDispatchEx?

    Some forums are less active than others...well, most, really. However, that's what happens if everybody decides to post questions in the wrong forum.
    My usual boring signature: Nothing

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width