简体   繁体   中英

How can I determine programmatically whether the Windows taskbar is hidden or not?

I need to know whether the Windows taskbar is hidden or not. I believe there is no .NET method to do this, and also I have come across a lot of "how to hide and show the taskbar" samples, but I haven't seen anything based on what I am looking for. I am not familiar with the Windows API, so I find it hard to understand traditional Windows code. Can someone please direct me to an article or type code telling whether the current state of the taskbar is hidden or not? I am coding in C#.

Thanks.

winSharp93 presents a helper class (" Find out Size (and position) of the taskbar ") that seems to work. It uses Win32's SHAppBarMessage function .

Here's the code (with minor additions) from his blog:

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace TaskbarTest
{
    public enum TaskbarPosition
    {
        Unknown = -1,
        Left,
        Top,
        Right,
        Bottom,
    }

    public sealed class Taskbar
    {
        private const string ClassName = "Shell_TrayWnd";

        public Rectangle Bounds {
            get;
            private set;
        }
        public TaskbarPosition Position {
            get;
            private set;
        }
        public Point Location {
            get {
                return this.Bounds.Location;
            }
        }
        public Size Size {
            get {
                return this.Bounds.Size;
            }
        }
        //Always returns false under Windows 7
        public bool AlwaysOnTop {
            get;
            private set;
        }
        public bool AutoHide {
            get;
            private set;
        }

        public Taskbar() {
            IntPtr taskbarHandle = User32.FindWindow(Taskbar.ClassName, null);

            APPBARDATA data = new APPBARDATA();
            data.cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA));
            data.hWnd = taskbarHandle;
            IntPtr result = Shell32.SHAppBarMessage(ABM.GetTaskbarPos, ref data);
            if (result == IntPtr.Zero)
                throw new InvalidOperationException();

            this.Position = (TaskbarPosition)data.uEdge;
            this.Bounds = Rectangle.FromLTRB(data.rc.left, data.rc.top, data.rc.right, data.rc.bottom);

            data.cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA));
            result = Shell32.SHAppBarMessage(ABM.GetState, ref data);
            int state = result.ToInt32();
            this.AlwaysOnTop = (state & ABS.AlwaysOnTop) == ABS.AlwaysOnTop;
            this.AutoHide = (state & ABS.Autohide) == ABS.Autohide;
        }
    }

    public enum ABM : uint
    {
        New = 0x00000000,
        Remove = 0x00000001,
        QueryPos = 0x00000002,
        SetPos = 0x00000003,
        GetState = 0x00000004,
        GetTaskbarPos = 0x00000005,
        Activate = 0x00000006,
        GetAutoHideBar = 0x00000007,
        SetAutoHideBar = 0x00000008,
        WindowPosChanged = 0x00000009,
        SetState = 0x0000000A,
    }

    public enum ABE : uint
    {
        Left = 0,
        Top = 1,
        Right = 2,
        Bottom = 3
    }

    public static class ABS
    {
        public const int Autohide = 0x0000001;
        public const int AlwaysOnTop = 0x0000002;
    }

    public static class Shell32
    {
        [DllImport("shell32.dll", SetLastError = true)]
        public static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData);
    }

    public static class User32
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public uint cbSize;
        public IntPtr hWnd;
        public uint uCallbackMessage;
        public ABE uEdge;
        public RECT rc;
        public int lParam;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }
}

The author claims it works on his Windows 7 machine and it appears to work on my XP Pro machine.

Here's how you might use it:

    Taskbar tb = new Taskbar();
    Console.WriteLine("w:{0}, h:{1} - hide:{2}", tb.Size.Width, tb.Size.Height, tb.AutoHide);

Where: tb.Size.Width and tb.Size.Height returns the width and height of the Taskbar, and tb.AutoHide returns true if the Taskbar is hidden and false if it is not.

All solutions I found didn't work for me, so I had follwing idea and it works great for me.

 public static bool IsTaskbarVisible()
 {
      return Math.Abs(SystemParameters.PrimaryScreenHeight - SystemParameters.WorkArea.Height) > 0;
 }

SystemParameters.PrimaryScreenHeight returns the real display height. SystemParameters.WorkArea.Height returns the available workarea height.

If they are different, the taskbar is showing.

SystemParametersInfo with SPI_GETWORKAREA

Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates.

To get the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.

You can use IsWindowVisible Win32 function.

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWindowVisible(IntPtr hWnd);

    IntPtr hWnd = FindWindow("Shell_TrayWnd", null);
    if (hWnd != null) IsTaskBarVisible = IsWindowVisible(hWnd);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM