Creating a Collection

Can you spot the fundamental problem with the CDrivesO collection as shown previously?

You might start with the performance question. Because a Collection of items operates significantly more slowly than an array of the same items, and because you don’t need most of the features of a Collection, it might seem much more efficient to save the items (such as drives) in an array rather than in a Collection. That would indeed be faster, and that’s exactly how programmers often create a collection in other languages. But you can’t do that in Visual Basic because arrays don’t have a _NewEnum method—or at least not one that you can get at. Actually, Visual Basic does create an IEnumVARIANT object for arrays when you iterate through them with For Each. But the Performance sidebar on page 218 gives you a good idea of what that does to performance.

In any case, arrays versus Collections really isn’t the problem. With either method, you have to calculate all the available items before you can return any of them. With the CDrivesO collection, that’s only 26 items. But some of those items take a long time to come through. The floppy drives at the start of the list are the slowest, and sometimes network drives are slow, too. When iterating through a drives collection, it might be nicer to display the drives one at a time as they are calculated rather than waiting until they’ve all been counted.

And of course, drives aren’t the only things you might put in a collection. Imagine a collection that includes all the files in your Windows System directory. On my system, that’s over a thousand files (most of them unknown). I wouldn’t want to process all of them before displaying the first one. In fact, that’s how the IEnumVARIANT interface is supposed to work. You’re supposed to count one at a time or, if that’s too slow, in small chunks for greater efficiency. Creating such a collection is a fundamental feature of COM, and using it is a fundamental feature of Visual Basic. So why can’t you create it in Visual Basic?

Well, you can. And we’re about to do so using a hack so gross and dangerous that I won’t even put the source code in this book. I never thought I’d encounter a trick that was actually too hardcore for Hardcore Visual Basic, but this is it. I got the technique from COM guru Matt Curland. Essentially, it consists of writing C++ in Visual Basic. In fact, some parts of it are even lower-level—more like writing a C++ compiler in Visual Basic. I’m in awe of Matt’s audacity in even thinking it would be possible to take over a COM object by copying function pointers into its vtable.

But ultimately we’re not concerned with amazing code tricks. We want to do something very simple and intuitive. We want to enumerate variants.