Results 1 to 10 of 10

Thread: [RESOLVED] VB6 ActiveX.dll, and using it without registering it (manifest?)

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Resolved [RESOLVED] VB6 ActiveX.dll, and using it without registering it (manifest?)

    Hi all,

    Okay, I've got a situation where I'd like to create a VB6 ActiveX.dll for use by another VB6 standard (EXE) project.

    However, when everything is compiled (or possibly even in the IDE for the standard project), I'd like to be able to use this ActiveX.dll without having it registered.

    Anyone the expert on how to do this?

    Do I need to somehow get a XML manifest information for it, and place it in the manifest of the standard EXE project?

    I'm at a bit of a loss here. Any pointers would be greatly appreciated.

    Regards,
    Elroy

    p.s. Late-binding of the ActiveX.dll would be fine.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  2. #2

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    Hmmm, well, I found this by Dilettante, and it seems like maybe I'm good to go.

    Dilettante, I must say that you're sure a cantankerous fellow at times, but you have written some excellent code. And you've clearly spent the time to get the deepest bowels of each Windows release sorted.

    Well, I owe you a thanks for posting the above code. I worked through your demo, and it worked just fine. Now, I just need to think through it, and "bend" it to my particular wishes.

    Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  3. #3
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,295

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    [...]
    Last edited by dz32; Apr 26th, 2019 at 11:59 AM.

  4. #4

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    Hi dz32,

    Yes, I have a strong need to not need to register anything. I've discussed these needs elsewhere on these forums and won't go into them here. It even makes me nervous to think about registering something "on-the-fly". I've got routines that can register things without even any need for regsvr32, but I'd rather not use them.

    I do appreciate the information on how you're doing it though. I've been playing around with Dilettante's work, and I think it's going to provide an answer for me. I particularly like that it works without anything being registered.

    I don't think I'll mark this as resolved just yet, as I'm still getting all the concepts of what Dilettante did sorted out, and I may have other questions regarding all of this.

    Also, ideas about other non-registry-methods are more than welcome. The basic idea is, I want to create a VB6 DLL that's called from a VB6 EXE, with nothing being registered.

    Regards,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    You can use this module for working with COM-Dll's without registration.
    You can use SxS manifest as well. This is the example:
    Code:
        <file name="MTDownloader.dll">
            <comClass 
                 clsid="{20FAEF52-0D1D-444B-BBAE-21240219905B}" 
                 threadingModel="Apartment"                   
                 tlbid="{AABFB2BB-49A2-4C39-8622-0DBE16C4161B}"   
                 progid="MTDownloader.MultithreadDownloader"                   
            />
            <typelib 
                 tlbid="{AABFB2BB-49A2-4C39-8622-0DBE16C4161B}" 
                 version="1.0"
    	     helpdir=""         
            />
    
        </file>
    
        <comInterfaceExternalProxyStub
            name = "_MultithreadDownloader"
            iid="{DF3BDB52-3380-4B78-B691-4138300DD304}"
            proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
            baseInterface="{00000000-0000-0000-C000-000000000046}"
            tlbid="{AABFB2BB-49A2-4C39-8622-0DBE16C4161B}"
        />
        <comInterfaceExternalProxyStub
            name = "__MultithreadDownloader"
            iid="{2C3EA7B8-17A3-42A0-93E1-C8074BCB907C}"
            proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
            baseInterface="{00000000-0000-0000-C000-000000000046}"
            tlbid="{AABFB2BB-49A2-4C39-8622-0DBE16C4161B}"
        />
    You can skip comInterfaceExternalProxyStub if you don't want to use marshalling.

  6. #6

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    Hi Trick,

    Your code looks SUPER cool.

    I haven't done much testing. However, if you don't mind, a couple of questions.

    1. First, this stuff runs the ActiveX.dll as in-process, correct? I'm hoping that's the case, as I want to pass my ActiveX.dll an open database and some open recordsets, and have it use them just as the main program would.
    2. Next, my actual ActiveX.dll files will also have .ocx dependencies. I'm assuming I can just embed a .manifest file in each of them to take care of that. Would you agree with that?
    3. I will have the source code to my main project as well as all the ActiveX.dll files I create. Therefore, even though it's late-binding, I will know each class's methods and properties (and I'll use them correctly). Therefore, I'm assuming I can just delete the GetAllCoclasses , CreateIDispatch, ITypeLib_GetTypeInfoCount, ITypeLib_GetTypeInfo, and ITypeInfo_GetDocumentation procedures. In other words, I believe I'll only be calling CreateObjectEx2 (and what it needs) and UnloadLibrary. So, I can delete what those don't need. Is that correct?
    4. Lastly, so ... I need to call UnloadLibrary when I'm done with the ActiveX.dll and I want to get it out of memory? Correct?


    Again, Trick, if this all works like I'm hoping it will, this is totally cool stuff.

    Thanks millions for sharing this. If all goes as expected, this is going to be huge for my project.

    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,229

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    I use UMMM to generate SxS manifests.
    There's also a simple Manifest generator in the Codebank.

    I would use Trick's methods if implementing a ActiveX DLL plugin system, that needed to support XP, otherwise I would use ActCtx.

  8. #8
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    Hi, Elroy.
    Quote Originally Posted by Elroy View Post
    Your code looks SUPER cool.
    Thanks.
    Quote Originally Posted by Elroy View Post
    First, this stuff runs the ActiveX.dll as in-process, correct? I'm hoping that's the case, as I want to pass my ActiveX.dll an open database and some open recordsets, and have it use them just as the main program would.
    Yes. It loads a Dll.
    Quote Originally Posted by Elroy View Post
    Next, my actual ActiveX.dll files will also have .ocx dependencies. I'm assuming I can just embed a .manifest file in each of them to take care of that. Would you agree with that?
    Yes.
    Quote Originally Posted by Elroy View Post
    I will have the source code to my main project as well as all the ActiveX.dll files I create. Therefore, even though it's late-binding, I will know each class's methods and properties (and I'll use them correctly). Therefore, I'm assuming I can just delete the GetAllCoclasses , CreateIDispatch, ITypeLib_GetTypeInfoCount, ITypeLib_GetTypeInfo, and ITypeInfo_GetDocumentation procedures. In other words, I believe I'll only be calling CreateObjectEx2 (and what it needs) and UnloadLibrary. So, I can delete what those don't need. Is that correct?
    Yes. I think it needs to testing. I don't remember exactly.
    Couple words. You can use early binding as well. If i'm not wrong you can add your DLL to references (or TLB) and use an Interface to working with an object. It doesn't require any dependencies in an end exe (if you don't use New keyword with classes that contains in a Dll).
    I make small example that shows how you can use late/early binding.
    For example, you have the class CTestClass:
    Code:
    Option Explicit
    
    Public Sub ShowMessage( _
               ByRef sText As String)
        MsgBox sText
    End Sub
    You compile the Dll with TestDll.dll name. Run regsvr32 TestDll.dll -u in order to cancel registration.
    You can use any combination of this code in EXE (you should add your library to References):
    Code:
    Option Explicit
    
    Sub Main()
        'Dim tmpObj  As Object               ' // Late binding
        Dim tmpObj  As TestDll.CTestClass    ' // Early binding
        
        On Error GoTo error_handler
        
        ' // It wont work in EXE if the Dll has not been registered
        ' // Set tmpObj = New TestDll.CTestClass
        
    
        Set tmpObj = CreateObjectEx2(App.path & "\..\ActiveX_dll\TestDll.dll", _
                                     App.path & "\..\ActiveX_dll\TestDll.dll", _
                                     "CTestClass")
                                     
        tmpObj.ShowMessage "Test message"
                                     
        Exit Sub
        
    error_handler:
        
        MsgBox "An error occurs: " & Err.Description
        
    End Sub
    You can improve performance if you'll use CLSID. For example, you even can remove the resource with TypeLibrary from DLL in order to nobody know interfaces and classes in the DLL.
    Quote Originally Posted by Elroy View Post
    Lastly, so ... I need to call UnloadLibrary when I'm done with the ActiveX.dll and I want to get it out of memory? Correct?
    Yes. You can even delete this DLL if need.
    Attached Files Attached Files

  9. #9

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    @DEXWERX, yeah, I've got the manifest stuff all worked out in terms of getting the xml code needed. I just hadn't used a manifest with an ActiveX.dll before, but I assumed they work the same, which Trick suggested that they do. Thanks though.

    @Trick, again thanks! I've got some other work to do today, but I'll be working with all of this over the weekend. It looks like it's all going to work extremely well. I'll report back how it all goes.

    That's also interesting about the early-binding. Makes sense, and it might make my IDE development of the main project easier, and also help performance (as you say). I've just got to be careful to always use your CreateObjectEx2 for instantiation.

    In fact, I've already written a bit of a wrapper for CreateObjectEx2:
    Code:
    
    Public Function NewObjectFromActivexDll(ByRef pathToDll As String, _
                                            ByRef className As String) As IUnknown
        ' Create object by Name.
        ' Uses DLL as the TLB.
        '
        Set NewObjectFromActivexDll = CreateObjectEx2(pathToDll, pathToDll, className)
    End Function
    
    Elroy
    Last edited by Elroy; Sep 16th, 2016 at 10:09 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #10

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,910

    Re: VB6 ActiveX.dll, and using it without registering it (manifest?)

    Okay, I've now tested and Trick's procedures work flawlessly, and no need for any references to call a VB6 ActiveX.dll. I even embedded a manifest in the ActiveX.dll programs so that they wouldn't need references either, but others may not need that level of complexity.

    I cut Trick's procedures down to suit my needs, and thought I'd post my version here. I've just got it in a standard BAS module.

    Code:
    
    '
    ' For working with ActiveX.dll libraries without registration.
    ' Krivous Anatolii Anatolevich (The trick), 2015.
    ' Cut down by Elroy, 2016.
    '
    Option Explicit
    '
    Private Type GUID
        data1       As Long
        data2       As Integer
        data3       As Integer
        data4(7)    As Byte
    End Type
    '
    Private Declare Function CLSIDFromString Lib "ole32.dll" (ByVal lpszCLSID As Long, ByRef clsid As GUID) As Long
    Private Declare Function GetMem4 Lib "msvbvm60" (ByRef src As Any, ByRef dst As Any) As Long
    Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryW" (ByVal lpLibFileName As Long) As Long
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleW" (ByVal lpModuleName As Long) As Long
    Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
    Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Private Declare Function DispCallFunc Lib "oleaut32" (ByVal pvInstance As Any, ByVal oVft As Long, ByVal cc As Integer, ByVal vtReturn As Integer, ByVal cActuals As Long, ByRef prgvt As Any, ByRef prgpvarg As Any, ByRef pvargResult As Variant) As Long
    Private Declare Function LoadTypeLibEx Lib "oleaut32" (ByVal szFile As Long, ByVal regkind As Long, ByRef pptlib As IUnknown) As Long
    Private Declare Function memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) As Long
    '
    Private Const IID_IClassFactory   As String = "{00000001-0000-0000-C000-000000000046}"
    Private Const IID_IUnknown        As String = "{00000000-0000-0000-C000-000000000046}"
    Private Const CC_STDCALL          As Long = 4
    Private Const REGKIND_NONE        As Long = 2
    Private Const TKIND_COCLASS       As Long = 5
    '
    Private iidClsFctr      As GUID
    Private iidUnk          As GUID
    Private isInit          As Boolean
    '
    
    Public Function NewObjectFromActivexDll(ByRef pathToDll As String, _
                                            ByRef className As String) As IUnknown
        ' Create object by Name.
        ' Uses DLL as the TLB.
        '
        Set NewObjectFromActivexDll = CreateObjectEx2(pathToDll, pathToDll, className)
    End Function
    
    Public Sub UnloadActivexDll(ByRef path As String)
        ' Unload DLL if not used.
        '
        Dim hLib    As Long
        Dim lpAddr  As Long
        Dim ret     As Long
        Dim spot    As Long
        '
        spot = 1
        If isInit Then
            spot = 2
            hLib = GetModuleHandle(StrPtr(path))
            If hLib <> 0 Then
                spot = 3
                lpAddr = GetProcAddress(hLib, "DllCanUnloadNow")
                If lpAddr <> 0 Then
                    spot = 4
                    ret = DllCanUnloadNow(lpAddr)
                    If ret = 0 Then
                        FreeLibrary hLib
                        Exit Sub
                    End If
                End If
            End If
        End If
        If Not bCompiled Then MsgBox "Didn't unload " & Chr$(34) & path & Chr$(34) & " but got to spot " & Format(spot) & "."
    End Sub
    
    '******************************************************************************
    '
    ' Private from here down.
    '
    '******************************************************************************
    '
    Private Function CreateObjectEx2(ByRef pathToDll As String, _
                                     ByRef pathToTLB As String, _
                                     ByRef className As String) As IUnknown
        ' Create object by Name.
        ' The DLL can be used as the TLB with VB6 ActiveX.DLL files.
        '
        Dim typeLib As IUnknown
        Dim typeInf As IUnknown
        Dim ret     As Long
        Dim pAttr   As Long
        Dim tKind   As Long
        Dim clsid   As GUID
        '
        ret = LoadTypeLibEx(StrPtr(pathToTLB), REGKIND_NONE, typeLib)
        If ret Then
            Err.Raise ret
            Exit Function
        End If
        ret = ITypeLib_FindName(typeLib, className, 0, typeInf, 0, 1)
        If typeInf Is Nothing Then
            Err.Raise &H80040111, , "Class not found in type library"
            Exit Function
        End If
        ITypeInfo_GetTypeAttr typeInf, pAttr
        GetMem4 ByVal pAttr + &H28, tKind
        If tKind = TKIND_COCLASS Then
            memcpy clsid, ByVal pAttr, Len(clsid)
        Else
            Err.Raise &H80040111, , "Class not found in type library"
            Exit Function
        End If
        ITypeInfo_ReleaseTypeAttr typeInf, pAttr
        Set CreateObjectEx2 = CreateObjectEx1(pathToDll, clsid)
    End Function
    
    Private Function CreateObjectEx1(ByRef path As String, _
                                    ByRef clsid As GUID) As IUnknown
        ' Create object by CLSID and path.
        '
        Dim hLib    As Long
        Dim lpAddr  As Long
        Dim isLoad  As Boolean
        Dim ret     As Long
        Dim out     As IUnknown
        '
        hLib = GetModuleHandle(StrPtr(path))
        If hLib = 0 Then
            hLib = LoadLibrary(StrPtr(path))
            If hLib = 0 Then
                Err.Raise 53, , Error(53) & " " & Chr$(34) & path & Chr$(34)
                Exit Function
            End If
            isLoad = True
        End If
        lpAddr = GetProcAddress(hLib, "DllGetClassObject")
        If lpAddr = 0 Then
            If isLoad Then FreeLibrary hLib
            Err.Raise 453, , "Can't find dll entry point DllGetClasesObject in " & Chr$(34) & path & Chr$(34)
            Exit Function
        End If
        If Not isInit Then
            CLSIDFromString StrPtr(IID_IClassFactory), iidClsFctr
            CLSIDFromString StrPtr(IID_IUnknown), iidUnk
            isInit = True
        End If
        ret = DllGetClassObject(lpAddr, clsid, iidClsFctr, out)
        If ret = 0 Then
            ret = IClassFactory_CreateInstance(out, 0, iidUnk, CreateObjectEx1)
        Else
            If isLoad Then FreeLibrary hLib
            Err.Raise ret
            Exit Function
        End If
        Set out = Nothing
        If ret Then
            If isLoad Then FreeLibrary hLib
            Err.Raise ret
        End If
    End Function
    
    Private Function DllGetClassObject(ByVal funcAddr As Long, _
                                       ByRef clsid As GUID, _
                                       ByRef iid As GUID, _
                                       ByRef out As IUnknown) As Long
        ' Call "DllGetClassObject" function using a pointer.
        '
        Dim params(2)   As Variant
        Dim types(2)    As Integer
        Dim list(2)     As Long
        Dim resultCall  As Long
        Dim pIndex      As Long
        Dim pReturn     As Variant
        '
        params(0) = VarPtr(clsid)
        params(1) = VarPtr(iid)
        params(2) = VarPtr(out)
        '
        For pIndex = 0 To UBound(params)
            list(pIndex) = VarPtr(params(pIndex)):   types(pIndex) = VarType(params(pIndex))
        Next
        resultCall = DispCallFunc(0&, funcAddr, CC_STDCALL, vbLong, 3, types(0), list(0), pReturn)
        If resultCall Then Err.Raise 5: Exit Function
        DllGetClassObject = pReturn
    End Function
    
    Private Function DllCanUnloadNow(ByVal funcAddr As Long) As Long
        ' Call "DllCanUnloadNow" function using a pointer.
        '
        Dim resultCall  As Long
        Dim pReturn     As Variant
        '
        resultCall = DispCallFunc(0&, funcAddr, CC_STDCALL, vbLong, 0, ByVal 0&, ByVal 0&, pReturn)
        If resultCall Then Err.Raise 5: Exit Function
        DllCanUnloadNow = pReturn
    End Function
    
    Private Function IClassFactory_CreateInstance(ByVal obj As IUnknown, _
                                                  ByVal punkOuter As Long, _
                                                  ByRef riid As GUID, _
                                                  ByRef out As IUnknown) As Long
        ' Call "IClassFactory:CreateInstance" method.
        '
        Dim params(2)   As Variant
        Dim types(2)    As Integer
        Dim list(2)     As Long
        Dim resultCall  As Long
        Dim pIndex      As Long
        Dim pReturn     As Variant
        '
        params(0) = punkOuter
        params(1) = VarPtr(riid)
        params(2) = VarPtr(out)
        '
        For pIndex = 0 To UBound(params)
            list(pIndex) = VarPtr(params(pIndex)):   types(pIndex) = VarType(params(pIndex))
        Next
        resultCall = DispCallFunc(obj, &HC, CC_STDCALL, vbLong, 3, types(0), list(0), pReturn)
        If resultCall Then Err.Raise resultCall: Exit Function
        IClassFactory_CreateInstance = pReturn
    End Function
    
    Private Function ITypeLib_FindName(ByVal obj As IUnknown, _
                                       ByRef szNameBuf As String, _
                                       ByVal lHashVal As Long, _
                                       ByRef ppTInfo As IUnknown, _
                                       ByRef rgMemId As Long, _
                                       ByRef pcFound As Integer) As Long
        ' Call "ITypeLib:FindName" method.
        '
        Dim params(4)   As Variant
        Dim types(4)    As Integer
        Dim list(4)     As Long
        Dim resultCall  As Long
        Dim pIndex      As Long
        Dim pReturn     As Variant
        '
        params(0) = StrPtr(szNameBuf)
        params(1) = lHashVal
        params(2) = VarPtr(ppTInfo)
        params(3) = VarPtr(rgMemId)
        params(4) = VarPtr(pcFound)
        '
        For pIndex = 0 To UBound(params)
            list(pIndex) = VarPtr(params(pIndex)):   types(pIndex) = VarType(params(pIndex))
        Next
        resultCall = DispCallFunc(obj, &H2C, CC_STDCALL, vbLong, 5, types(0), list(0), pReturn)
        If resultCall Then Err.Raise resultCall: Exit Function
        ITypeLib_FindName = pReturn
    End Function
    
    Private Sub ITypeInfo_GetTypeAttr(ByVal obj As IUnknown, _
                                      ByRef ppTypeAttr As Long)
        ' Call "ITypeInfo:GetTypeAttr" method.
        '
        Dim resultCall  As Long
        Dim pReturn     As Variant
        '
        pReturn = VarPtr(ppTypeAttr)
        resultCall = DispCallFunc(obj, &HC, CC_STDCALL, vbEmpty, 1, vbLong, VarPtr(pReturn), 0)
        If resultCall Then Err.Raise resultCall: Exit Sub
    End Sub
    
    Private Sub ITypeInfo_ReleaseTypeAttr(ByVal obj As IUnknown, _
                                          ByVal ppTypeAttr As Long)
        ' Call "ITypeInfo:ReleaseTypeAttr" method.
        '
        Dim resultCall  As Long
        '
        resultCall = DispCallFunc(obj, &H4C, CC_STDCALL, vbEmpty, 1, vbLong, VarPtr(CVar(ppTypeAttr)), 0)
        If resultCall Then Err.Raise resultCall: Exit Sub
    End Sub
    
    Private Function bCompiled() As Boolean
        On Error GoTo Errored
        Debug.Print 1 / 0
        bCompiled = True
    Errored:
    End Function
    
    And here's an example of how I use it...
    Code:
    
    
    Private Sub cmdDotsr_Click()
        Dim oDotsrDll As Object
        '
        Hide
        Set oDotsrDll = NewObjectFromActivexDll(DependenciesFolder & "Dotsr.dll", "clsDotsrDll")
        oDotsrDll.SetGlobals wsTheWorkspace, dbTheDatabase, PatientData, Encounters, gbEscToExit, bCompiled, DotsrData
        oDotsrDll.Execute
        oDotsrDll.CleanUp
        Set oDotsrDll = Nothing
        UnloadActivexDll DependenciesFolder & "Dotsr.dll"
        Show
    End Sub
    
    Now, for my DLL, it's a project named Dotsr.dll, and it has a single class in it named clsDotsrDll. And this class has three methods: SetGlobals, Execute, & Cleanup. Also, there are some variables scoped outside of that CommandButton procedure I've shown you, namely: DependenciesFolder, wsTheWorkspace, dbTheDatabase, PatientData, Encounters, gbEscToExit, bCompiled, & DotsrData. However, this should give you the idea how to use Trick's procedures.

    Just FYI, the oDotsrDll.Execute takes the user through several questions, loading up many forms that are internal to the Dotsr.dll, and this oDotsrDll.Execute doesn't return until the user has completed all the tasks. It even records its data into the database, via the globals it was told about.

    Regards,
    Elroy
    Last edited by Elroy; Sep 17th, 2016 at 09:00 AM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

Posting Permissions

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



Click Here to Expand Forum to Full Width