Results 1 to 31 of 31

Thread: How do I create a TypeLib for UDTs in VB6?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    How do I create a TypeLib for UDTs in VB6?

    I have created a user-defined-type like this in my form in VB6.
    Code:
    Private Type Rational
    Numerator As Long
    Denominator As Long
    End Type
    I tried putting a variable of this type, into a variable of type Variant, but I got the error "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions".

    I then tried changing the declaration of the type to Public, and put it inside a VB6 module like this.
    Code:
    Public Type Rational
    Numerator As Long
    Denominator As Long
    End Type
    But I still ended up getting the same error.

    Since then I've read that you can't do that, unless you do one of 3 things:
    1) Use a Class instead of a UDT
    2) Put the UDT in an ActiveX DLL file and register the DLL file
    3) Put the UDT in a TypeLib (a file with the TLB file extension)

    I already know how to do the first 2 of those techniques. I'm interested in doing #3 in that list. How do I create a TypeLib in VB6 that contains the desired UDT? Can somebody here tell me how to do it, and if it requires additional TypeLib making software, please point me to a place to download or purchase such software.

  2. #2
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  3. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Ben, I didn't read through Bonnie's link, and I intend to do that, but I can give you some pointers on getting a TypeLib created.

    • Start VB6 Project.
    • Under Project/Project1 Properties..., change it to an ActiveX DLL.
    • Add a standard module and put a Sub Main in it.
    • Add a Class1 module.
    • Under Project/Project1 Properties... again, go to the "Components" tab and check "Remote Server Files".
    • Compile the project.
    • Voila, a Project1.tlb file appears.


    Now, I'm not comfortably in my area of expertise, but I'm thinking with a more fleshed out Class1, with Public "stuff" in it, you're on your way. Also, you probably want to just delete Form1, unless you intend on your DLL having some user interface.

    It's my understanding that UDTs are to be combined with Variants only when passing arguments into and out of one of these ActiveX components. I've never tried to just piggy-back on the TypeLib's declaration to use the UDT within my program. It'd be interesting to know if it'd work.

    Regards,
    Elroy

    EDIT1: If fafalone's error message is true, I still think you're out of luck.
    'Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound modules.'
    ... actually the same error message you posted.

    Truth be told, I've never missed being able to stuff a UDT into a variant. If I ever have a need for something similar, I just build a class in my project, and build Get/Let/Set properties that make it look just like a UDT. Just like Variants not liking fixed length strings, they don't much like UDTs either.

    I'm guessing it's something to do with having an "address to an address" for things that don't typically work that way, such as fixed length strings and UDTs.
    Last edited by Elroy; Aug 17th, 2016 at 03:43 PM.
    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.

  4. #4
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How do I create a TypeLib for UDTs in VB6?

    Hi Ben,

    I'm curious. If I might ask.
    1) What are you building?
    2) Why do you want to put the UDT in a variant?
    3) What advantage to you hope to gain by using a TBL over a DLL?
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Cool beans, it actually seems to work just fine. Here's what I did. Create a Project1.dll just as outlined in post #3. I deleted the Form1 from it though. I also declared the following at the top of Class1:

    Code:
    
    Option Explicit
    
    Public Type udt
        i1 As Long
        i2 As Long
    End Type
    
    
    
    Then...

    • Re-compiled it, just as outlined in post #3.
    • Started another project, naming it as Project2 under Project/Project? Properties... (Project Name).
    • (This project2 was just a regular Standard EXE project.)
    • Under Project/References... I attempted to add Project1.tlb, but it failed...
      • I figured out that I had to register it, so...
      • I popped open a CMD window, navigated to where the Project1.tlb was.
      • Then typed: path>regtlib Project1.tlb
    • Tried to add Project1.tlb to Project2 again, and it succeeded.
    • Then I added the following code to Project2's Form1, and it succeeded.


    Code:
    
    Option Explicit
    '
    
    Private Sub Form_Load()
        Dim u As Project1.udt
        Dim v As Variant
        '
        u.i1 = 5
        u.i2 = 8
    
        v = u
    
        test v
    
    
    End Sub
    
    
    Sub test(v As Variant)
        MsgBox v.i1
    End Sub
    
    
    Now, I'm curious about whether I can just abandon the Project1.dll so long as I don't actually attempt to use it to instantiate an object from Class1. To partially test this, I deleted the Project1.dll, and re-executed the Project2 test, and it still worked just fine. So apparently, voila, UDTs in Variants.

    Have Fun,
    Elroy

    EDIT1: If this is all true and all the typelib info just gets compiled into the program, it makes you wonder why they didn't just allow UDTs in Variants natively.
    Last edited by Elroy; Aug 17th, 2016 at 04:19 PM.
    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.

  6. #6
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Still curious as to how far this could be pushed, I tried adding a public fixed length string to the Class1 (in my Project1.dll), but it was a syntax error.

    Next, I tried adding the following code to the Class1:

    Code:
    
    Public Type udtstr
        s As String * 10
    End Type
    
    It wasn't a syntax error, but I did get a compiler error:
    Fixed-length strings and use of the 'new' qualifier are not allowed for fields in a public user defined type defined in an object module.
    Therefore, I guess we still don't get fixed length strings into Variants.

    EDIT1: I did try one last thing. I tried moving the above udtstr declaration to the Module1.bas (within the Project1.dll project), and recompiled, and re-registered my Project1.tlb. I then started another Project2, added the Project1.tlb, but I couldn't "see" the udtstr type. Obviously, when declared in a standard module (even of a .dll), these UDTs aren't "exposed", and are not included in the typelib.
    Last edited by Elroy; Aug 17th, 2016 at 04:29 PM.
    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

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I create a TypeLib for UDTs in VB6?

    I'm trying to avoid creating an ActiveX DLL file, and instead create a TLB who's ONLY contents are the definition for my user defined type. I do NOT want a TLB that contains definitions for an ActiveX DLL file

    I want the entire content of the TLB file to ONLY be a definition of the user defined type I'm trying to make work with variants. Is there a way to do this? Is there a tool I can use (either from MS, or a 3rd party) that can create a TLB with the definition of a user defined type? If I can avoid compiling an ActiveX DLL, that would be GREAT.

    I hate those AX DLLs. AX DLLs require registration (adding data to the registry). This means when you distribute a program that uses an AX DLL, not only do you need to distribute the EXE and the DLL, but you need to include an installer for your software, which when run invokes regsvr32 to register the AX DLL. And of course since adding data to the registry requires Admin level of permission, you can't do this on modern PCs if you aren't logged in as the admin. I'm trying to create an INSTALLERLESS (portable) application, which has all the functions STATICALLY LINKED (embedded in the EXE file). And from my understanding, that's what a TLB does. It can include all the same stuff as an AX DLL file, but instead of creating an external file that needs to be registered, a TLB statically links into the EXE file when it is compiled. This means that the TLB only exists as a separate file on the programmer's PC, and only requires registration on the programmer's PC. It does NOT exist as a separate file and does NOT require registration, on the end-user's PC, as it is embedded in the compiled EXE file itself. So you can distribute a single-file application to the end-user, that single file being the EXE file.
    Last edited by Ben321; Aug 17th, 2016 at 04:37 PM.

  8. #8
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Ben,

    I don't understand. What's your ultimate objective? Are you trying to develop a TypeLib that you'll distribute to other developers?

    If not, then what do you care if some superfluous information is in the TypeLib? It's all just compiled into the executable, so you're the only one who'd have to manage the actual TypeLib.

    There are probably TypeLib editors out there, but I'm not familiar with them.

    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.

  9. #9
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    So, Ben, have you looked at my link in Post #2 yet? You really wouldn't want to ignore that.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  10. #10

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Elroy View Post
    Ben,

    I don't understand. What's your ultimate objective? Are you trying to develop a TypeLib that you'll distribute to other developers?

    If not, then what do you care if some superfluous information is in the TypeLib? It's all just compiled into the executable, so you're the only one who'd have to manage the actual TypeLib.

    There are probably TypeLib editors out there, but I'm not familiar with them.

    Elroy
    If I create a TypeLib based on an ActiveX DLL file, then I will need to distribute the ActiveX DLL file. It won't require the AX DLL file to be registered (info added to the registry), as the EXE file with the TLB will now contain all the information within itself needed to use the AX DLL, but it will still require distributing the AX DLL file itself. In other words, using VB6 to create a TLB will create a TLB that simply contains references to an AX DLL file. However, from my understanding, you can also create (using tools other than VB6) a TLB that will encapsulate all kinds of things other than references to an AX DLL file. Using these additional tools, you can create a TLB that includes its own functions, constants, user-defined-types, etc. Does anybody here know the name of such software though? And if so, what is it called, and where can I get it?

  11. #11

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Bonnie West View Post
    So, Ben, have you looked at my link in Post #2 yet? You really wouldn't want to ignore that.
    I did. All they showed were code samples that looked like they were in C or C++. The "struct" is NOT a VB6 concept.

  12. #12
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Ben321 View Post
    I did. All they showed were code samples that looked like they were in C or C++. The "struct" is NOT a VB6 concept.
    What you just saw was an IDL/ODL script. Compiling that script via either MIDL.EXE or MKTYPLIB.EXE (they're both in the VS6 CDs) will give you a TLB file. I've already shown you before how a TLB file can be referenced in VB6 without registering it in the system. Writing an IDL/ODL script requires that you have some knowledge of basic C/C++ syntax and also of Windows Data Types.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  13. #13
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    It's quite clear that Bonnie has given you a path for creating TypeLibs with whatever you'd like in them. It's also nice to know how to include a TypeLib in your VB6 project without registering it.

    However...

    Quote Originally Posted by Ben321 View Post
    If I create a TypeLib based on an ActiveX DLL file, then I will need to distribute the ActiveX DLL file.
    ... from my testing, that's not true.

    I tested that very concept in my post #5:

    Now, I'm curious about whether I can just abandon the Project1.dll so long as I don't actually attempt to use it to instantiate an object from Class1. To partially test this, I deleted the Project1.dll, and re-executed the Project2 test, and it still worked just fine. So apparently, voila, UDTs in Variants.
    I'll admit that some more testing may be in order, but I'm actually not clear on what that would even be. I'm just using the TypeLib to declare "types" and not actually instantiate "classes", so all should be well. So, if you're looking for a pure VB6 approach, it appears you have one.

    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.

  14. #14
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Elroy View Post
    So, if you're looking for a pure VB6 approach, it appears you have one.
    The pure VB6 approach to creating TLBs is actually a pretty good option in many cases. Its biggest drawback though IMO, is that it pollutes the Registry. While the ActiveX DLL's registry entries can always be unregistered afterwards, I prefer to prevent this from happening in the first place by compiling the ActiveX DLL either under the supervision of a "sandbox" type of program or inside a virtual machine OS.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  15. #15
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: How do I create a TypeLib for UDTs in VB6?

    Would a SxS manifest keep the registry clean?

  16. #16
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Dex, it's puzzling to me why I had to register the TypeLib after I compiled, but I was always under the impression that making ActiveX components placed things in the registry during compile. I'm going to guess that it's just the TypeLib info that didn't get auto-registered when compiled, but the actual ActiveX.dll (or ActiveX.ocx) did get registered when compiled.

    I'm not sure there's a way to stop the VB6 IDE (or the VB6.exe, if compiled from a batch file) from auto-registering the component. At least I'm not able to find a switch anywhere to do this. You can probably check the "Project Compatibility" or "Binary Compatibility" switch to keep it from auto-registering with different UUIDs more than once, but I don't think there's a way to completely suppress the auto-registering.

    I'm pretty sure this is the registry cluttering that Bonnie is talking about.

    TypeLibs used in the way discussed in this thread (just to get UDTs into Variants), there wouldn't be any registry cluttering of client computers, unless you did include the superfluous DLL in your package.

    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.

  17. #17
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: How do I create a TypeLib for UDTs in VB6?

    @Elroy it's not really practical to keep the registry clean on the development machine, so my question is really geared at deployment.

    I'm count on typelib's not getting autoregistered on compile or my machine would be a total mess....
    I don't mind polluting my VB Development VM however. (which is not where i compile TLBs)

  18. #18
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by DEXWERX View Post
    it's not really practical to keep the registry clean on the development machine
    I tend to agree with you, but I do think that's the point to which Bonnie was referring.

    Quote Originally Posted by DEXWERX View Post
    my question is really geared at deployment
    As long as you toss the superfluous DLL that was created, and just use the TypeLib, there shouldn't be any registry consequences to deployment.
    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.

  19. #19
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Ben321 View Post
    If I create a TypeLib ... you can create a TLB that includes its own functions, constants, user-defined-types, etc.
    reading this statement I guess I fail to see the advantage over a class based solution which can of course do all those things.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  20. #20
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by DEXWERX View Post
    Would a SxS manifest keep the registry clean?
    It's my understanding that when an ActiveX DLL/OCX is used in conjunction with a SxS manifest, no CLSIDs/IIDs/TypeLibs/etc. are written to the Registry.

    Quote Originally Posted by Elroy View Post
    Dex, it's puzzling to me why I had to register the TypeLib after I compiled, but I was always under the impression that making ActiveX components placed things in the registry during compile. I'm going to guess that it's just the TypeLib info that didn't get auto-registered when compiled, but the actual ActiveX.dll (or ActiveX.ocx) did get registered when compiled.
    ActiveX DLLs/OCXs typically contain a TLB resource and it is actually that TLB resource that gets registered when the ActiveX DLL/OCX is registered. So, when VB6 registered the newly compiled DLL/OCX, there really is no need to register the standalone TLB file as well since the information in it (which is identical to the embedded TLB resource) has already been registered.

    Quote Originally Posted by DEXWERX View Post
    @Elroy it's not really practical to keep the registry clean on the development machine, ...
    Preventing obsolete ActiveX registry entries indeed requires a significant amount of effort, but it can be done and IMHO, the rewards are worth the effort (the system doesn't get slower and slower over time for instance).
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  21. #21
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Bonnie West View Post
    ActiveX DLLs/OCXs typically contain a TLB resource and it is actually that TLB resource that gets registered when the ActiveX DLL/OCX is registered. So, when VB6 registered the newly compiled DLL/OCX, there really is no need to register the standalone TLB file as well since the information in it (which is identical to the embedded TLB resource) has already been registered.
    But Bonnie, for this pure UDT in Variant case, what I was recommending was to build your UDT in an ActiveX.dll type project, compile it, and then delete the resulting ActiveX.dll, leaving only the ActiveX.tlb.

    Then, for a subsequent project (that'll use that TypeLib to get the UDT into a Variant) we'd reference that ActiveX.tlb so we could continue with our work.

    The TypeLib internal to the ActiveX.dll may have been registered, but the external one (that got created from me checking "Remote Server Files") didn't seem to get registered. Therefore, to use it in a subsequent project (for purposes of getting its UDT into a Variant), it had to be manually registered. At least that was my experience.

    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.

  22. #22
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    The standalone TLB file that gets generated when the "Remote Server Files" checkbox is ticked is actually exactly the same as the TLB resource that's embedded in the ActiveX DLL. Therefore, the standalone TLB file doesn't need to be registered because the information it contains has already been registered (remember, the standalone TLB and the TLB resource are identical). Note that deleting the ActiveX DLL without unregistering it first will render that ActiveX DLL's registry entries obsolete.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  23. #23
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Hmmm, ok, maybe my machine is messed up or something. Yes, I do understand what you're saying, but there's also got to be something in the registry about how a new VB6 IDE project is going to "get" those TypeLibs. In other words, what file is your VB6 IDE project going to "point at" to indicate that it wants to use them.

    Here's what I did to suggest a need for manual registration:

    1. start a new project
    2. change the project name to "test"
    3. mark it as an ActiveX.dll project
    4. add a class
      • add any Public Sub to it
    5. add a BAS module
      • add Sub Main to it
    6. specify you want the "Remote Server Files"
    7. compile it as test.dll


    Note that the order of those steps is somewhat important. I get these files: test.dll, test.exp, test.lib, test.tlb, test.vbr.

    Alright, now, I can shut down that copy of the IDE. It doesn't really matter whether or not you save anything.

    Now for the test:
    • start another new project
    • (this time, we'll want to use our new TypeLib, specifically test.tlb)
    • Open up Project/References...
    • Browse to the new test.tlb and attempt to add it.


    It won't add. It doesn't report any error or anything. It just won't add.

    Now, bounce out to a CMD window and register the test.tlb.

    And again open the Project/References..., browse to test.tlb and add it.

    This time it works.

    Note, you do have to close the references window and then re-open it after you've registered the TypeLib.

    If you're having different results, I'd sure be curious to know.

    A couple of other points.

    • In this example, I didn't ever delete the test.dll file.
    • However, once the test.tlb is registered, it doesn't seem to matter whether test.dll is deleted or not.
    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.

  24. #24
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: How do I create a TypeLib for UDTs in VB6?

    Quote Originally Posted by Elroy View Post
    ... but there's also got to be something in the registry about how a new VB6 IDE project is going to "get" those TypeLibs. In other words, what file is your VB6 IDE project going to "point at" to indicate that it wants to use them.
    I believe a registry key similar to the following holds the path to the type library file/resource:

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\1.0\0\win32

    The UUID in that registry key is the UUID of the type library (it can be obtained via a TLB viewer such as OleView.exe).

    Quote Originally Posted by Elroy View Post
    • However, once the test.tlb is registered, it doesn't seem to matter whether test.dll is deleted or not.
    When the standalone TLB file was registered, the above registry key was updated and it now points to the TLB file instead of the ActiveX DLL which has an embedded copy of the TLB file. The registry still has entries for the ActiveX DLL though, such as this one:

    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\InprocServer32

    The UUID here is the UUID of one of the coclasses in the type library. Unceremoniously deleting the ActiveX DLL is therefore not really advisable because registry entries like the above will be orphaned.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  25. #25
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    Sounds good, I "get" it.

    So, to get UDTs into Variants:
    • do like outlined above.
    • register the resulting .tlb file.
    • don't delete the .dll file (but it won't be used).
    • don't distribute the .dll file.


    Sounds like a plan, and it seems to work without any problems.

    Also, I guess advice should be out there to use "Binary Compatibility" in the ActiveX.dll project to create the typelibs (especially if they'll occasionally be adding more UDTs to it), so one doesn't pollute their registry to badly. In fact, since all we're using it for is to get a .tlb file, there's probably very little downside to just using the same ActiveX.dll project for all our projects that want these UDTs in Variants.

    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.

  26. #26
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: How do I create a TypeLib for UDTs in VB6?

    I'm not sure, whether all participants in this thread are aware, that the acknowledged rule:
    "You don't have to ship a *.tlb along with your compiled Binaries" only holds true for typelib-infos,
    which are *not* related to UDT-definitions in said *.tlb.
    If a given *.tlb does contain UDT-defs - and when these UDTs in turn are used either:
    . 1) in Variants (forcing IRecordInfo to kick in)
    . 2) as Arguments in Event-Definitions (same reason as above)
    . 3) as Arguments in Method-Signatures on Public COM-Interfaces
    ...then the vbRuntime will be forced to perform extra-registry-lookups at runtime
    (no matter if the tlb-info was known at compile-time)...

    And whilst #3 above is only relevant for ActiveX-Exes, Dlls or OCX-Binaries -
    the points #1 and #2 are relevant also for normal "Standalone-Exes"...

    That means, that a created TypeLib (which defines a "Variant-capable UDT"),
    *has* to be shipped along with the Executable in question and it needs registering as well -
    (when points #1 and #2 above are true).

    So, this means that "bothering with *.tlb-creation the hard way" is not really necessary, because
    it's easier and much more straight forward, to define the "Public, and Variant-capable UDT-Def"
    inside an ActiveX-Dll project (which can then also contain other useful Helper-Classes) -
    and then simply use SxS-manifests, to be able to ship the Standard-Executable (along with the
    compiled ActiveX-Dll) as a portable App.

    Olaf
    Last edited by Schmidt; Aug 21st, 2016 at 06:21 PM.

  27. #27
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: How do I create a TypeLib for UDTs in VB6?

    You can also make all of this go away by avoiding UDTs and using simple value classes instead. While this doesn't substitute for all UDT usage it works quite well for the majority of cases. If necessary you can add code to persist them as text data (XML, JSON, INI-like key/value lists) or PropertyBags or whatever.

    This can be much more useful because you can also extend them by adding code as property, method, and event definitions.

    No DLL, no TLB, no anything extra required.

  28. #28
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How do I create a TypeLib for UDTs in VB6?

    Somewhere in the attic is a dusty box with a floppy that has a small program written in VB6.
    It converts UDT definitions to class properties and loads them onto the windows clipboard for pasting.

    It wasn't all the difficult to write as I recall.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  29. #29
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,852

    Re: How do I create a TypeLib for UDTs in VB6?

    I'm not really sure it needs a conversion program.

    • start a new class and name it the name of the UDT declaration
    • remove the Type...End Type lines from the UDT declaration
    • cut-paste all the items of the type into the new class
    • put the Public keyword before all the items
    • put the "New" keyword in all the places where you'd declared a variable with your UDT
    • and you should be good to go


    I suppose one might be handy. If I were to write it, I'd just have it do it from the clipboard. Copy old UDT into the clipboard, run my little program, paste results into new class module.

    Not sure there's an easy way around inserting the "New" keyword though.

    Regards,
    Elroy

    EDIT1: I suppose one downside I see is where you use Private Type UdtTypeName, and then use that same UdtTypeName in other places with a different set of items. That's horrible programming practice, but it would create a bit more work to convert one or all to classes.

    Also, of course, the "New" keyword isn't used in argument declarations.

    EDIT2: Also, just thinking about it, I suppose it would be a bit less resource intensive if you actually did create Friend Property Get and Friend Property Let procedures for all of them, and then have those Get/Let module level variables in the new class. But my bullet-points above would certainly get it done.
    Last edited by Elroy; Aug 20th, 2016 at 07:56 PM.
    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.

  30. #30
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How do I create a TypeLib for UDTs in VB6?

    I believe my app which I cannot locate converted UDT code into get/let property lists not public variables.
    This saved one heck of a lot of typing and made the conversion a lot less painful.

    I also used to use custom collection classes so you could add class instances by entering their property values directly.

    Code:
    Dim Users as clsUsers
    Set Users = New clsUsers
    Users.Add("Bob","Thornton", "03/27/1961", 74. "503-396-5454")
    ' The add method internally creates the new instances of the class items.
    As well as create parameter based Initializer methods for the class items.
    Code:
    User.Init("Jill","Tilly", "12/02/1972", 74. "503-397-2351")
    For UDT file compatibilty you could write a small import and export conversion methods into the custom collection class.

    Once you create the classes working with them in code is actually easier than using UDTs
    in my opinion.
    Last edited by Gruff; Aug 21st, 2016 at 04:48 AM.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

  31. #31
    Frenzied Member Gruff's Avatar
    Join Date
    Jan 2014
    Location
    Scappoose Oregon USA
    Posts
    1,293

    Re: How do I create a TypeLib for UDTs in VB6?

    Here is a small proof of concept for writing UDTs from a class.
    The file IO would be better if encapsulated in the custom collection class.
    It is just a silly test so go easy on the code comments.
    Code:
    Option Explicit
    'Class clsUser
    
    Private Type mUser
      Name As String * 25
      Age As Byte
    End Type
    
    Private mUDT As mUser
    
    Public Property Get Name() As String
      Name = mUDT.Name
    End Property
    
    Public Property Let Name(Value As String)
      If Len(Value) > 25 then Value = Left$(Value,25)
      mUDT.Name = Value
    End Property
    
    Public Property Get Age() As Byte
      Age = mUDT.Age
    End Property
    
    Public Property Let Age(Value As Byte)
      mUDT.Age = Value
    End Property
    
    Public Sub FileWrite(FileHandle As Integer, Pos As Integer)
      Put FileHandle, Pos, mUDT
    End Sub
    
    Public Sub FileRead(FileHandle As Integer, Pos As Integer)
      Get FileHandle, Pos, mUDT
    End Sub
    
    Public Property Get UdtSize() As Integer
      UdtSize = LenB(mUDT)
    End Property
    
    Public Sub Init(UserName As String, UserAge As Byte)
      mUDT.Name = UserName
      mUDT.Age = UserAge
    End Sub
    Code:
    ' Form Code
    Option Explicit
    
    Private Sub CommandButton1_Click()
      Dim User As clsUser: Set User = New clsUser
      
      With User
        .Init "Steve", 25
        MsgBox .Name & "  " & .Age
        
        Open "C:\Test1.dat" For Random As #1 Len = (.UdtSize)
        .FileWrite 1, 1
        Close #1
      End With
    End Sub
    
    Private Sub CommandButton2_Click()
     ' Use a new variable to avoid contamination of test
     Dim User2 As clsUser: Set User2 = New clsUser
     
     With User2
       Open "C:\Test1.dat" For Random As #1 Len = (.UdtSize)
       .FileRead 1, 1
       Close #1
     
       MsgBox .Name & "  " & .Age
     End With
    End Sub
    Last edited by Gruff; Aug 21st, 2016 at 08:12 AM.
    Burn the land and boil the sea
    You can't take the sky from me


    ~T

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