【问题标题】:How to toggle/switch Windows taskbar from "show" to "auto-hide" (and vice-versa)?如何切换/切换 Windows 任务栏从“显示”到“自动隐藏”(反之亦然)?
【发布时间】:2009-09-04 22:38:36
【问题描述】:

基本上,我想制作简单的切换程序(将映射到某个键盘快捷键),将任务栏设置为正常模式下的自动隐藏模式(反之,如果处于自动隐藏模式,则设置为正常显示模式)。

你知道如何在 C# 中实现它吗? (或 Win32 C++,但实际上可以做到的任何事情都可以。)

谢谢。希望我已经说清楚了。

--

我真的不想要任何与任务栏重叠的全屏应用程序,只想要切换显示模式和退出的无窗口程序。我定期从自动隐藏切换到普通视图,并想简化它。 (使用Win7。)

--

已编辑。例如

#include <windows.h>

int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    SetWindowPos(FindWindow(L"Shell_traywnd", NULL ), 0, 0, 0, 0, 0, 0x40);
}

不会做这个伎俩,它只显示任务栏,这已经是可见的=真,但不切换到/从自动隐藏。 (同样适用于 0x80。)

【问题讨论】:

    标签: c# windows animation taskbar


    【解决方案1】:

    以下是我使用的功能:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr FindWindow(string strClassName, string strWindowName);
    
    [DllImport("shell32.dll")]
    public static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);
    
    public enum AppBarMessages
    {
        New              = 0x00,
        Remove           = 0x01,
        QueryPos         = 0x02,
        SetPos           = 0x03,
        GetState         = 0x04,
        GetTaskBarPos    = 0x05,
        Activate         = 0x06,
        GetAutoHideBar   = 0x07,
        SetAutoHideBar   = 0x08,
        WindowPosChanged = 0x09,
        SetState         = 0x0a
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public UInt32 cbSize;
        public IntPtr hWnd;
        public UInt32 uCallbackMessage;
        public UInt32 uEdge;
        public Rectangle rc;
        public Int32 lParam;
    }
    
    public enum AppBarStates
    {
        AutoHide    = 0x01,
        AlwaysOnTop = 0x02
    }
    
    /// <summary>
    /// Set the Taskbar State option
    /// </summary>
    /// <param name="option">AppBarState to activate</param>
    public void SetTaskbarState(AppBarStates option)
    {
        APPBARDATA msgData = new APPBARDATA();
        msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
        msgData.hWnd = FindWindow("System_TrayWnd", null);
        msgData.lParam = (Int32)(option);
        SHAppBarMessage((UInt32)AppBarMessages.SetState, ref msgData);
    }
    
    /// <summary>
    /// Gets the current Taskbar state
    /// </summary>
    /// <returns>current Taskbar state</returns>
    public AppBarStates GetTaskbarState()
    {
        APPBARDATA msgData = new APPBARDATA();
        msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
        msgData.hWnd = FindWindow("System_TrayWnd", null);
        return (AppBarStates)SHAppBarMessage((UInt32)AppBarMessages.GetState, ref msgData);
    }
    

    实现上述代码后,只需将任务栏设置为自动隐藏:SetTaskbarState(AppBarStates.AutoHide);

    通过以下方式获取当前状态:

    AppBarStates currentState = GetTaskbarState();
    

    【讨论】:

    • 你能展示一下SetTaskbarState()GetTaskbarState()的实现吗?
    • 在答案的末尾有两个可用的示例: 当上面的代码被实现时,只需通过以下方式将任务栏设置为自动隐藏: SetTaskbarState(AppBarStates.AutoHide);获取当前状态:AppBarStates currentState = GetTaskbarState();
    • 我的意思是您的帖子中没有定义这些方法。您只显示使用情况。
    • 如果你向下滚动你会看到它们。这是完整的代码。
    • 它可以在 Windows 10 上运行,对我没有任何改变。
    【解决方案2】:

    对于所有像我一样从 Google 来到这里并使用 Windows 10 的人,@Quispie 和 @nicruo 的答案还可以,但需要额外的 if

    原因是类名因版本而异(显然,因为除了 10 之外我不再拥有任何其他 Windows)。

    msgData.hWnd = FindWindow("System_TrayWnd", null);
    if (msgData.hWnd == IntPtr.Zero)
        msgData.hWnd = FindWindow("Shell_TrayWnd", null);
    

    【讨论】:

      【解决方案3】:

      我关注了@Quispie 的回答,但它最初在 Windows 10 中不起作用,但给了我解决它的基础和资源(非常荣幸)以及http://www.pinvoke.net/

      [DllImport("user32.dll", CharSet = CharSet.Auto)]
      public static extern IntPtr FindWindow(string strClassName, string strWindowName);
      
      [DllImport("shell32.dll")]
      public static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);
      
      public enum AppBarMessages
      {
          New = 0x00,
          Remove = 0x01,
          QueryPos = 0x02,
          SetPos = 0x03,
          GetState = 0x04,
          GetTaskBarPos = 0x05,
          Activate = 0x06,
          GetAutoHideBar = 0x07,
          SetAutoHideBar = 0x08,
          WindowPosChanged = 0x09,
          SetState = 0x0a
      }
      
      [StructLayout(LayoutKind.Sequential)]
      public struct APPBARDATA
      {
          public int cbSize; // initialize this field using: Marshal.SizeOf(typeof(APPBARDATA));
          public IntPtr hWnd;
          public uint uCallbackMessage;
          public uint uEdge;
          public RECT rc;
          public int lParam;
      }
      
      [StructLayout(LayoutKind.Sequential)]
      public struct RECT
      {
          public int Left, Top, Right, Bottom;
      
          public RECT(int left, int top, int right, int bottom)
          {
              Left = left;
              Top = top;
              Right = right;
              Bottom = bottom;
          }
      
          public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }
      
          public int X
          {
              get { return Left; }
              set { Right -= (Left - value); Left = value; }
          }
      
          public int Y
          {
              get { return Top; }
              set { Bottom -= (Top - value); Top = value; }
          }
      
          public int Height
          {
              get { return Bottom - Top; }
              set { Bottom = value + Top; }
          }
      
          public int Width
          {
              get { return Right - Left; }
              set { Right = value + Left; }
          }
      
          public System.Drawing.Point Location
          {
              get { return new System.Drawing.Point(Left, Top); }
              set { X = value.X; Y = value.Y; }
          }
      
          public System.Drawing.Size Size
          {
              get { return new System.Drawing.Size(Width, Height); }
              set { Width = value.Width; Height = value.Height; }
          }
      
          public static implicit operator System.Drawing.Rectangle(RECT r)
          {
              return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
          }
      
          public static implicit operator RECT(System.Drawing.Rectangle r)
          {
              return new RECT(r);
          }
      
          public static bool operator ==(RECT r1, RECT r2)
          {
              return r1.Equals(r2);
          }
      
          public static bool operator !=(RECT r1, RECT r2)
          {
              return !r1.Equals(r2);
          }
      
          public bool Equals(RECT r)
          {
              return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
          }
      
          public override bool Equals(object obj)
          {
              if (obj is RECT)
                  return Equals((RECT)obj);
              else if (obj is System.Drawing.Rectangle)
                  return Equals(new RECT((System.Drawing.Rectangle)obj));
              return false;
          }
      
          public override int GetHashCode()
          {
              return ((System.Drawing.Rectangle)this).GetHashCode();
          }
      
          public override string ToString()
          {
              return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
          }
      }
      
      
      public enum AppBarStates
      {
          AlwaysOnTop = 0x00,
          AutoHide = 0x01
      }
      
      /// <summary>
      /// Set the Taskbar State option
      /// </summary>
      /// <param name="option">AppBarState to activate</param>
      public void SetTaskbarState(AppBarStates option)
      {
          APPBARDATA msgData = new APPBARDATA();
          msgData.cbSize = Marshal.SizeOf(msgData);
          msgData.hWnd = FindWindow("System_TrayWnd", null);
          msgData.lParam = (int)option;
          SHAppBarMessage((UInt32)AppBarMessages.SetState, ref msgData);
      }
      
      /// <summary>
      /// Gets the current Taskbar state
      /// </summary>
      /// <returns>current Taskbar state</returns>
      public AppBarStates GetTaskbarState()
      {
          APPBARDATA msgData = new APPBARDATA();
          msgData.cbSize = Marshal.SizeOf(msgData);
          msgData.hWnd = FindWindow("System_TrayWnd", null);
          return (AppBarStates)SHAppBarMessage((UInt32)AppBarMessages.GetState, ref msgData);
      }
      

      【讨论】:

      • 您好 Nicruo,感谢您更新 Windows 10。你遇到了什么问题?
      • @Quispie 我相信问题是在 Windows 10 中,类名是 "Shell_TrayWnd"(这是对我有用的类名)。我创建了一个if 来查找两者,以防万一。
      【解决方案4】:

      VB“显示”和“自动隐藏”任务栏 - Windows 10

      我已经用 VB 翻译了这个,可能对其他人有用(Windows 10;应该在 32 位和 64 位下工作):

          Option Explicit On
          Option Strict On
          Imports System.Runtime.InteropServices
      
          Module WindowsTaskbarSettings
      
          Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
          Declare Function SHAppBarMessage Lib "shell32.dll" Alias "SHAppBarMessage" (ByVal dwMessage As Integer, ByRef pData As APPBARDATA) As Integer
      
          'https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shappbarmessage
          'https://docs.microsoft.com/nl-nl/windows/win32/api/shellapi/ns-shellapi-appbardata
      
          'https://docs.microsoft.com/en-us/windows/win32/shell/abm-getstate 'requires csize to be set
          'https://docs.microsoft.com/en-us/windows/win32/shell/abm-setstate 'requires hwnd and csize to be set
      
          Structure APPBARDATA
              Dim cbSize As Integer
              Dim hwnd As Long
              Dim uCallbackMessage As Integer '[Delegate]
              Dim uEdge As Integer
              Dim rc As RECT
              Dim lParam As Integer 'message specific, see 
          End Structure
      
          Structure RECT
              Dim Left As Integer
              Dim Top As Integer
              Dim Right As Integer
              Dim Bottom As Integer
          End Structure
      
          Public Enum AppBarMessages
              Newx = &H0
              Remove = &H1
              QueryPos = &H2
              SetPos = &H3
              GetState = &H4
              GetTaskBarPos = &H5
              Activate = &H6
              GetAutoHideBar = &H7
              SetAutoHideBar = &H8
              WindowPosChanged = &H9
              SetState = &HA
          End Enum
      
          Public Enum AppBarStates
              AutoHide = &H1
              AlwaysOnTop = &H2
          End Enum
      
          Public Sub AutoHide_Toggle()
      
              If GetTaskbarStateAutoHide() Then
                  SetTaskbarState(AppBarStates.AlwaysOnTop)
              Else
                  SetTaskbarState(AppBarStates.AutoHide)
              End If
          End Sub
      
          Public Sub SetTaskbarState(StateOption As AppBarStates)
              'sets the Taskbar State to StateOption (AllwaysOnTop or AutoHide)
      
              Dim msgData As New APPBARDATA
              msgData.cbSize =  Marshal.SizeOf(msgData)
               'not necessary to use handle of Windows Taskbar, but can be found by
               'msgData.hwnd = CInt(FindWindow("Shell_TrayWnd", ""))
      
              'Set the State which will be requested
              msgData.lParam = StateOption
      
              'Ansd send the message to set this state
              SHAppBarMessage(AppBarMessages.SetState, msgData)
              'Remark on my small (1280x800) screen the desktop area remains the same, but on my larger (1080x1920) screen
              'the desktop icons are displaced when autohide is set on !!! Don't understand why (it then thinks the screen is only 800 high)
          End Sub
      
          Public Function GetTaskbarStateAutoHide() As Boolean
              'true if AutoHide is on, false otherwise
      
              Dim msgData As New APPBARDATA
              Dim ret As Integer
              msgData.cbSize =  Marshal.SizeOf(msgData)
              ' also here not necessay to find handle to Windows Taskbar
      
              ret = SHAppBarMessage(AppBarMessages.GetState, msgData)
      
              GetTaskbarStateAutoHide = CBool(ret And &H1)
          End Function
      
      End Module
      
      

      【讨论】:

        【解决方案5】:

        我用这样的代码创建了一个任务栏类:

        public class Taskbar
        {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string strClassName, string strWindowName);
        [DllImport("shell32.dll")]
        public static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);
        public enum AppBarMessages
        {
            New = 0x00,
            Remove = 0x01,
            QueryPos = 0x02,
            SetPos = 0x03,
            GetState = 0x04,
            GetTaskBarPos = 0x05,
            Activate = 0x06,
            GetAutoHideBar = 0x07,
            SetAutoHideBar = 0x08,
            WindowPosChanged = 0x09,
            SetState = 0x0a
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct APPBARDATA
        {
            public UInt32 cbSize;
            public IntPtr hWnd;
            public UInt32 uCallbackMessage;
            public UInt32 uEdge;
            public Rectangle rc;
            public Int32 lParam;
        }
        public enum AppBarStates
        {
            AutoHide = 0x01,
            AlwaysOnTop = 0x02
        }
        /// <summary>
        /// Set the Taskbar State option
        /// </summary>
        /// <param name="option">AppBarState to activate</param>
        public void SetTaskbarState(AppBarStates option)
        {
            APPBARDATA msgData = new APPBARDATA();
            msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
            msgData.hWnd = FindWindow("System_TrayWnd", null);
            msgData.lParam = (Int32)(option);
            SHAppBarMessage((UInt32)AppBarMessages.SetState, ref msgData);
        }
        /// <summary>
        /// Gets the current Taskbar state
        /// </summary>
        /// <returns>current Taskbar state</returns>
        public AppBarStates GetTaskbarState()
        {
            APPBARDATA msgData = new APPBARDATA();
            msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
            msgData.hWnd = FindWindow("System_TrayWnd", null);
            return (AppBarStates)SHAppBarMessage((UInt32)AppBarMessages.GetState, ref msgData);
        }
        }
        

        问题是,当我在表演时

        taskbar.SetTaskbarState(Taskbar.AppBarStates.AlwaysOnTop);
        

        之后

        taskbar.SetTaskbarState(Taskbar.AppBarStates.AutoHide);
        

        我的开始按钮不再被激活(我无法打开开始菜单,点击它不会导致一切)。我正在使用 Windows 10。有人知道解决方案吗?

        【讨论】:

        • 如果你把这两个命令合二为一呢? taskbar.SetTaskbarState(Taskbar.AppBarStates.AlwaysOnTop | Taskbar.AppBarStates.AutoHide);是仅按此特定顺序不起作用还是始终不起作用? Nicruo 的答案应该适用于 Windows 10。
        【解决方案6】:

        隐藏任务栏

        这是一个比 C# 更多与 WIN32 API 相关的问题。可以使用this(当然需要翻译成点网)来隐藏任务栏。

        您可以使用http://www.pinvoke.net 将 WIN32 API 调用转换为 dot net。

        设置自动隐藏到任务栏

        您可以通过使用描述here 的键来操作注册表来实现这一点。

        这应该是一件容易的事,祝你好运。

        【讨论】:

        • 那篇知识库文章不允许您切换自动隐藏
        【解决方案7】:

        任务栏是一个应用栏,你可以用SHAppBarMessage控制它

        【讨论】:

        • 文档非常神秘......一个简单的例子会很好......
        猜你喜欢
        • 1970-01-01
        • 2014-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        • 1970-01-01
        • 2017-02-18
        • 2023-03-20
        相关资源
        最近更新 更多