Ages ago, I happened onto Bruce McKinney’s HardCore VB and the Win.TLB file that he created and I was hooked.
Ever since, I’ve been a big fan of using typelibs with VB6. They’re relatively compact, support help, work nicely with Intellisense, and, most importantly, any elements of a typelib that your project doesn’t use, don’t get compiled into you project, unlike standard VB DECLARE statements.
Furthermore, typelibs provide just about the ONLY way to access certain COM interfaces that are normally declared with attributes that make them unusable by VB.
For examples of that, check out Edanmo’s page, or the VBAccelerator stuff.
I’ve been using Matt Curland’s Excellent PowerVB Typelib editor to edit, extend, and generally hack and bash the original win.tlb (I generally don’t use unicode much explicitly, so I haven’t kept the WINU.TLB unicode variant up to date, unfortunately). Note, though that you have to buy the book to get the editor. If you do this much, the editor alone is worth it, but the book is truly the best books on low level VB6 out there.
Doing things the Right Way
However, I really wanted to get this thing back into shape, and I felt like the best way to do that was to get it BACK into IDL format, and then use the MIDL compiler on it.
You’d think that doing so would be, basically:
- Load the TLB into OLEVIEW
- Export the whole thing as an IDL file.
- Edit the IDL with a text editor
- Run MIDL on it to recompile the WIN.TLB and presto! Nice new, clean tlb file.
Sigh. Is anything ever that simple?
Problems, Problems
First, OLEVIEW exports things in completely the wrong order (I’m not exactly sure what it uses to order things other than just the defined order in the TLB). As a result, I got tons of “symbol not defined” errors when I compiled, because a call referenced a structure that was defined later in the IDL, and didn’t have forward declaration.
Shuffling LOTS of typedefs around, I resolved all that, only to end up with tons of MIDL2022 “illegal or missing value for entry attribute”, as well as MIDL2270 “duplicate UUID” errors.
The duplicate UUID errors I fully understand, even though I really don’t like it. Basically, the TLB “redefines” a number of internal COM interfaces to make them usable by VB, for instance IEnumString.
However, MIDL doesn’t allow you to redefine an interface that already exists, and that particular interface does already exist.
In that case, commonly, you just rename your new definition to, say, IVBEnumString.
And with mktyplib and Matt’s TLB editor, that’s no problem. But MIDL see’s the old IEnumString (defined in the automatically INCLUDEd OBJIDL.IDL) and the new IVBEnumString, notices that they have the same UUID (which they must) and throws that MIDL2270 Duplicate UUID error.
Bruce resolved this by actually copying the OAIDL.IDL, OBJIDL.IDL, UNKNWN.IDL and WTYPES.IDL from the Visual Studio 6 Include dir right into his TLB project, and modified them as necessary. It works because of the MIDL search rules, but I REALLY didn’t want to continue mucking with the MS IDL files. I’d much rather just redefine those that I need to redefine and be done with it. Just seems like a safer alternative.
Ok, fine, so I go back to mktyplib and move on.
Not so fast, young Skywalker!
mktyplib is an older tool (read, unsupported, not maintained, and generally considered just that much bit junk now). And sure enough, a very common element in my type lib, it doesn’t support, namely non-variant optional parameters.
I have a line of ODL (mktyplib’s prefered input file type) like:
HRESULT _stdcall Commit([in, optional, defaultvalue(0)] STGC grfCommitFlags);
And it has no idea how to handle that OPTIONAL and I have too many of these to bother counting them all (ok, not really, there’s 64).
I really don’t want to have to make all those method parms suddenly “required” when they’re not.
The Cycle of Irritation
So, here I am, hours later, and back where I started.
I’m going to continue using the PowerVB editor to update the WIN.TLB file.
And just to recap, my version started from Bruce McKinney’s ANSI version, generally targeted at VB5, then pulls in LOTS of additional COM interfaces, ala Edanmo, VBAccelerator, and others, corrects some issues with certain calls that VB5 had no issues with but VB6 didn’t like, throws in lots of new ENUMS for parameters of functions instead of just blind LONGs where you get no Intellisense, and rounds things out with a little bit more help text for some methods (though that’s still pretty spotty).
One nasty habit of TypeLibs
One thing to be very careful of if you do start working with typelibs, is to make sure that any API function you decide to pull in and actually use will exist on the target machine.
These days, that’s not particularly hard. Win2k through Vista have changed very little as far as typical low level API’s are concerned.
At one point, my apps were running on everything from Win95 through XP, and there were definitely issues with commonly used functions existing under Win2k or XP that had no equivalent under 95 or 98. In those few cases, I just resorted to a standard VB declare and then error trapped the call. If the function wasn’t available, you’d get an error, trap it and deal with it.
However, if that same function was defined in a typelib, the app loaded will validate all implicitly linked libs and try to resolve them all at load time. If it failed for ANY function, the app won’t load at all, and all this happens before any of you VB code has a chance to do anything about it.
5 Comments
Oh man, Hardcore VB… love the book. It’s total nerdvanna for VB developers. My copy’s fuzzy from all the late-night rampaging through it.
Question about monster-ass huge typelibs: any downside to the compile/linking time? Recognizing that modern hardware usually negates the bottlenecks of a 10-year-old dev language, if I utilize really big typelibs in my project will it cause the IDE to slow down, or compile times to increase?
For more typlibby fun and all sorts of other dangerous shenanigans, check out the VBSpeed website: http://www.xbeat.net/vbspeed/index.htm
Whoa momma, some of the stuff explored there is about as safe as covering your butt with honey and humpty-dancing in front of a hive of africanized bees, but if you need that extra 5 ms edge in performance, this is the place to go.
Believe it or not, in all my surfing,I’ve never run into VBSPEED. Very cool stuff there. Thanks for the pointer.
I had to check some of my tried and true routines, most were worthy, looks like a few I’ll be throwing out!
I just wish the guys would refer to code snippets/functions/routines as just that, and not "codes", as in "check out these wicked codes". Ok, it’s minor, but it’s a bit of a pet peeve of mine.
About extreme typelibs. Never noticed any speed difference, certainly not enough to be relevant. And having them all in one place I find extremely handy.
I definitely want to check out that OPEN ODL project mentioned on VBSpeed. That might be just the ticket to getting real ODL source for my monster TLB to actually compile reasonably.
Ack. The OPEN ODL project is nothing more than just ODL files for those TLB’s… Sigh. I though it was an open source ODL/IDL compiler that might work better that MIDL.
Oh well, I’ll just keep looking for a MIDL solution and in the meantime, Curland’s EditTLB works just fine.
wOsBUj Thanks for good post