Display an overlay on the taskbar button


Today's "Little Program" displays an overlay on the taskbar button. I've seen some people call this a "badge", but "overlay" is the official term.

Start with our scratch program and make the following changes:

#include <comip.h>
#include <comdef.h>
#include <shlobj.h>
#include <shellapi.h>

_COM_SMARTPTR_TYPEDEF(ITaskbarList3, __uuidof(ITaskbarList3));

I decided to shake things up and use a different smart pointer library: com_ptr_t. (That'll teach you to complain that I don't use a smart pointer library in my samples. Now you get to complain that I use the wrong smart pointer library.)

HICON g_hicoAlert;
UINT g_wmTaskbarButtonCreated;

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
  g_hicoAlert = LoadIcon(nullptr, IDI_EXCLAMATION);
  g_wmTaskbarButtonCreated = RegisterWindowMessage(
                              TEXT("TaskbarButtonCreated"));
  return TRUE;
}

Our overlay icon is the system exclamation point icon. I chose this because I'm lazy.

bool g_fHasOverlay = false;

void UpdateOverlayIcon(HWND hwnd)
{
  HICON hicon = g_fHasOverlay ? g_hicoAlert : nullptr;
  PCWSTR pszDescription = g_fHasOverlay ?
                        L"Attention required" : nullptr;
  ITaskbarList3Ptr sptb3;
  sptb3.CreateInstance(CLSID_TaskbarList);
  sptb3->SetOverlayIcon(hwnd, hicon, pszDescription);
}

void OnChar(HWND hwnd, TCHAR ch, int cRepeat)
{
  if (ch == ' ') {
    g_fHasOverlay = !g_fHasOverlay;
    UpdateOverlayIcon(hwnd);
  }
}

    HANDLE_MSG(hwnd, WM_CHAR, OnChar);

    default:
      if (uiMsg != 0 && uiMsg == g_wmTaskbarButtonCreated) {
        UpdateOverlayIcon(hwnd);
      }
      break;

A real program would have error checking, of course.

Press the space bar, and the overlay will be toggled on and off.

If you're really clever, you might generate your overlay icons on the fly, say, if you wanted to report the number of unread messages or something.

I've heard that there's one program out there that abuses the ITaskbar­List3::Set­Progress­State method by changing its progress state repeatedly, causing its taskbar button to cycle through different colors to get the user's attention.

Just a reminder: The user interface guidelines say that the way to get the user's attention is to flash your taskbar button. Various parts of the system understand this convention and respond to it. (For example, the taskbar will temporarily unhide if a button starts flashing, and accessibility tools know how to signal the flash state to the user.) As always, the shell reserves the right to block this sort of abusive behavior in the future, just like it has done with abusive notification icons.

Comments (20)
  1. Anonymous says:

    I find it strange that someone would think that the taskbar button blinking isn't enough of an attention grabber while at the same time not forcing focus.

  2. Anonymous says:

    I bet they cycled colors because it was 'cool' and could be done, not because it was better. You remember the good old days of skinned apps, when you had to spend half an hour looking for the close button because a plain window was boring, don't you?

  3. Anonymous says:

    I've heard that there's one program out there that abuses the ITaskbar­List3::Set­Progress­State method by changing its progress state repeatedly, causing its taskbar button to cycle through different colors to get the user's attention.

    Man that could be useful. I've got a notification program (one I use not one I wrote) that changes its icon repeatedly while working but uses a constant one while idle.

    There was in Win 3.1 a backup program that minimized while running the backup to take strain off the UI. Guess how it reported its state?

    So the same thing can finally be done again.

  4. Anonymous says:

    I once wrote a little taskbar notification area program that changed its icon to a different solid color every X milliseconds; just as a proof of concept, of course.

  5. Anonymous says:

    I think the term "badge" comes from (or at least was popularized by) mobile platforms.

  6. Anonymous says:

    Possibly obvious after the fact but the overlay icon is not displayed if the taskbar appearance is set to use small icons.

    I spent way too much time trying to troubleshoot this :<. The behavior is documented.

    P.S. Long time lurker, first time poster. Fantastic blog … thank you, sir!

  7. nullptr, eh?  Using C++0x already?

    [People complain when I don't take advantage of "modern" C++ so I threw that in there to keep them happy. -Raymond]
  8. @Mark VY: Surely you mean C++11

    Since we're nitpicking: ' ' => _T(' ')

  9. Anonymous says:

    Also: Ewww. Mixing BOOL and bool. Pick one and stick with it

    (choose BOOL. I've never liked these young'uns and their 'bool's. I like my BOOLs to be neither TRUE nor FALSE. Like how they _should_ be. None of this needing to be one or the other. Excluded middle? Bah.)

    [The bool was another concession to the "modern C++" crowd. I used BOOL only when required for interop. -Raymond]
  10. Anonymous says:

    "I like my BOOLs to be neither TRUE nor FALSE."

    You mean <a href="thedailywtf.com/…/a>

  11. Anonymous says:

    > The user interface guidelines say that the way to get the user's attention is to flash your taskbar button.

    How is this supposed to work with Windows 8 MS-DOS emulation layer (I think the "modern" term is full screen application)?

    [Um, MS-DOS applications run in a window now, not full-screen, so I'm not sure what you're talking about. If you're really talking about MS-DOS applications, then the answer is that MS-DOS applications run in an emulator, and in that emulator, the MS-DOS application has exclusive control of the system. It doesn't need to get the user's attention since it already has the user's attention. There is no taskbar in the emulator because MS-DOS doesn't have a taskbar. It'd be like asking, "How does Mr. Darcy send a text message?" -Raymond]
  12. xpclient says:

    For me, the idea of taskbar overlays is cool but most apps I've seen that take advantage of it are "mostly always running in the background (startup) apps" which I would have placed in the notification area (which serves the purpose of putting background apps aside nicely besides showing notifications). Taskbar overlays should be used more by apps which are started by the user and closed when the user is done with them. For apps that I want to "keep running but put aside and out of my way" e.g. Messenger or Skype, tray is better. I bet MS telemetry tells them which apps use Taskbar overlays. Will be interesting to peek at that list. Media Player Classic – Home Cinema is one app that isn't always running and uses overlays correctly for me. So I feel overlay icons in the taskbar should not be intended to supply long-standing status or notifications. Those are best relegated to the notification area.

  13. For example, the taskbar will temporarily unhide if a button starts flashing

    This is partially broken in Windows 8 when running in high contrast mode – the taskbar will unhide, but the button won't flash, which is slightly annoying when you don't know which button caused the taskbar to unhide. Having to click every one of them to get the taskbar to hide again gets old pretty fast.

  14. [Um, MS-DOS applications run in a window now, not full-screen, so I'm not sure what you're talking about.]

    I'm pretty sure ThomasX was referring to Metro^H^H^H^HodernUI^H^H^H^H^H^H^H^HWindows Store apps.

    [I find it hard to believe that somebody would call one of those types of applications an "MS-DOS application". -Raymond]
  15. Anonymous says:

    After reading the whole article, it occurs to me that I don't think I've ever seen one of these overlays. I verified that I don't have small icons selected in the taskbar options.

    I use Win7, Excel, Word, Explorer, and VS. Am I just not trying hard enough?

    BTW, I think the "MS-DOS emulation layer" comment refers strictly to the idea of windows taking up the whole monitor, just as DOS programs did. Obviously nobody would call Metro apps "MS-DOS applications" — that term is reserved for console apps.

  16. Anonymous says:

    You might have mentioned upfront that this is a Windows 7+ feature, i.e. not useful for real software right now.

  17. Entegy says:

    @Anonymous Coward

    Seriously? Almost every app I use on a daily basis supports the taskbar button stuff (such as progress meters). Come join us in 2013 instead of 2001, technology is much better.

  18. GregM says:

    Just because a particular feature requires Windows 7 doesn't mean you can't use it.  We support Windows XP, but use the taskbar progress meter, as it is an additional capability.  The issue comes in when something is done one way on one OS version, and a different way on another OS version.  I am generally slow to adopt things like that, where the behavior of the program is different on different OSes, but when it's an additional new functionality that provides more information not available on older OSes, that's another thing.  Another example is edit fields with balloon tips or the cue banner on Windows XP and later.

  19. Anonymous says:

    > [I find it hard to believe that somebody would call one of those types of applications an "MS-DOS application". -Raymond]

    Metro applications *have* rewound the clock on User Interface design. Everyone's trying to do their own thing, just like the old days in MSDOS, before people realised convention was a good thing.

    [But who looks at a Windows Store app and says "Oh, that's an MS-DOS application"? It's one thing to call it that pejoratively; it's another to actually think that's what it is. -Raymond]
  20. I'm pretty sure ThomasX was making a sarcastic comment about how MSFT has taken a step back and is apparently moving to eliminate overlayed windows (given that the desktop APIs have been relegated to the legacy dustbin), such that each app uses the full screen – just like the old MS-DOS apps of yesteryear.  Not really sure how that's supposed to be a productivity boost…

Comments are closed.