WPF中全屏窗口,会自动隐藏任务栏。
那非全屏窗口如何隐藏任务栏?甚至有没有一种场景,隐藏任务后自定义一套系统任务栏来显示?
以下会分阶段讲述一些概念,任务栏、查找窗口、控制窗口显示。
任务栏,其实也是一个窗口,主屏的任务栏名称是"Shell_TrayWnd"。
所以可以通过名称查找窗口,然后对窗口进行显示、隐藏操作。
以下是主屏幕任务栏的控制操作:
1 public static class ScreenTaskBar 2 { 3 private const int SwHide = 0; //隐藏窗口 4 private const int SwRestore = 9;//还原窗口 5 6 [DllImport("user32.dll")] 7 private static extern int ShowWindow(int hwnd, int nCmdShow); 8 [DllImport("user32.dll")] 9 private static extern int FindWindow(string lpClassName, string lpWindowName); 10 /// <summary> 11 /// 显示任务栏 12 /// </summary> 13 public static void Show() 14 { 15 ShowWindow(FindWindow("Shell_TrayWnd", null), SwRestore); 16 } 17 /// <summary> 18 /// 隐藏任务栏 19 /// </summary> 20 public static void Hide() 21 { 22 ShowWindow(FindWindow("Shell_TrayWnd", null), SwHide); 23 } 24 }
如果是多屏,对任务栏进行处理的场景,一般是对窗口所对应的任务栏操作。
如何获取任意窗口所在的任务栏呢?既然任务栏也是窗口,那么我们的关注点就是如何找到任务栏窗口了。
User32有EnumWindows函数,可以遍历当前电脑的所有窗口。
1 [DllImport("user32")] 2 private static extern bool EnumWindows(WndEnumProc lpEnumFunc, int lParam);
WwdEnumProc是个回调方法,返回的参数是句柄信息:
1 bool OnEnumWindow(IntPtr hWnd, int lparam) 2 { 3 //添加代码XXX 4 return true; 5 }
然后可以在回调内部添加代码,根据窗口的句柄信息,我们去拿窗口的一些信息,类名、窗口标题、窗口的Bounds(位置、大小)
1 [DllImport("user32")] 2 private static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 3 [DllImport("user32")] 4 private static extern int GetWindowText(IntPtr hWnd, StringBuilder lptrString, int nMaxCount); 5 [DllImport("user32")] 6 private static extern bool GetWindowRect(IntPtr hWnd, ref LPRECT rect);
以下是一些遍历出来的窗口信息:
所以,可以筛选出那些以TrayWnd字符串结尾的,这些都是任务栏窗口。
之后就是如何筛选出我们想要的任务栏,即窗口对应的任务栏。
窗口与任务栏,是通过屏幕关联在一起的。通过窗口获取当前屏幕信息,任务栏的Bounds如果与屏幕Bounds相交,则说明此任务栏在此屏幕内。
1 var intPtr = new WindowInteropHelper(window).Handle;//获取当前窗口的句柄 2 var screen = Screen.FromHandle(intPtr);//获取当前屏幕 3 var currentScreenBounds = screen.Bounds; 4 var taskBars = windows.Where(i => i.ClassName.Contains("TrayWnd")); 5 var currentTaskBar = taskBars.FirstOrDefault(i => i.Bounds.IntersectsWith(currentScreenBounds));
获取任务栏,也可以通过任务栏的句柄获取屏幕,与主窗口所在屏幕判断是否同一个。
获取了指定的任务栏信息后,我们就可以控制任务栏显示、隐藏了。调用下user32下函数ShowWindow即可:
1 private const int SwHide = 0; //隐藏窗口 2 private const int SwRestore = 9;//还原窗口 3 /// <summary> 4 /// 通过句柄,窗体显示函数 5 /// </summary> 6 /// <param name="hWnd">窗体句柄</param> 7 /// <param name="cmdShow">显示方式</param> 8 /// <returns>返回成功与否</returns> 9 [DllImport("user32.dll", EntryPoint = "ShowWindowAsync", SetLastError = true)] 10 public static extern bool ShowWindow(IntPtr hWnd, int cmdShow);