Introduction
I recently needed to hide the Windows taskbar and startmenu. All the code that I found on the net for this purpose did not work on Windows Vista, so I decided to write some by myself. The solution I have found works well on Windows XP, Windows Vista and Windows 7, both 32- and 64-bit.
Background
Hiding the taskbar is very easy, because its window handle can easily been found with a call to the FindWindow
WINAPI function:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
string className, string windowTitle);
IntPtr taskBarWnd = FindWindow("Shell_TrayWnd", null);
Once we know the window handle, we can hide the window using the WINAPI
function ShowWindow
. If you do this, the taskbar is hidden, but the "Start" button still remains visible. Under Windows XP (and before) this was also easy, because the "Start" button was a child window of the taskbar and its window handle can be found with a call to FindWindowEx
:
IntPtr startWnd = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start");
However, this changed with Windows Vista: If you look closely, you will see that the Vista start orb is overlapping the taskbar a little bit. The start orb is not a child window of the taskbar anymore, but a window of its own. To find the handle of this window, I proceed as follows:
First, I get the id of the process that owns the taskbar window:
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);
int procId;
GetWindowThreadProcessId(taskBarWnd, out procId);
Then I enumerate all threads of this process by using managed code. For each thread, I enumerate its windows by using the WINAPI function EnumThreadWindows
:
Process p = Process.GetProcessById(procId);
if (p != null)
{
foreach (ProcessThread t in p.Threads)
{
EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);
}
}
The EnumThreadWindows
function lets Windows call my callback function MyEnumThreadWindowsProc
for each window of the given thread. Within the callback function, I check whether the caption of each window is "Start" (which is true only for the start menu window):
private static bool MyEnumThreadWindowsProc(IntPtr hWnd, IntPtr lParam)
{
StringBuilder buffer = new StringBuilder(256);
if (GetWindowText(hWnd, buffer, buffer.Capacity) > 0)
{
if (buffer.ToString() == VistaStartMenuCaption)
{
vistaStartMenuWnd = hWnd;
return false;
}
}
return true;
}
Using the Code
I packed everything in a single static
class so you don't have to worry about WINAPI
. Just include the class Taskbar
in your application and call the static
method Hide
or Show
. That's all, really! Of course this works on Windows XP, Vista and Windows 7!
Taskbar.Hide();
History
- 2008-04-23: Version 1.0 posted
- 2008-07-16: Version 1.1 posted, sources updated so they should work also on non-English versions of Vista
- 2011-11-24: Version 1.2 posted, added an alternate way to find a window handle, solution updated to VS2010