Results 1 to 24 of 24

Thread: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Question Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Hello everyone,

    I'm working with VB6 and I have imported a type library into my project. I've run into an issue where I cannot use fully qualified names for enum values, even though the enums are defined in my type library. Here's what I've done:

    Type Library Definition (.IDL File):
    Code:
    import "oaidl.idl";
    [uuid(3869b3c3-8849-45a0-a337-bab659c42363), version(1.0)] library mylib
    {
    typedef [v1_enum] enum {
        MB_NONE = -1,
        MB_LEFT = 1,
        MB_LEFTDOUBLE = 2,
        MB_RIGHT = 3,
    } eMouseButtons;
    
    typedef [v1_enum] enum {
        BT_BalloonTopic_NONE = 0,
        BT_CLICKTOPURCHASEBOOK = 1,
        BT_SPACENOTNECESSARY = 2,
        BT_THIRDDOTNOTNECESSARY = 3,
    } eBalloonTopic;
    }
    Compiling and Registering the Type Library:
    I compiled the IDL file with midl to produce mylib.tlb and then registered it using regtlib.exe.

    Using the Type Library in VB6:
    After adding a reference to mylib.tlb in my VB6 project, I tried to declare and use the enum values. Here is the code snippet:

    Code:
    Dim i As mylib.eMouseButtons
    i = MB_DRAGDROP_DROP 'This works, but it's not fully qualified.
    
    'However, these do not work:
    i = mylib.eMouseButtons.MB_DRAGDROP_DROP 'Error: does not work.
    i = eMouseButtons.MB_DRAGDROP_DROP 'Error: does not work.
    Problem:
    I would like to use the fully qualified names for enum values to avoid potential naming conflicts and for better code clarity. However, VB6 does not seem to recognize the enum type as a qualifier for the enum values.

    Questions:

    Is there a way to use fully qualified enum names in VB6 when using a type library?
    If not, what are the best practices to handle similar situations where name clashes might occur due to global scope enums?
    Any help or guidance would be greatly appreciated!

  2. #2
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,619

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Move your TypeLib reference higher up in your list of references to increase priority.

    Better yet, declare your enums in a BAS module for maximum priority.

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    That is not reason and not a fix unfortunately.

    Using the enums inside a .bas provides the full path option, but I need to have the enums in a typelib because I have too many enums for VB6 to handle (results in Out of memory error).

    I used to have them in an activex exe, and that provided the full path option, but caused other weirdnesses which is why I chose idl / midl / typelib now.
    Last edited by tmighty2; Aug 16th, 2024 at 03:36 PM.

  4. #4
    PowerPoster VanGoghGaming's Avatar
    Join Date
    Jan 2020
    Location
    Eve Online - Mining, Missions & Market Trading!
    Posts
    2,619

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    If you have too many enums for one BAS module then simply split them fifty-fifty between two or more BAS modules. Problem solved.

  5. #5
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Use oleview to check if midl mangled the names (my guess since you omitted a leading name). midl is a nightmare for vb6-compatible typelibs.

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Is there any other tool you would prefer over midl?

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Can you define "mangled names"?

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I found a solution. I am again using ActiveX even though I had disposed the idea.
    The problem was that it wouldn't generated the tlb, only .exe or .dll.

    I got this problem resolved now, and now I have only .tlb, and all works fine.
    Thank you!

    Start VB6 as admin

    Project type: ActiveX-DLL
    Startobject: Sub Main
    Add a class to it:
    Bindinung: vbNone
    Source: vbone
    Instance: 6 Global Multise
    MTS: 0 NotAnMTS
    Persistable: 1

    Add your enums and udts in it, e. g.


    Code:
    Option Explicit
    
    Public Enum eBlas
        eBlas1 = 1
        eBlas2 = 2
    End Enum
    
    Public Type udtMyType
        MyType As String
        MyLong As Long
    End Type

    Update active x cotnrols
    Threading: Single Threaded
    Check "Remove information about not used active x controls"
    Check "Remote server files"
    Check "No compatiblity"
    Compile the project.

    This will create a dll and a tlb.

    Open a new vb6 project in admin mode, click "Add reference" and select the tlb.
    It will not work.

    Add the dll as a reference. This will work.
    Save this test project and re-open up.
    Add the tlb as a reference.
    It will work.
    You can also delete the dll.

    ps: I had to repeat the scenario and noticed I was:

    It only worked when I (noticing it didn't work) switched from ActiveX-DLL to ActiveX-Exe and compile and then switched to ActiveX-DLL again.
    Last edited by tmighty2; Aug 17th, 2024 at 08:52 PM.

  9. #9
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    mktyplib works better for plain tlbs for vb6, it;s included with it.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    The issue is that one must NOT be admin when creating the exe or dll.
    It will tell about registration error.
    Nevermind, start vb6 as admin now and use the tlb.

    It worked for me.

  11. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,909

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Just FYI, once compiled, you shouldn't need to worry about this type of TypeLib at all. It'll all be wrapped into the executable.
    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.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I found out more:

    The tlb was always locked by an exe that I built with a reference to it.
    I thought VB6 was to blame. Therefore I created a tlb using a text editor and compiling it with midl and registering it with regtlb.
    There problem is still the same:

    When I build an exe and use the enums / types in the tlb as a reference, the tlb will be locked.

    Does anybody know a way around?

    I can not keep the enums in vb6 in a bas as vb6 reports an out of memory error because my projects are too big.

    FYI, here is a sample of such a .idl file that I created.

    I do not understand yet why the tlb is locked / used after compilation.

    Code:
    // Generated .IDL file (by tws TypeLibMake)
    //
    // typelib filename: twsLib.tlb
    
    [
      uuid(C94B5E98-E2CE-4E0E-A64E-3EACDB8EF12E),
      version(1.03)
    ]
    library twsLib
    {
        // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
        importlib("stdole2.tlb");
    
        // Forward declare all types defined in this typelib
        interface _Class1;
    
        [
          odl,
          uuid(54CA51B5-6F51-4970-A38D-864EDECB743E),
          version(1.0),
          hidden,
          dual,
          nonextensible,
          oleautomation,
            custom(50867B00-BB69-11D0-A8FF-00A0C9110059, "4")    
    
        ]
        interface _Class1 : IDispatch {
        };
    
        [
          uuid(6E226F97-CBE5-49FB-B11E-3BE90F4AF262),
          version(1.0),
          appobject
        ]
        coclass Class1 {
            [default] interface _Class1;
        };
    
        typedef [uuid(EBCF0FB1-C7AB-4008-96B1-66527653A83F), version(1.0)]
        struct tagudtSanityCheck1 {
            [helpstring("udtSanityCheck1")        
        ]
            [helpstring("ALongValue")
    ]
            long ALongValue;
            [helpstring("AStringValue")
    ]
            BSTR AStringValue;
            [helpstring("ABoolean")
    ]
            VARIANT_BOOL ABoolean;
        } udtSanityCheck1;
    };
    Last edited by tmighty2; Aug 18th, 2024 at 09:44 PM.

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Hi everyone,

    I'm encountering a persistent issue where an executable locks a type library (TLB) when using a certain UDT (User-Defined Type) and subroutine in VB6. After extensive troubleshooting, I've managed to create a minimal reproducible example to illustrate the problem.

    Problem Description: When I use the following udt / struct in my VB6 project, the executable locks the TLB file, necessitating its availability at runtime.

    VB6 Code:

    Code:
    Option Explicit
    
    Private Sub Form_Load()
    
        Dim n() As udtTextCountRest
        ReDim n(0)
        n(0).Text = "hi!"
    
    End Sub
    UDT Definition in IDL:
    Code:
    // typelib filename: MyTest.tlb
    [
      uuid(1F9A252A-FC23-4629-A880-581503938FD4),
      version(1.03)
    ]
    library MyTest
    {
        importlib("stdole2.tlb");
        importlib("D://Dev//Common//tlb//Implements//oleexpimp.tlb");
        typedef [public] boolean VARIANT_BOOL;
        typedef [uuid(B29A5926-4768-4134-8D6F-AB0DAC326C96), version(1.0)]
        struct udtTextCountRest
        {
            BSTR Text;
            long Count;
        } udtTextCountRest;
    };
    This issue occurs only with this particular sub and UDT defined in the TLB. I'm at a loss as to why this specific setup causes the executable to lock the TLB.

    Has anyone else experienced this or have any insights into what might be causing the TLB lock? Any help or suggestions would be greatly appreciated!
    Last edited by tmighty2; Sep 6th, 2024 at 11:18 AM.

  14. #14
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    924

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    How did you determine that the file is locked? I say this because in Windows 2000+, renaming executable files(EXE/DLL/OCX, etc) is allowed while the file is open, to allow updates. I am not sure if TLB is treated the same. If you try to rename a text file while it's open(in MS WORD, not Notepad), you can't. For EXE's, you can. I guess delete to the recycle pin is the easiest method.

    Another thing to check is Object Browser(F2), it shows what VB is seeing. Look for anything unusual, like extra underscore, etc.

  15. #15

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I have tested it manually first by renaming. I have spent over 14 days with it. I can rule out any mistake on my side when it comes to being locked or not.


    Code:
    Public Function IsFileLocked(ByVal filename As String, _
        Optional ByVal for_write As Boolean = True) As Boolean
    Const PERMISSION_DENIED As Integer = 70
    Dim fnum As Integer
    Dim err_number As Integer
    
        On Error Resume Next
        fnum = FreeFile
        If for_write Then
            Open filename For Append As #fnum
            err_number = Err.Number
        Else
            Open filename For Input As #fnum
            err_number = Err.Number
        End If
        Close #fnum
    
        On Error GoTo 0
        If err_number = 0 Then
            IsFileLocked = False
        ElseIf err_number = PERMISSION_DENIED Then
            IsFileLocked = True
        Else
            Err.Raise err_number
        End If
    End Function

  16. #16

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    ps:

    In my typelib I have hundreds of other structs.
    This one is the only one causing such a weird behaviour.

    When you test it yourself, do this:

    Compile your project, then shut down VB6 and start the exe without having VB6 running as VB6 itself also locks the tlb.

    I made myself a little app with a timer like this:

    Code:
    Private Sub Timer1_Timer()
    
        If IsFileLocked("d:\MyTest.tlb") Then
            Me.BackColor = vbRed
        Else
            Me.BackColor = vbGreen
        End If
    
    End Sub

  17. #17

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    This really baffles me.

    In my tlb I have more structs. They don't cause any locking of the tlb.

    I have also renamed the struct to

    Code:
        struct udtTextCountRest1
        {
            long TheCount;
            BSTR TheText;
        } udtTextCountRest1;
    It causes the same behaviour.

    I have also changed the order like this:

    Code:
        struct udtTextCountRest1
        {
            BSTR TheText;
            long TheCount;
    
        } udtTextCountRest1;
    Same problem.

    I have pretty complex structs in my idl normally consisting of enums, they work fine.
    Just this weird little thing does not.

  18. #18
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    924

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Quote Originally Posted by tmighty2 View Post
    I have tested it manually first by renaming. I have spent over 14 days with it. I can rule out any mistake on my side when it comes to being locked or not.


    Code:
    Public Function IsFileLocked(ByVal filename As String, _
        Optional ByVal for_write As Boolean = True) As Boolean
    I just tested your function with an XLS file open in LibreOffice Calc, I left the second parameter blank(for_write = True), and the function returns False. I tried renaming it in File Explorer(Win10 Home 64-Bit), and it showed "This action can't be completed because the file is open in LibreOffice".

    I stepped through the code and err_number is assigned 0. I changed the first Open line to the following, it showed the expected return value True, err_number = 70:

    Open filename For Binary Lock Read Write As #fnum

    Edit: You can try using Process Monitor to see what flags VB is using when calling CreateFile, to see why it was not as expected.

  19. #19
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    924

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Here is what process monitor showed for CreateFile when only Append is used, like originally posted:

    Result: SUCCESS
    Desired Access: Generic Read/Write
    Disposition: OpenIf
    Options: Synchronous IO Non-Alert, Non-Directory File
    Attributes: N
    ShareMode: Read, Write
    AllocationSize: 0
    OpenResult: Opened

    From ShareMode, it would succeed if the other process also used the same ShareMode. Using "Lock Read Write" insures exclusive access.

    Wish you luck, after all, it's Friday!

  20. #20
    Fanatic Member
    Join Date
    Feb 2019
    Posts
    924

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    When using "Lock Read Write", process monitor shows 3 CreateFile calls, all failing with "SHARING VIOLATION".

    Call 1:

    Desired Access: Generic Read/Write
    Disposition: OpenIf
    Options: Synchronous IO Non-Alert, Non-Directory File
    Attributes: N
    ShareMode: None
    AllocationSize: 0

    Call 2:

    Desired Access: Generic Write, Read Attributes
    Disposition: OpenIf
    Options: Synchronous IO Non-Alert, Non-Directory File
    Attributes: N
    ShareMode: None
    AllocationSize: 0

    Call 3:

    Desired Access: Generic Read
    Disposition: OpenIf
    Options: Synchronous IO Non-Alert, Non-Directory File
    Attributes: N
    ShareMode: None
    AllocationSize: 0

  21. #21

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I did the testing manually at first. I used this function only today for the first time.
    Before that, I tried to delete the tlb file to see if it is locked.
    The function that I mentioned to you was just a helper to me because I somewhen couldn't bare to do it by hand anymore.
    That was the first function that I found when googeling, and it reflected what I experienced when I tried to delete it manually.

  22. #22
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    Did you try removing the uuid? That turns the whole tlb into something more akin to an active-x control.

  23. #23

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    760

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I have removed them now, and I believe the problem is gone.
    Do you have any idea why?
    Each time I recreated the tbl / idl, I automatically generated new UUIDs, so I still don't know what the cause it.
    I am still scared that this might happen again.

  24. #24
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,653

    Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library

    I don't know precisely why other than what I said about it making your tlb like an activex control with registration requirements, and that of all the typelibs I've made and used, none of them have the locking problem and none of them use registered types/enums (the uuid attribute on them).

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
  •  



Click Here to Expand Forum to Full Width