Playing with Windows 7

I was playing around with some (default Windows) programs these days and noticed that taskbar items for those programs show some cool effects whenever there is some progress going on So I decided to write a little unit to take advantage of these effects in one of my Delphi applications.

To take advantage of the new Windows 7 TaskBar API take a look at the ITaskBarList3 interface (an probably 4 for that matter). I have translated the interface to Delphi and added some initialization code and came up with a little unit that exposes a class helper for TCustomForm.

The final user-friendly code looks like this:

procedure TForm1.Button1Click(Sender: TObject);
  SetProgressValue(50, 100);

The SetProgressState and SetProgressValue methods are inserted by the class helper. The example makes the taskbar icon for the window look like a 50% complete red progress bar (indicating an error):


or something like this for a “indefinite” state (of course the animation is missing so you can’t see the effects):


If you want to play with the unit, take a look here: [download#38]


  1. Hi Alex,

    Looks nice. Maybe you can check for the Windows version instead of catching the exception?

    Kind regards,

    procedure InitializeAPI();
    Unk: IInterface;
    GlobalTaskBarInterface := nil;

    if CheckWin32Version(6) then // Interface probably supported
    { Make sure that COM is initialized }
    CoInitializeEx(nil, 0);
    { Obtain an IUnknown }
    Unk := CreateComObject(TASKBAR_CID);

    if Assigned(Unk) then
    { Cast to the required interface }
    GlobalTaskBarInterface := Unk as ITaskBarList3;

    { Initialize }
    GlobalTaskBarInterface := nil;

  2. @Bas,

    yes, the unit needs more checks of course but I just put it up in a few minutes and did not bother with it’s quality too much. I was interested in the effects 🙂


  3. @Markus, the blogs.embt.. site uses a custom feed generated by this blog. It seems to have some problems with that and is not showing up the name properly.

    BTW, my name is Ciobanu Alexandru

  4. Nice, but PLEASE will people STOP using class helpers for this kind of thing!

    You only have to google for “class helper for TCustomForm” to find that other people are using class helpers to “add” functionality to TCustomForm (and that of course isn’t going to find such helpers that people are using in their own projects but not publishing/blogging about) , and since only ONE class helper can be in scope at any time, and it is impossible to qualify multiple class helpers, you can only USE one class helper in any given “consumer” unit.

    There are other ways of doing this:

    1. Modify TCustomForm directly (difficult/tricky/not advisable),

    2. Use simple unit level procedures that take a TCustomForm parameter to operate on (put them in a class and implement as class procedures if you really have to and enjoy unnecessary typing).

    3. If you enjoy hack-ology you can even do it with a fake, member-data-less class type and hard casting.

    4. You can “spoof” a new TForm class (without having to modify VCL code) and introduce the functionality there (see my “Deltics Forms Magic” posts in my blog).

    #2 is far and away the cleanest and safest implementation, at the expense of a little extra verbosity in the API (one extra param – big deal!). #4 is a bit clever but also very safe and avoids that extra param.

    Borland/CodeGear have always said that class helpers were and are not intended for general use – they were created to solve a particular problem in the VCL.

    Maybe one day they will be usable for this sort of thing, but for that either all in-scope class helpers will have to be “merged” into a single resolvable scope, or qualification/helpcasting will need to be supported.

  5. [Off topic] @Jolyon : In the current state of Delphi, class helpers indeed have the shortcoming that only one is allowed – but what would happen if that irritation was alleviated? Then I envision class helpers would be a mighty powerful tool, giving us a taste of “Aspect Oriented” programming – except no data could yet be added…

    Regarding that last point (adding data) : Delphi 2009 and later have extended TObject with 4 extra bytes (TObject. InstanceSize returns 8 now), in which a so-called ‘Monitor’ can be stored (used for native object-level locking).
    Thorsten Engler propsed a (IMHO) small modification to this construct (he coined the word ‘ObjectExtension’), which would make it possible that any data could be added to TObject (even at runtime). This would open up the way to let ‘aspects’ add data to any class too (!)

    Sadly, I’ve heard nothing since (Allan Bauer did participate in that discussion, but never reacted to Thorsten’s proposal) – Let’s hope this improves in one of the next releases of Delphi…

    [On topic] @Alex : Nice work! I can already imaging someone will back-port this to WinXP/Vista in some form, so we can show an application-progress bar in a generic (OS-independent) fashion.

  6. @Jolyon:

    It was a simple example. It’s not like it should be used anywhere. A proper solution should be implemented, for example a normal component or related.

    See Daniel’s post about the components he’s been working on.

  7. Alex et al…. a “simple example” would have been a couple of simple unit level methods.

    Using a class helper:

    a) actually makes the example more complex (for people who haven’t come across class helpers or are using Delphi 7 or earlier)

    b) is likely to result in problems when people try to use the simple example but are already using someone-elses “simple example” using a class helper for TCustomForm and find that *this* simple example doesn’t work OR that using it breaks their previously working consumption of that other “simple example”.

    Using class helpers results in code that is less portable and intrinsically less re-usable.

    Don’t. Do . It.

    Keep “simple examples” SIMPLE!

    As for using class helpers for AO, I think AO is about more than just adding new methods and data to an existing class … it’s more about adding new behaviours to existing class behaviours.

    I don’t see that class helpers can “help” with that, no matter how they may be improved.

    To my mind class helpers are like partial classes…. something to be avoided at all costs if you wish to create a maintainable code base, rather than simply create a code base quickly.

    e.g. When curious about the behaviour of some method on a class (perhaps even just to find the in code documentation) you inspect that class’ source code only to find that the method isn’t introduced by that class or any ancestor/class part and then you have to go spelunking to find it.

    The apologists for class helpers and partial classes then wheel out the “IDE will find the declaration for you”, which is fine and dandy if you are IN the IDE at the time and the IDE is able to find it, which ime is not always the case even with less exotic code constructs/elements, especially if you are viewing the source – in the IDE – outside the context of any particular project context

    imho language features that lean on/require IDE support to be usable have to pass a higher standard of useFULness to justify their existence. Primarily – if there are less obfuscated means by which essentially the same thing may be achieved then their existence is NOT justified.

    Class helpers (outside of the their initial need, as identified by Borland at the time) do not meet that criteria – again imho.

    ditto Partial classes.

  8. @Jolyon

    Thanks, I agree that class helpers are a horrendous invention. Will try to refrain their use in the next examples 🙂

    P.S. This was the first time I have ever used class helpers.

  9. @alex – no worries. Just trying to be helpful. Class helpers are most disruptive when used in publicly shared code, is all.

    Thanks for the Windows 7 API stuff. I’m not sure I adequately conveyed how useful the actual subject of your post was, in amongst my ranting at the delivery vehicle.


  10. Great thanks for this unit! Used in my program, and it works very fine!
    But some code I needed to rewrite for compability with WindowsMediaPlayer activeX and removed Form helper, changed Handle to Application.Handle (Form1.Handle didn’t worked for me)

  11. Hey I was just wondering if the link which is for Delphi 7, Delphi 2006, Delphi 2007, and Delphi 2009, could be converted so that I can use it on my Delphi 5 or possibly C Builder 5?

    Is this possible??
    Or is there another solution on how I can achieve it?

  12. The link points to the site of the person developing the components. It’s not my work. But, you should be aware that Delphi 5 is really old and very few people would bother supporting it. Delphi 7 is usually supported because it’s still being used a lot in our days (and considered an iconic release).


  13. @alex, ok Thanks for the advice.
    As I see the .pas is available for download but if could it be possible to upload the entire project to see how it all fits together?
    Possibly in a zip?

  14. Thanks, this is very usefull!
    However, to avoid delphi 7 compiler errors, you should not use UInt64.
    When I cahenged the line below, it worked perfectly.

    procedure SetProgressValue(hwnd: THandle; ullCompleted: int64; ullTotal: int64); stdcall;

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.