tags:

views:

1234

answers:

2

I would like to be able to hide another application's window from the taskbar, without hiding the window itself. Specifically, I want to have several different Web browsers running, visible, available in the Alt+Tab list, but not taking up space on the taskbar.

(If anyone's curious why: I've written a dashboard app that uses Vista's DwmRegisterThumbnail APIs to show live previews of several windows at once -- a sort of "picture in picture", if you will. At that point, also having taskbar buttons for those windows seems redundant.)

I am aware that changing the other window's style to include WS_EX_TOOLWINDOW will hide it from the taskbar, and I tried this first. But, as expected, it had some side effects I didn't want: the title bar got shorter (not all bad, I guess) and the minimize and maximize buttons went away (not good). I also had to hide and re-show the window to get the taskbar to recognize the change, which caused repainting artifacts when I did it to IE windows.

My next thought was that, since windows with owners are hidden from the taskbar by default, maybe I could change the other windows to be owned by mine. But MSDN is pretty clear that "[a]fter creating an owned window, an application cannot transfer ownership of the window to another window."

I found this question that's worded similarly to mine, but it's specifically about windows from your own process, where you have complete control over window ownership.

Does anyone know of any other ways to hide a taskbar button, that will work for windows from another process?


Update: Tormod put me on the right track with ITaskbarList -- it works great. The pinvoke.net page had some errors (wrong GUID, methods declared alphabetically instead of in interface order), but I edited it, made corrections, and also added an example of how to instantiate the ITaskbarList via its coclass.

Update 2: If you use DeleteTab to hide a window's taskbar button, and then make that the active window (e.g. via SetForegroundWindow or Alt+Tab), its taskbar button will reappear. To keep the taskbar button hidden, I had to add a timer and keep calling DeleteTab. As long as you don't mind the taskbar button reappearing briefly whenever the window gets focused, this works well.

A: 

Have you tried removing WS_EX_APPWINDOW?

JP Alioto
Yes, I did. That only works if the other app had to add `WS_EX_APPWINDOW` in the first place, e.g. if it had an owner window. Ordinary top-level windows don't need `WS_EX_APPWINDOW`, so it's not there to remove.
Joe White
+2  A: 

From MSDN:

Version 4.71 and later of Shell32.dll adds the capability to modify the contents of the taskbar. From an application, you can now add, remove, and activate taskbar buttons. Activating the item does not activate the window; it shows the item as pressed on the taskbar.

The taskbar modification capabilities are implemented in a Component Object Model (COM) object (CLSID_TaskbarList) that exposes the ITaskbarList interface (IID_ITaskbarList). You must call the ITaskbarList::HrInit method to initialize the object. You can then use the methods of the ITaskbarList interface to modify the contents of the taskbar.

It seems like COM interop is the way to go to reliably manipulate the contents of the taskbar. In particular, you would need to call the following functions:

You can find the C# signature for the ITaskbarList interface at pinvoke.net: ITaskbarList.

Tormod Fjeldskår
Sweet -- I never knew about this, but it sounds like the ticket. Thanks!
Joe White