|
-
Aug 16th, 2024, 05:22 AM
#1
Thread Starter
Fanatic Member
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!
-
Aug 16th, 2024, 06:09 AM
#2
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.
-
Aug 16th, 2024, 03:22 PM
#3
Thread Starter
Fanatic Member
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.
-
Aug 17th, 2024, 01:22 AM
#4
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.
-
Aug 17th, 2024, 02:15 AM
#5
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.
-
Aug 17th, 2024, 09:13 AM
#6
Thread Starter
Fanatic Member
Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library
Is there any other tool you would prefer over midl?
-
Aug 17th, 2024, 09:30 AM
#7
Thread Starter
Fanatic Member
Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library
Can you define "mangled names"?
-
Aug 17th, 2024, 10:00 AM
#8
Thread Starter
Fanatic Member
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.
-
Aug 17th, 2024, 06:00 PM
#9
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.
-
Aug 18th, 2024, 06:47 AM
#10
Thread Starter
Fanatic Member
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.
-
Aug 18th, 2024, 08:45 AM
#11
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.
-
Aug 18th, 2024, 09:22 PM
#12
Thread Starter
Fanatic Member
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.
-
Sep 6th, 2024, 10:53 AM
#13
Thread Starter
Fanatic Member
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.
-
Sep 6th, 2024, 11:10 AM
#14
Fanatic Member
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.
-
Sep 6th, 2024, 11:19 AM
#15
Thread Starter
Fanatic Member
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
-
Sep 6th, 2024, 11:20 AM
#16
Thread Starter
Fanatic Member
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
-
Sep 6th, 2024, 11:44 AM
#17
Thread Starter
Fanatic Member
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.
-
Sep 6th, 2024, 12:16 PM
#18
Fanatic Member
Re: Issue with Fully Qualified Enum Names in VB6 from Imported Type Library
 Originally Posted by tmighty2
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.
-
Sep 6th, 2024, 12:25 PM
#19
Fanatic Member
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!
-
Sep 6th, 2024, 12:36 PM
#20
Fanatic Member
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
-
Sep 6th, 2024, 03:35 PM
#21
Thread Starter
Fanatic Member
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.
-
Sep 6th, 2024, 07:59 PM
#22
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.
-
Sep 6th, 2024, 10:15 PM
#23
Thread Starter
Fanatic Member
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.
-
Sep 6th, 2024, 10:42 PM
#24
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|