How to get the position and size of the taskbar?

I want to know how to get the rectangle (bottom, top, left and right) that occupies the taskbar. How do I do this in C #?

+28
c #
Aug 12 '09 at 5:50
source share
7 answers
private enum TaskBarLocation { TOP, BOTTOM, LEFT, RIGHT} private TaskBarLocation GetTaskBarLocation() { TaskBarLocation taskBarLocation = TaskBarLocation.BOTTOM; bool taskBarOnTopOrBottom = (Screen.PrimaryScreen.WorkingArea.Width == Screen.PrimaryScreen.Bounds.Width); if (taskBarOnTopOrBottom) { if (Screen.PrimaryScreen.WorkingArea.Top > 0) taskBarLocation = TaskBarLocation.TOP; } else { if (Screen.PrimaryScreen.WorkingArea.Left > 0) { taskBarLocation = TaskBarLocation.LEFT; } else { taskBarLocation = TaskBarLocation.RIGHT; } } return taskBarLocation; } 
+10
Sep 06 '11 at 18:05
source share

This is actually much more complicated than shown above. Firstly, the taskbar does not have to be on the main screen; you can drag it to any screen. On the other hand, in theory there may be something fixed on each edge of each given screen. The above code incorrectly assumes that finding something docked to one edge excludes all other edges.

The only way that the taskbar location could finally be obtained from the borders compared to the workspace would be if only one edge of all screens was attached to it.

The following function returns an array of rectangles, each of which represents a fixed taskbar, and writes the counter to its byref parameter. If this number is 1, element 0 of the returned array is a rectangle occupied by the taskbar. If greater than 1, time to guess?

 Public Function FindDockedTaskBars(ByRef DockedRectCounter As Integer) As Rectangle() Dim TmpScrn As Screen = Nothing Dim LeftDockedWidth As Integer = 0 Dim TopDockedHeight As Integer = 0 Dim RightDockedWidth As Integer = 0 Dim BottomDockedHeight As Integer = 0 Dim DockedRects(Screen.AllScreens.Count * 4) As Rectangle DockedRectCounter = 0 For Each TmpScrn In Screen.AllScreens If Not TmpScrn.Bounds.Equals(TmpScrn.WorkingArea) Then LeftDockedWidth = Math.Abs(Math.Abs(TmpScrn.Bounds.Left) - Math.Abs(TmpScrn.WorkingArea.Left)) TopDockedHeight = Math.Abs(Math.Abs(TmpScrn.Bounds.Top) - Math.Abs(TmpScrn.WorkingArea.Top)) RightDockedWidth = (TmpScrn.Bounds.Width - LeftDockedWidth) - TmpScrn.WorkingArea.Width BottomDockedHeight = (TmpScrn.Bounds.Height - TopDockedHeight) - TmpScrn.WorkingArea.Height If LeftDockedWidth > 0 Then DockedRects(DockedRectCounter).X = TmpScrn.Bounds.Left DockedRects(DockedRectCounter).Y = TmpScrn.Bounds.Top DockedRects(DockedRectCounter).Width = LeftDockedWidth DockedRects(DockedRectCounter).Height = TmpScrn.Bounds.Height DockedRectCounter += 1 End If If RightDockedWidth > 0 Then DockedRects(DockedRectCounter).X = TmpScrn.WorkingArea.Right DockedRects(DockedRectCounter).Y = TmpScrn.Bounds.Top DockedRects(DockedRectCounter).Width = RightDockedWidth DockedRects(DockedRectCounter).Height = TmpScrn.Bounds.Height DockedRectCounter += 1 End If If TopDockedHeight > 0 Then DockedRects(DockedRectCounter).X = TmpScrn.WorkingArea.Left DockedRects(DockedRectCounter).Y = TmpScrn.Bounds.Top DockedRects(DockedRectCounter).Width = TmpScrn.WorkingArea.Width DockedRects(DockedRectCounter).Height = TopDockedHeight DockedRectCounter += 1 End If If BottomDockedHeight > 0 Then DockedRects(DockedRectCounter).X = TmpScrn.WorkingArea.Left DockedRects(DockedRectCounter).Y = TmpScrn.WorkingArea.Bottom DockedRects(DockedRectCounter).Width = TmpScrn.WorkingArea.Width DockedRects(DockedRectCounter).Height = BottomDockedHeight DockedRectCounter += 1 End If End If Next Return DockedRects End Function 

Or for those of you who prefer C # ... (Note: this ported code has not been verified)

 using System.Drawing; using System.Windows.Forms; public Rectangle[] FindDockedTaskBars(ref int DockedRectCounter) { int LeftDockedWidth = 0; int TopDockedHeight = 0; int RightDockedWidth = 0; int BottomDockedHeight = 0; Rectangle[] DockedRects = new Rectangle[Screen.AllScreens.Count() * 4]; DockedRectCounter = 0; foreach (Screen TmpScrn in Screen.AllScreens) { if (!TmpScrn.Bounds.Equals(TmpScrn.WorkingArea)) { LeftDockedWidth = Math.Abs(Math.Abs(TmpScrn.Bounds.Left) - Math.Abs(TmpScrn.WorkingArea.Left)); TopDockedHeight = Math.Abs(Math.Abs(TmpScrn.Bounds.Top) - Math.Abs(TmpScrn.WorkingArea.Top)); RightDockedWidth = (TmpScrn.Bounds.Width - LeftDockedWidth) - TmpScrn.WorkingArea.Width; BottomDockedHeight = (TmpScrn.Bounds.Height - TopDockedHeight) - TmpScrn.WorkingArea.Height; if (LeftDockedWidth > 0) { DockedRects[DockedRectCounter].X = TmpScrn.Bounds.Left; DockedRects[DockedRectCounter].Y = TmpScrn.Bounds.Top; DockedRects[DockedRectCounter].Width = LeftDockedWidth; DockedRects[DockedRectCounter].Height = TmpScrn.Bounds.Height; DockedRectCounter += 1; } if (RightDockedWidth > 0) { DockedRects[DockedRectCounter].X = TmpScrn.WorkingArea.Right; DockedRects[DockedRectCounter].Y = TmpScrn.Bounds.Top; DockedRects[DockedRectCounter].Width = RightDockedWidth; DockedRects[DockedRectCounter].Height = TmpScrn.Bounds.Height; DockedRectCounter += 1; } if (TopDockedHeight > 0) { DockedRects[DockedRectCounter].X = TmpScrn.WorkingArea.Left; DockedRects[DockedRectCounter].Y = TmpScrn.Bounds.Top; DockedRects[DockedRectCounter].Width = TmpScrn.WorkingArea.Width; DockedRects[DockedRectCounter].Height = TopDockedHeight; DockedRectCounter += 1; } if (BottomDockedHeight > 0) { DockedRects[DockedRectCounter].X = TmpScrn.WorkingArea.Left; DockedRects[DockedRectCounter].Y = TmpScrn.WorkingArea.Bottom; DockedRects[DockedRectCounter].Width = TmpScrn.WorkingArea.Width; DockedRects[DockedRectCounter].Height = BottomDockedHeight; DockedRectCounter += 1; } } } return DockedRects; } 
+6
Mar 22 '12 at 16:13
source share

Based on David's answer , here is the best implementation that uses P / Invoke to correctly determine the placement and size of the taskbar. The only limitation that I know so far is that it does not return the correct boundaries when multiple monitors are configured to display in advanced mode.

The code with all subsequent updates is available at https://git.io/v9bCx .

 /****************************************************************************** * Name: Taskbar.cs * Description: Class to get the taskbar position, size and other properties. * Author: Franz Alex Gaisie-Essilfie * based on code from https://winsharp93.wordpress.com/2009/06/29/find-out-size-and-position-of-the-taskbar/ * * Change Log: * Date | Description * -------------|-------------------------------------------------------------- * 2017-05-16 | Initial design */ using System; using System.Drawing; using System.Runtime.InteropServices; namespace System.Windows.Forms { public enum TaskbarPosition { Unknown = -1, Left, Top, Right, Bottom, } public static class Taskbar { private enum ABS { AutoHide = 0x01, AlwaysOnTop = 0x02, } ////private enum ABE : uint private enum AppBarEdge : uint { Left = 0, Top = 1, Right = 2, Bottom = 3 } ////private enum ABM : uint private enum AppBarMessage : uint { New = 0x00000000, Remove = 0x00000001, QueryPos = 0x00000002, SetPos = 0x00000003, GetState = 0x00000004, GetTaskbarPos = 0x00000005, Activate = 0x00000006, GetAutoHideBar = 0x00000007, SetAutoHideBar = 0x00000008, WindowPosChanged = 0x00000009, SetState = 0x0000000A, } private const string ClassName = "Shell_TrayWnd"; private static APPBARDATA _appBarData; /// <summary>Static initializer of the <see cref="Taskbar" /> class.</summary> static Taskbar() { _appBarData = new APPBARDATA { cbSize = (uint)Marshal.SizeOf(typeof(APPBARDATA)), hWnd = FindWindow(Taskbar.ClassName, null) }; } /// <summary> /// Gets a value indicating whether the taskbar is always on top of other windows. /// </summary> /// <value><c>true</c> if the taskbar is always on top of other windows; otherwise, <c>false</c>.</value> /// <remarks>This property always returns <c>false</c> on Windows 7 and newer.</remarks> public static bool AlwaysOnTop { get { int state = SHAppBarMessage(AppBarMessage.GetState, ref _appBarData).ToInt32(); return ((ABS)state).HasFlag(ABS.AlwaysOnTop); } } /// <summary> /// Gets a value indicating whether the taskbar is automatically hidden when inactive. /// </summary> /// <value><c>true</c> if the taskbar is set to auto-hide is enabled; otherwise, <c>false</c>.</value> public static bool AutoHide { get { int state = SHAppBarMessage(AppBarMessage.GetState, ref _appBarData).ToInt32(); return ((ABS)state).HasFlag(ABS.AutoHide); } } /// <summary>Gets the current display bounds of the taskbar.</summary> public static Rectangle CurrentBounds { get { var rect = new RECT(); if (GetWindowRect(Handle, ref rect)) return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom); return Rectangle.Empty; } } /// <summary>Gets the display bounds when the taskbar is fully visible.</summary> public static Rectangle DisplayBounds { get { if (RefreshBoundsAndPosition()) return Rectangle.FromLTRB(_appBarData.rect.Left, _appBarData.rect.Top, _appBarData.rect.Right, _appBarData.rect.Bottom); return CurrentBounds; } } /// <summary>Gets the taskbar window handle.</summary> public static IntPtr Handle { get { return _appBarData.hWnd; } } /// <summary>Gets the taskbar position on the screen.</summary> public static TaskbarPosition Position { get { if (RefreshBoundsAndPosition()) return (TaskbarPosition)_appBarData.uEdge; return TaskbarPosition.Unknown; } } /// <summary>Hides the taskbar.</summary> public static void Hide() { const int SW_HIDE = 0; ShowWindow(Handle, SW_HIDE); } /// <summary>Shows the taskbar.</summary> public static void Show() { const int SW_SHOW = 1; ShowWindow(Handle, SW_SHOW); } private static bool RefreshBoundsAndPosition() { //! SHAppBarMessage returns IntPtr.Zero **if it fails** return SHAppBarMessage(AppBarMessage.GetTaskbarPos, ref _appBarData) != IntPtr.Zero; } #region DllImports [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); [DllImport("shell32.dll", SetLastError = true)] private static extern IntPtr SHAppBarMessage(AppBarMessage dwMessage, [In] ref APPBARDATA pData); [DllImport("user32.dll")] private static extern int ShowWindow(IntPtr hwnd, int command); #endregion DllImports [StructLayout(LayoutKind.Sequential)] private struct APPBARDATA { public uint cbSize; public IntPtr hWnd; public uint uCallbackMessage; public AppBarEdge uEdge; public RECT rect; public int lParam; } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } } } 
+6
May 16 '17 at 9:54 a.m.
source share
 private enum TaskBarLocation { TOP, BOTTOM, LEFT, RIGHT } private TaskBarLocation GetTaskBarLocation() { //System.Windows.SystemParameters.... if (SystemParameters.WorkArea.Left > 0) return TaskBarLocation.LEFT; if (SystemParameters.WorkArea.Top > 0) return TaskBarLocation.TOP; if (SystemParameters.WorkArea.Left == 0 && SystemParameters.WorkArea.Width < SystemParameters.PrimaryScreenWidth) return TaskBarLocation.RIGHT; return TaskBarLocation.BOTTOM; } 
+3
Dec 20 '11 at 20:29
source share

This is a response from Mark McGinty in C #.

This code returns all taskbars to the jump list:

  • 0 rectangles means that the taskbar is hidden;
  • 1 rectangle is the position of the taskbar;
  • 2+ is very rare, which means that we have several monitors, and we do not use Extend these displays to create a single virtual desktop.

Works in every situation

It works well with:

  • Windows 7 (it will almost certainly work on Windows 8.1 and Windows 10).
  • All combinations of settings.

enter image description here

C # code

 public static List<Rectangle> FindDockedTaskBars() { List<Rectangle> dockedRects = new List<Rectangle>(); foreach (var tmpScrn in Screen.AllScreens) { if (!tmpScrn.Bounds.Equals(tmpScrn.WorkingArea)) { Rectangle rect = new Rectangle(); var leftDockedWidth = Math.Abs((Math.Abs(tmpScrn.Bounds.Left) - Math.Abs(tmpScrn.WorkingArea.Left))); var topDockedHeight = Math.Abs((Math.Abs(tmpScrn.Bounds.Top) - Math.Abs(tmpScrn.WorkingArea.Top))); var rightDockedWidth = ((tmpScrn.Bounds.Width - leftDockedWidth) - tmpScrn.WorkingArea.Width); var bottomDockedHeight = ((tmpScrn.Bounds.Height - topDockedHeight) - tmpScrn.WorkingArea.Height); if ((leftDockedWidth > 0)) { rect.X = tmpScrn.Bounds.Left; rect.Y = tmpScrn.Bounds.Top; rect.Width = leftDockedWidth; rect.Height = tmpScrn.Bounds.Height; } else if ((rightDockedWidth > 0)) { rect.X = tmpScrn.WorkingArea.Right; rect.Y = tmpScrn.Bounds.Top; rect.Width = rightDockedWidth; rect.Height = tmpScrn.Bounds.Height; } else if ((topDockedHeight > 0)) { rect.X = tmpScrn.WorkingArea.Left; rect.Y = tmpScrn.Bounds.Top; rect.Width = tmpScrn.WorkingArea.Width; rect.Height = topDockedHeight; } else if ((bottomDockedHeight > 0)) { rect.X = tmpScrn.WorkingArea.Left; rect.Y = tmpScrn.WorkingArea.Bottom; rect.Width = tmpScrn.WorkingArea.Width; rect.Height = bottomDockedHeight; } else { // Nothing found! } dockedRects.Add(rect); } } if (dockedRects.Count == 0) { // Taskbar is set to "Auto-Hide". } return dockedRects; } 
+2
Mar 29 '16 at 13:13
source share

This is a simple example of using winforms with wpf and multi screen support:

 Screen sc = Screen.FromHandle(new WindowInteropHelper(this).Handle); if (sc.WorkingArea.Top > 0) { // TASKBAR TOP } else if (sc.WorkingArea.Left != sc.Bounds.X) { // TASKBAR LEFT } else if ((sc.Bounds.Height - sc.WorkingArea.Height) > 0) { // TASKBAR BOTTOM } else if (sc.WorkingArea.Right != 0) { // TASKBAR RIGHT } else { // TASKBAR NOT FOUND } 
+1
Apr 20 '17 at 17:17
source share

This is how to get the height of the taskbar (using WPF)

 int PSBH = System.Windows.Forms.Screen.PrimaryScreen.Bounds int TaskBarHeight = PSBH - System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height; 

If you want to consider dpi

 int PSH = SystemParameters.PrimaryScreenHeight; int PSBH = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height; double ratio = PSH / PSBH; int TaskBarHeight = PSBH - System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height; TaskBarHeight *= ratio; 
0
Feb 28 '19 at 19:14
source share



All Articles