How do I get the taskbar's position and size?
Asked Answered
c#
A

10

34

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

Algie answered 12/8, 2009 at 5:50 Comment(3)
Try using Screen.PrimaryScreen.Bounds and Screen.PrimaryScreen.WorkingArea and subtract them. You can use AllScreens[n] instead of PrimaryScreen for multi-monitor systems.Mellicent
^ Lol actual answer's up here.Chancellor
I used: Screen.PrimaryScreen.Bounds.Right - Screen.PrimaryScreen.WorkingArea.Right for a vertical taskbar on the right side of my screen.Chancellor
D
15
    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;
    }
Daffi answered 6/9, 2011 at 18:5 Comment(1)
This does not work if the taskbar is set to auto-hide. WorkingArea and Screen.Bounds are just the same then.Shcherbakov
C
9

It's actually way more complicated than is shown above. For one thing, the task bar doesn't have to be on the primary screen, it can be dragged to any screen. For another, in theory there could be something docked on each edge of each given screen. The code above incorrectly assumes that finding something docked to one edge excludes all other edges.

The only way the location of the task bar could be definitively derived from bounds vs workingarea, would be if only one edge out of all screens had something docked to it.

The following function returns an array of Rectangles, each representing a docked task bar, and writes the count to its byref parameter. If that count is 1, element 0 of the returned array is the Rectangle occupied by the task bar. 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 is untested)

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;
}
Claim answered 22/3, 2012 at 16:13 Comment(3)
The code is in visual basic, not C#... Not so easy to copy paste now :PAce
A good surprise. Come to read yet another C# answer and find a VB.NET one I can copy. Thank you.Proletarian
I ported it to C#, testing is up to you.Claim
A
7

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

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

/******************************************************************************
 * Name:        Taskbar.cs
 * Description: Class to get the taskbar's 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's window handle.</summary>
        public static IntPtr Handle
        {
            get { return _appBarData.hWnd; }
        }

        /// <summary>Gets the taskbar's 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;
        }
    }
}
Anhedral answered 16/5, 2017 at 9:54 Comment(3)
Thanks for your answer, it's been very useful so far! It seems there is a Shell_SecondaryTrayWnd window class that is used for a second Taskbar. Potentially some other name for a 3rd. Both seem to have a MSTaskListWClass child window, so I am going to proceed in this direction. If I can get all handles of MSTaskListWClass and somehow check which monitor they are on, and if it match the monitor I am using, it might be a viable solution. EDIT: MonitorFromWindow might be the answer. I'm already using this from my main window to determine which monitor dimensions to use.Lobbyism
This solution does not work for multiple monitors. I have windows taskbar docked on Right side of each monitor of multi monitor hardware configuration. The width of each taskbar is slightly different and this solution appears to only grab the height/width of the primary monitor.Ashram
This method doesn't work with custom display scaling. Wrong width or height in DisplayBounds.Popelka
K
4
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;
}
Krongold answered 20/12, 2011 at 20:29 Comment(2)
Note that this code only works based on where the TaskBar is when the application starts. If the TaskBar is moved while the application is running, the SystemParameters.WorkArea doesn't seem to get updated accordingly. Usually this won't be an issue since people rarely move their TaskBar around, but worth noting.Liva
On my Windows 10, this solution works fine even if I move the taskbar while my app is running. Also, it works if I change the DPI setting.Giannini
M
3

This is the answer from Mark McGinty in C#.

This code brings back all of the task bars as a list of rectanges:

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

Works in every situation

It works well with:

  • Windows 7 (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;
}   
Moriah answered 29/3, 2016 at 13:13 Comment(6)
The taskbar detection utterly fails with multi-monitor multi-DPI setups. The reported taskbar positions contain a mix of device pixels and wrongly-converted logical pixels, none of them compares with the logical pixels used by WPF, so the window will happily remain on the taskbar. Mixing WPF and Windows Forms APIs is probably not a supported scenario with anything else than 96 dpi.Eastwood
It doesn't return appropriate device coords? I know for a fact that Windows forms work at alternate DPI settings, but can't speak to WPF. As you can see this code makes no attempt to convert, it's just rectangle math... I guess I'll have to try it out one of these days.Claim
Note that other apps could implement a docking task bar, older versions of Office installed one and I believe it's supported by window styles, a window class or both.Claim
My system has only one DPI setting that applies to all monitors. When I change it, the device coordinates returned by this code are unchanged. I am able to set the resolution of each monitor individually, but in that configuration the code still returns rational coordinates for all task bar positions. I know very little about WPF... does it include any coordinate conversion functions?Claim
@Mark McGinty. Good to know. If you can post a better answer which works with more scenarios, I'll upvote it :)Moriah
@Contago The following is from Microsoft.Kinect.CoordinateMapper.MapDepthFrameToColorFrame Method remarks section: "This function will then return color image coordinates that are unlikely to be useful." Interesting! I've read a mountain of tech ref over the last 30 years, that's not the sort of thing you see... often? Ever? :-) I'm waiting to learn WPF the old fashioned way (someone pays me to learn it.) Every coords scheme has to map back to device coords at the end of the day, right? (Some even include functions that claim their returns to be useful.) :-)Claim
I
2

This is a simple example 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
            }
Inductance answered 20/4, 2017 at 17:17 Comment(0)
M
2
[StructLayout(LayoutKind.Sequential)]
public struct RECT { public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; }
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA { public UInt32 cbSize; public IntPtr hWnd; public UInt32 uCallbackMessage; public UInt32 uEdge; public RECT rc; public IntPtr lParam; }
[DllImport("shell32.dll")]
public static extern IntPtr SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);

private void Form1_Load(object sender, EventArgs e)
{
    APPBARDATA msgData = new APPBARDATA();
    msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
    // get taskbar position
    SHAppBarMessage((UInt32)0x00000005, ref msgData);
    RECT taskRect = msgData.rc;
    Console.WriteLine("top:" + taskRect.top + "; left:" + taskRect.left + "; bottom:" + taskRect.bottom + "; right:" + taskRect.right);
    Console.WriteLine("width:" + (taskRect.right - taskRect.left) + "; height:" + (taskRect.bottom - taskRect.top));
}

Output: top:1040; left:0; bottom:1080; right:1920 width:1920; height:40

Misfire answered 22/11, 2020 at 13:52 Comment(0)
C
1

This is how to get the Taskbar's Height (using WPF)

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

If you want to account for 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;
Condensable answered 28/2, 2019 at 19:14 Comment(0)
M
0

I hate to say this, but one of the best and most consistent methods for setting your window size when using a WindowStyle of none is to create a temporary window that is created, maximized, Width and Height recorded, and then destroyed.

    private (double height, double width) GetVirtualWindowSize()
    {
        Window virtualWindow = new Window();
        virtualWindow.Show();
        virtualWindow.WindowState = WindowState.Maximized;
        double returnHeight = virtualWindow.Height;
        double returnWidth = virtualWindow.Width;
        virtualWindow.Close(); 

        return (returnHeight, returnWidth);
    }

You can then set the MaxHeight and MaxWidth properties of your window using the values returned within the tuple. This "sacrificial" window will use the standard window frame, and so Windows knows how to properly maximize it, thus returning accurate values every time.

You can do this at startup so that you only have to deal with the window creation once, or you can recheck the dimensions on every maximize.

I know it isn't pretty, and there is a brief flash. But it always works for me, no matter where the taskbar is, no matter the scaling, and no matter the changes that have taken place since the application started.

Mcclelland answered 6/8, 2021 at 22:44 Comment(0)
R
-1

This will work on Windows and macOS. It will also work with multiple monitors. As is, it is for electron applications, but you can easily understand what's going on.

type TaskBarPos int

const (
    UNKNOWN TaskBarPos = -1
    LEFT    TaskBarPos = 0
    RIGHT   TaskBarPos = 1
    TOP     TaskBarPos = 2
    BOTTOM  TaskBarPos = 3
)

type Rect struct {
    top    int
    bottom int
    width  int
    height int
    left   int
    right  int
}

func (r Rect) centerX() int {
    return r.left + ((r.right - r.left) / 2)
}

func (r Rect) centerY() int {
    return r.top + ((r.bottom - r.top) / 2)
}

func taskbar(tray *js.Object) TaskBarPos {

    // Step 1 - Get relevant display
    display := screen.Call("getDisplayNearestPoint", screen.Call("getCursorScreenPoint")) // Replace with primary monitor or a secondary monitor. This line as is grabs the monitor that the mouse cursor is on.

    // Step 2 - Determine taskbar bounds relative to the display
    bounds := display.Get("bounds")
    workArea := display.Get("workArea")
    var tb *Rect

    d := Rect{
        top:    bounds.Get("y").Int(),
        bottom: bounds.Get("y").Int() + bounds.Get("height").Int(),
        width:  bounds.Get("width").Int(),
        height: bounds.Get("height").Int(),
        left:   bounds.Get("x").Int(),
        right:  bounds.Get("x").Int() + bounds.Get("width").Int(),
    }

    wa := Rect{
        top:    workArea.Get("y").Int(),
        bottom: workArea.Get("y").Int() + workArea.Get("height").Int(),
        width:  workArea.Get("width").Int(),
        height: workArea.Get("height").Int(),
        left:   workArea.Get("x").Int(),
        right:  workArea.Get("x").Int() + workArea.Get("width").Int(),
    }

    if tray != nil {
        tBounds := tray.Call("getBounds")
        tb = &Rect{
            top:    tBounds.Get("y").Int(),
            bottom: tBounds.Get("y").Int() + tBounds.Get("height").Int(),
            width:  tBounds.Get("width").Int(),
            height: tBounds.Get("height").Int(),
            left:   tBounds.Get("x").Int(),
            right:  tBounds.Get("x").Int() + tBounds.Get("width").Int(),
        }
    }

    // Step 3 - Determine Position of Taskbar
    if wa.top > d.top {
        return TOP
    } else if wa.bottom < d.bottom {
        return BOTTOM
    } else if wa.left > d.left {
        return LEFT
    } else if wa.right < d.right {
        return RIGHT
    }
    if tb == nil {
        return UNKNOWN
    }

    // Check which corner tray is closest to
    if ((*tb).top - d.top) < (d.bottom - (*tb).bottom) {
        return TOP
    }
    if ((*tb).left - d.left) < (d.right - (*tb).right) {
        return LEFT
    }
    if d.bottom-(*tb).centerY() < d.right-(*tb).centerX() {
        return BOTTOM
    }
    return RIGHT
}
Rabbinate answered 27/5, 2020 at 1:50 Comment(1)
The question is ask in C#, is this snippet compiled in C#?Saffian

© 2022 - 2024 — McMap. All rights reserved.