Introduction
When VB5 initially arrived, the AddressOf keyword caused great excitement (we're an exciting
lot, us VB coders). Not only could you finally start implementing features such as
Subclassing and Enumeration callbacks
but also it raised the possibility of using Win32's threading features. Excellent - truly hardcore VB!
Despite the fact that the original VB5 release was not
thread-safe and therefore there were no guarantees as to what would and wouldn't work on a separate
thread, programmers jumped in and had a try. There was even a multi-threaded debugger written in VB,
published over two issues of MSJ - an amazingly feat and something
to mention to those smug VC++ coders when they said that VB was a programming language only for monkeys
and you couldn't do anything serious with it (such as spend 3 days trying to find the missing '*')
All of this fun coding suddenly stopped working when VB5 Service Pack 2 was released.
VB5 Service Pack 2
SP2 addressed a serious design error in VB's control creation abilities, namely that it could not create
threaded controls. This meant that if you hosted VB authored controls in a package that created multiple
threads, and that package hosted a control on more than one thread, those threads would block each other.
This situation can be seen if you create an Internet Explorer page with two frames and host a single-threaded
VB control in each frame.
VB solved this problem by introducing Appartment Model threading. Now a multi-threaded app could create
controls on its own threads. However, VB's developers didn't do this for the convenience of hacker
developers who liked to use the CreateThread function. The way VB's developers implemented
multi-threading was by use of a mechanism called Thread Local Storage (TLS). The implementation meant
that if you created a new thread using the API virtually no VB functions were available to run on it
until you managed to create an object on that thread. But with no VB functions, how do you create the
thread?
VB6
VB6 made things even worse. In VB6 the only VB function which works before TLS is initialised is the
Beep function. Whilst I may not like all of VB's functionality, coding with only the Beep
function is really a bit too restrictive, although of course it does allow the possibility of
an entirely asynchronous audible-feedback error-reporting DLL for machines with no soundcards.
The fix
Some 2 years on from VB5 Service Pack 2, there is finally a way to create multiple threads in-process from a
DLL. This is thanks to an article by Matthew Curland, one of the developers on Microsoft's Visual
Basic team, which described in some detail how to do it. The article is published in the June 1999 issue
of VBPJ which I highly recommend you beg, borrow or steal a subscription
to! Matthew Curland was also responsible for the code and algorithms behind the IOLEInPlaceActiveObject
tab-trapping mechanism for controls created using the API, applied liberally throughout this site.
|