• C# 显示、隐藏窗口对应的任务栏


    WPF中全屏窗口,会自动隐藏任务栏。

    那非全屏窗口如何隐藏任务栏?甚至有没有一种场景,隐藏任务栏后自定义一套系统任务栏来显示?

    以下会分阶段讲述一些概念,任务栏、查找窗口、控制窗口显示。

    1. 主屏任务栏

    任务栏,其实也是一个窗口,主屏的任务栏名称是"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     }

    2. 多屏任务栏

    如果是多屏,对任务栏进行处理的场景,一般是对窗口所对应的任务栏操作。

    如何获取任意窗口所在的任务栏呢?既然任务栏也是窗口,那么我们的关注点就是如何找到任务栏窗口了。

    User32有EnumWindows函数,可以遍历当前电脑的所有窗口。

    1     private delegate bool EnumWindowProc(IntPtr hWnd, int lParam);
    2     [DllImport("user32")]
    3     private static extern bool EnumWindows(EnumWindowProc lpEnumFunc, int lParam);

    EnumWindowProc定义了委托的处理。添加回调方法,返回的参数是句柄信息:

    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);

     这里的ShowWindow,与上面默认任务栏操作所调用的ShowWindow不一样,句柄参数是IntPtr 

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    查看linux系统内置宏定义
    C++ typename 关键字总结
    vs2017 如何定位C++内存泄漏
    centos7.6下pyspider + python2.7安装
    centos7下安装python3.7.5
    centos7下docker安装
    centos7.6下redis安装
    centos7下git的安装
    centos7下mysql5.7的安装
    centos7下nginx,tomcaat开机启动(新)
  • 原文地址:https://www.cnblogs.com/kybs0/p/15360894.html
Copyright © 2020-2023  润新知