Disclaimer I'm not an IDL specialist (an interface definition language that is used to define COM types) or a Microsoft IDL compiler (MIDL), but I came to the conclusions below after playing with the type library for scrrun.dll, which has a similar enumeration problem. Some of this information was obtained from a quick review of this DevX article on IDL and VB6: IDL for VB Tutorial
VB6 expects the actual enumeration to have a name, not just the enumeration that typedef 'd for the name. The name __MIDL___MIDL_itf_autosvcs_0469_0002 is a placeholder, since the original typelib did not specify the enumeration name in the same typedef where the enumeration constants are defined.
When you browse the type library in the OLE Viewer, enum probably looks like this:
typedef [public] __MIDL___MIDL_itf_autosvcs_0469_0002 LockModes; typedef enum { LockSetGet = 0, LockMethod = 1 } __MIDL___MIDL_itf_autosvcs_0469_0002;
The first typedef creates the public name LockModes as an alias for the automatically generated name MIDL___MIDL_itf_autosvcs_0469_0002 , which was assigned to enum . When the source libary type was compiled, the midl compiler generated a long __MIDL name for the source enum and automatically created an alias of typedef pointing to it.
The source IDL probably defined the enumeration as follows:
typedef enum { LockSetGet = 0, LockMethod = 1 } LockModes;
When the midl compiler processes the enum definition written in this way, it automatically generates a name for enum (since it is absent, it should appear after the enum keyword). This is the __MIDL name that you see when viewing the type library in the OLE Viewer. The midl compiler also automatically generates a second typedef , which midl typedef name for the automatically generated enum name.
The problem is that VB6 cannot understand the enum created in this way. He expects everything to be in one typedef (i.e. you will give the name enum , and also name typedef ):
typedef enum LocksMode { LockSetGet = 0, LockMethod = 1 } LocksMode;
IDL treats typedef as C or C ++ does: you do not need to specify enum as a name because typedef already has a name, but you can specify an enumeration name if you select. In other words, typedef and enum are actually two separate objects. VB6 discovers that typedef and enum are two different but vaguely related things, so in your case it sees a typedef called __MIDL___MIDL_itf_autosvcs_0469_0002 , and it sees that it is an alias of an unnamed enum, and also sees a typedef for LockModes , which is a public alias for another alias typedef .
Since the first typedef is public, you will see an entry for LockModes in the object browser, and since it is an alias for an enumeration, you will see the enumeration constants in the object browser. However, the actual enumeration does not have a name (so it gets the funky auto-generated name assigned to it in the browser), and VB6 cannot use the enumeration because the auto-generated name in VB6 is illegal (double underlined names are automatically hidden in VB6).
To demonstrate this last point, if you type it in your VB6 code, Intellisense will work and it will compile, but obviously this is not very ideal:
MsgBox COMSVCSLib.[__MIDL___MIDL_itf_autosvcs_0469_0002].LockMethod
The reason this code works is because you can put names that usually cause syntax errors (for example, names starting with an underscore) in brackets to allow VB6 to accept a normally illegal name. In addition, the prefix of constants with an auto-generated name works with Intellisense because it is the actual name that VB6 associates with enum (remember that another typedef is just an alias for this βrealβ, generated name, and VB6 apparently cannot put all the parts together so that both names refer to the same enum ).
Instead of typing the ridiculous name as described above, you can also access the enum constants, prefixing them with the library name, for example, COMSVCSLib.LockMethod should work. Itβs less clear to me why this really works, and I'm not sure what will happen if two different enum define constants with the same name.
Finally, you can fix this problem differently by using the IDL from the OLE Viewer to create a custom IDL file in which you replace the existing enum typedefs with one typedef for each enum , which simply gives both enum and typedef the same name (i.e. e. typedef enum LockModes { ... } LockModes; ), but since the OLE Viewer does not necessarily generate a valid IDL, you probably have to tweak it even more to make it actually compile. If you can make it work, you can reference to your own .tlb from your VB6 project (instead of the COMSVCSLib library COMSVCSLib ), and enum will work as you would expect from them.
If you want to go this route, you need two more tools that must be installed on your development machine (but you may need to find them):
midl.exe : this tool can generate a typelib file (* .tlb) from a .idl file. Thus, you can copy the IDL from the OLE Viewer to Notepad, change the enumeration definitions as described above, save it as an .idl file .idl and transfer it to midl.exe to create a new typelib:
midl my-custom-typelib.idl
regtlib.exe : this tool can register the .tlb file that is required if you want to add it as a link to your VB6 project:
regtlib.exe my-custom-typelib.tlb
However, creating a custom typelib for this is probably too large, and as already mentioned, it can be difficult to get a compiled IDL file based on the output from the OLE Viewer, since it displays the inverse IDL construct for the type library, rather than the original IDL.