Monday, September 04, 2006
Please excuse me as I geek out.
Because Microsoft left it up to the Visual Basic programmers (ugh) to come up with this object, they chose to base it upon an IDispatch. In other words, the VTable for our object must start with the three IUnknown functions as all COM objects do (QueryInterface, AddRef, and Release), and then must be followed immediately with the four standard IDispatch functions (GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, and Invoke). Our object must then have three more functions. In our IDL file, when we define the VTable (i.e., the interface) for this object we'll create, we must name these three extra functions Count, Item, and _NewEnum. In our actual VTable for the object, we can use any name we want for the pointers (although I'll stick to those names). Why? Because no one is ever going to directly call them. No one will ever even know that we're going to add these three functions to our VTable. These functions must be called only indirectly via the Invoke function of our object -- even if you're using a language like C that could have called them directly if only Microsoft's Visual Basic programmers had designed this to accommodate more powerful languages. That's the terrible price we all pay for letting Visual Basic programmers design this. Furthermore, in our IDL file, we must assign the ID DISPID_VALUE to the Item function, and DISPID_NEWENUM to the _NewEnum function. We must. The Count function can be assigned any positive number of our choosing for its ID. Does there appear to be any sense of consistency or logic to this whatsoever? No? Remember -- Visual Basic programmers.