如何将 Windows 任务栏从“显示”切换到“自动隐藏”(反之亦然)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1381821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:05:32  来源:igfitidea点击:

How to toggle/switch Windows taskbar from "show" to "auto-hide" (and vice-versa)?

c#windowsanimationtaskbar

提问by DinGODzilla

Basically I want to make simple toggle program (that will be mapped to some keyboard shortcut) that set taskbar to auto-hide mode if in normal mode (and conversely, to normal show mode if in auto-hide).

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

Do You know how to implement it in C#? (or Win32 C++, but anything that will actually do it is fine.)

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

Thanks. Hope I've made myself clear.

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

--

——

I don't really want any full screen app that will overlap taskbar, only windowless program that toggles show mode and quit. I switch from auto-hide to normal view on regular basis and want to simplify it. (Using Win7.)

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

--

——

edited. For example

编辑。例如

#include <windows.h>

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

will not do the trick, it only shows taskbar, which is already visible=true, but not switch it to/from auto-hide. (Same applies for 0x80.)

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

采纳答案by Anders

The taskbar is a appbar and you can control it with SHAppBarMessage

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

回答by Quispie

Here are the functions I use:

以下是我使用的功能:

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

When the code above is implemented just set the Taskbar to autohide by: SetTaskbarState(AppBarStates.AutoHide);

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

Get the current state by:

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

AppBarStates currentState = GetTaskbarState();

回答by nicruo

I followed @Quispie answer but it didn't worked at first in Windows 10, but gave me the foundation and source to solve it (so kudos) and also http://www.pinvoke.net/.

我遵循了@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);
}

回答by Eran Betzalel

Hiding the taskbar

隐藏任务栏

It's a more WIN32 API related issue than C#. You can use this(needed to be translated to dot net of course) to hide the task bar.

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

You can use http://www.pinvoke.netto translate the WIN32 API calls to dot net.

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

Set auto-hide to the taskbar

设置自动隐藏任务栏

You can achieve that by manipulating the registry using the keys that described here.

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

It should be an easy task, Good luck.

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

回答by Philip

VB "show" and "auto-hide" the Taskbar - Windows 10

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

I have translated this in VB, which might be usefull for others (Windows 10; should work in 32bit an 64bit):

我已经在 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

回答by Fabian Fippl

I maked a taskbar class from this code like this:

我从这段代码中创建了一个任务栏类,如下所示:

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

The problem is, when I'm performing

问题是,当我表演时

taskbar.SetTaskbarState(Taskbar.AppBarStates.AlwaysOnTop);

after

taskbar.SetTaskbarState(Taskbar.AppBarStates.AutoHide);

My start button is no more activated (i can't open the startmenu, clicking on it dosen't causes everything). I'm using Windows 10. Does anyone know a solution about that?

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

回答by Marjan

This is a solution that I use: 7+ Taskbar Tweaker (http://rammichael.com/7-taskbar-tweaker). Kudos to the author!

这是我使用的解决方案:7+ Taskbar Tweaker ( http://rammichael.com/7-taskbar-tweaker)。为作者点赞!

A simple free program that makes it possible to toggle task bar auto-hide in one action - assigning it to double click or middle click on empty space of the task bar OR set it yourself (see advanced options + help, right click try icon).

一个简单的免费程序,可以在一个操作中切换任务栏自动隐藏 - 将其分配为双击或中键单击任务栏的空白区域或自行设置(请参阅高级选项 + 帮助,右键单击尝试图标) .

This is essential for me as I use the task bar in vertical position and on a laptop I run out of space when I project to XVGA, which is frequent. And it was a real pain, so many clicks to toggle it.

这对我来说很重要,因为我在垂直位置使用任务栏,而在笔记本电脑上,当我投影到 XVGA 时空间不足,这很常见。这真的很痛苦,需要点击很多次才能切换它。

It's a shame Microsoft has not developed this further since the 90's. Today, I think one option would be that it behaves as the ribbon in the office programs.

遗憾的是,微软自 90 年代以来就没有进一步发展这一点。今天,我认为一种选择是将其作为办公程序中的功能区。

Cheers!

干杯!

Marjan

马里安

回答by carlosrafaelgn

For all those who arrived here from Google and are using Windows 10, like me, the answers from @Quispie and @nicruo are OK but need an extra if.

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

The reason for that is the class name differs from version to version (apparently, as I no longer have any other Windows but 10).

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

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