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

8

9

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

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

--

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

Romney answered 4/9, 2009 at 22:38 Comment(0)
T
1

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

Teide answered 5/9, 2009 at 22:54 Comment(1)
The documentation is awfully cryptic... A simple example would be nice...Theresita
S
18

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

Get the current state by:

AppBarStates currentState = GetTaskbarState();
Splotch answered 3/12, 2012 at 14:18 Comment(5)
Could you show the implementations of SetTaskbarState() and GetTaskbarState()?Mistymisunderstand
At the end of the anwer are two examples available: When the code above is implemented just set the Taskbar to autohide by: SetTaskbarState(AppBarStates.AutoHide); Get the current state by: AppBarStates currentState = GetTaskbarState();Splotch
My point is that those methods are not defined in your post. You only show usage.Mistymisunderstand
If you scroll down you will see them. It is the complete code.Splotch
It works on Windows 10 without any changes for me.Nipissing
I
6

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/.

[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);
}
Ianiana answered 10/2, 2016 at 15:22 Comment(2)
Hello Nicruo, thank you for the windows 10 update. What where the problems you encountered?Splotch
@Splotch I believe the problem was that in Windows 10, the class name is "Shell_TrayWnd" (which is the class name that worked for me). I created an if to look for both, just in case.Illimitable
G
3

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.

You can use http://www.pinvoke.net to translate the WIN32 API calls to 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.

Garboard answered 4/9, 2009 at 22:46 Comment(1)
That KB article does not allow you to toggle auto-hideTeide
T
1

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

Teide answered 5/9, 2009 at 22:54 Comment(1)
The documentation is awfully cryptic... A simple example would be nice...Theresita
I
1

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.

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

msgData.hWnd = FindWindow("System_TrayWnd", null);
if (msgData.hWnd == IntPtr.Zero)
    msgData.hWnd = FindWindow("Shell_TrayWnd", null);
Illimitable answered 30/11, 2018 at 17:17 Comment(0)
F
1

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

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

    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://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shappbarmessage
    'https://learn.microsoft.com/nl-nl/windows/win32/api/shellapi/ns-shellapi-appbardata

    'https://learn.microsoft.com/en-us/windows/win32/shell/abm-getstate 'requires csize to be set
    'https://learn.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

Fungosity answered 11/5, 2020 at 15:40 Comment(0)
P
0

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?

Pothole answered 12/5, 2016 at 19:20 Comment(1)
And if you combine the two commands to one? taskbar.SetTaskbarState(Taskbar.AppBarStates.AlwaysOnTop | Taskbar.AppBarStates.AutoHide); Is it only in this specific order it won't work or is it always not working? The answer of Nicruo should work for Windows 10.Splotch
C
0

Here is a toggle example implemented in C++. Tested on Windows 11 23H2.

#include <Windows.h>
#include <WinUser.h>
#include <shellapi.h>

bool getTaskbarAutohideState()
{
    APPBARDATA msgData{};
    msgData.cbSize = sizeof(msgData);
    msgData.hWnd = FindWindow("System_TrayWnd", nullptr);
    LPARAM state = SHAppBarMessage(ABM_GETSTATE, &msgData);
    return state & ABS_AUTOHIDE;
}

void setTaskbarAutohide(bool enabled) 
{
    APPBARDATA msgData{};
    msgData.cbSize = sizeof(msgData);
    msgData.hWnd = FindWindow("System_TrayWnd", nullptr);
    msgData.lParam = enabled ? ABS_AUTOHIDE : ABS_ALWAYSONTOP;
    SHAppBarMessage(ABM_SETSTATE, &msgData);
}

void toggleTaskbarAutohide()
{
    setTaskbarAutohide(!getTaskbarAutohideState());
}

int main(int argc, char const *argv[])
{
    toggleTaskbarAutohide();

    return 0;
}

Full Github repo here to build the binary here.

Coady answered 4/11, 2023 at 15:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.