隐藏 Windows Vista 和 Windows 7 中的任务栏和开始菜单(开始按钮)
如何在 Windows Vista 下隐藏任务栏和开始菜单(开始按钮)

引言
我最近需要隐藏 Windows 任务栏和开始菜单。我在网上找到的所有为此目的的代码在 Windows Vista 上都无法工作,所以我决定自己编写一些代码。我找到的解决方案在 Windows XP、Windows Vista 和 Windows 7 上都能很好地工作,包括 32 位和 64 位系统。
背景
隐藏任务栏非常容易,因为可以使用 FindWindow
WINAPI 函数轻松找到它的窗口句柄。
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
string className, string windowTitle);
IntPtr taskBarWnd = FindWindow("Shell_TrayWnd", null);
一旦我们知道窗口句柄,就可以使用 WINAPI
函数 ShowWindow
隐藏窗口。如果这样做,任务栏将被隐藏,但“开始”按钮仍然可见。在 Windows XP(及更早版本)下,这也很容易,因为“开始”按钮是任务栏的子窗口,可以使用 FindWindowEx
函数找到它的窗口句柄。
IntPtr startWnd = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start");
然而,Windows Vista 改变了这一点:如果你仔细观察,你会看到 Vista 开始球稍微重叠在任务栏上。开始球不再是任务栏的子窗口,而是它自己的窗口。要找到此窗口的句柄,我按如下步骤进行:
首先,我获取拥有任务栏窗口的进程的 ID。
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);
int procId;
GetWindowThreadProcessId(taskBarWnd, out procId);
然后,我使用托管代码枚举该进程的所有线程。对于每个线程,我使用 WINAPI 函数 EnumThreadWindows
枚举它的窗口。
Process p = Process.GetProcessById(procId);
if (p != null)
{
// enumerate all threads of that process...
foreach (ProcessThread t in p.Threads)
{
EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);
}
}
EnumThreadWindows
函数让 Windows 为给定线程的每个窗口调用我的回调函数 MyEnumThreadWindowsProc
。在回调函数中,我检查每个窗口的标题是否为“Start”(仅当它是开始菜单窗口时才为真)。
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
我将所有内容打包到一个 static
类中,这样你就不必担心 WINAPI
。只需将类 Taskbar
包含在你的应用程序中,并调用 static
方法 Hide
或 Show
。就这些了!当然,这适用于 Windows XP、Vista 和 Windows 7!
// hide the taskbar and startmenu
Taskbar.Hide();
历史
- 2008-04-23:发布版本 1.0
- 2008-07-16:发布版本 1.1,更新源代码,使其也能在 Vista 的非英语版本上工作
- 2011-11-24:发布版本 1.2,添加了一种查找窗口句柄的替代方法,解决方案更新到 VS2010