The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
1 ActiveX Controls &nbsp

Free-Threaded In-Progress Indicators

Animated In-Progess Indicators which Don't Stop just because VB does

InProgress Component

One thing that occurs time and time again in applications is the need to show the user that something is happening whilst performing a long operation. Sometimes you know how many steps there are in the operation, in which case you can use a ProgressBar to show to the user how much has been processed and how much there is left.

However, often you don't know. For these cases you want to show an In-Progress indicator - something that runs in a loop whilst work is being done. Both Internet Explorer and Navigator make a big feature of this technique with a logo in the top-left corner of their apps. Whilst it would be nice to do this in your own app, there are two problems. The first is that suitable graphics are hard to come by and can be huge. Building multi-frame animations like the IE animated logo is not something to be undertaken lightly! The second is that the only control provided with VB to do this is the COMCTL32.DLL Animation control. This only accepts AVI files, a format which is not widely available and has no (AFAIK) good freeware tools for creating the files.

The two In-Progress indicators here help solve these problems by providing simple animations, the first being a Netscape/Knight-Rider style and the second using widely available Animated Cursors.

And if you're a hardcore VB coder, perhaps the more interesting thing to note is that just like the animation control both these samples are free-threaded, meaning they run even when VB is blocked.

Free-Threading in VB
Free-threading was widely believed to be impossible to do in VB. You can read a little about the issues and history of the problem in the article A History Of In-Process Threading in VB. In fact there are some midgets who still believe that to be the case today and should be forced to relinquish control of Bruce McKinney's previously excellent Win.TLB at gunpoint if possible.

Luckily for us Matthew Currland showed how to do it in VBPJ article. The downside is that to get a free-threaded app up and running isn't easy. For a start, it is impossible to debug your application in VB: to create your class on a new thread the code must use the CoCreateInstance COM function to get an instance of your class, and whilst you are running in the IDE VB messes around with ProgIDs and CLSIDs preventing this from succeeding.

Programming Model
Multi-threaded code in general is very tricky. Throughout you need to consider things like re-entrancy (where the same procedure is entered again whilst it is already executing from a prior call). The programming model for Matthew Currland's multi-threading library allows you to avoid worries about this, at the cost of a loss of flexibility and ease of use.

In this model, you can create a class on a new thread using the ProgID for the class. There is only one chance to communicate with the class: when it is started. You initialise the class through an implemented interface ThreadLaunch which only has one method: Go. It is possible to pass one variant in as a parameter. Normally the thread terminates when the IThreadLaunch_Go method completes. The only other control you have once the ThreadLaunch_Go method has been called is that you should write the thread to poll on a shared variable m_Notify. When the owner of the thread wants to terminate, it sets m_Notify to True, and the next time the code in IThreadLaunch_Go polls the value it should exit.

The Good, The Bad and The Out-of-Control
As you can see, this is not the usual way to code with objects in VB! Basically what it means is that apart from stopping the thread there is a one shot chance of communicating information from the owner to the thread.

However, there are distinct stability advantages to this programming model. The main one is you do not need to consider re-entrancy or other thread-related problems in your free-threaded class - because they simply cannot happen! All the places where there might be re-entrancy are already covered by Matthew Currland's code.

It does leave the issue of how to communicate between the threaded class and your code though. I have used a Window as the communication method in my examples. The variant data passed in to the thread is a window handle. All other variables which need to be passed between the caller and the free-threaded class are then obtained via the window handle; in the case of this code I have used the Windows Properties database (GetProp,SetProp and RemoveProp API calls) but you could likewise consider using subclassing and posting messages backwards and forwards between the windows.

My implementations of the free-threaded classes include at least two public classes:
  • A control object
    This is the object which the client of the object will use to manipulate the properties and to start and stop the thread.
  • A thread object
    This is the object which implements the ThreadLaunch_Go method. Since this cannot be directly referenced by the client, this normally would be set to private. However, to make the threading code work correctly this object must be accessible to the CoCreateInstance call, which requires that the object is entered in the registry and is therefore public.
    I name this object after the control object but with Thread added to the end.
Because the thread object is exposed publically, it is possible to try out the methods by creating an instance of the thread object in a design object. With a little work you should be able to create an object where you can completely test it out at design time.

The other obvious debugging technique for cases like this is to use conditional compilation constants to include MsgBox calls. This method is ok to a limited degree but in general it reminds you why languages with no integrated debugger either get one (JavaScript, VC++ 6 etc) or stop getting used!

Try the Code

TopBack to top
Source Code - What We're About!Back to ActiveX Control Source Code
Source Code - What We're About!Back to Source Code


AboutContributeSend FeedbackPrivacy

Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
Last updated: 15 November 1999