Sometimes you'll find a blank taskbar button that goes away when you click on it. What's the deal with that?

There are some basic rules on which windows go into the taskbar. In short:

  • If the WS_EX_APPWINDOW extended style is set, then it will show (when visible).
  • If the window is a top-level unowned window, then it will show (when visible).
  • Otherwise it doesn't show.

(Though the ITaskbarList interface muddies this up a bit.)

When a taskbar-eligible window becomes visible, the taskbar creates a button for it. When a taskbar-eligible window becomes hidden, the taskbar removes the button.

The blank buttons appear when a window changes between taskbar-eligible and taskbar-ineligible while it is visible. Follow:

  • Window is taskbar-eligible.
  • Window becomes visible ? taskbar button created.
  • Window goes taskbar-ineligible.
  • Window becomes hidden ? since the window is not taskbar-eligible at this point, the taskbar ignores it.

Result: A taskbar button that hangs around with no window attached to it.

This is why the documentation also advises, "If you want to dynamically change a window's style to one that doesn't support visible taskbar buttons, you must hide the window first (by calling ShowWindow with SW_HIDE), change the window style, and then show the window."

Bonus question: Why doesn't the taskbar pay attention to all windows as they come and go?

Answer: Because that would be expensive. The filtering out of windows that aren't taskbar-eligible happens inside USER32 and it then notifies the taskbar (or anybody else who has installed a WH_SHELL hook) via one of the HSHELL_* notifications only if a taskbar-eligibie window has changed state. That way, the taskbar code doesn't get paged in when there's nothing for it to to.