首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何获取任务栏的位置和大小?

如何获取任务栏的位置和大小?
EN

Stack Overflow用户
提问于 2009-08-12 05:50:07
回答 8查看 45.3K关注 0票数 33

我想知道如何获取任务栏所占的矩形(底部、顶部、左侧和右侧)。我如何在C#中做到这一点呢?

EN

回答 8

Stack Overflow用户

发布于 2011-09-07 02:05:27

代码语言:javascript
复制
    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;
    }
票数 14
EN

Stack Overflow用户

发布于 2012-03-23 00:13:58

它实际上比上面显示的要复杂得多。首先,任务栏不必在主屏幕上,它可以拖到任何屏幕上。另一方面,从理论上讲,在每个给定屏幕的每个边缘上都可以停靠一些东西。上面的代码错误地假设,找到停靠到一条边的东西会排除所有其他边。

只有当所有屏幕中只有一条边有停靠的东西时,任务栏的位置才能从bound vs workingarea确定。

下面的函数返回一个矩形数组,每个矩形表示一个停靠的任务栏,并将计数写入其byref参数。如果计数器为1,则返回数组元素0是任务栏占用的矩形。如果大于1,那么是时候猜测了吗?

代码语言:javascript
复制
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

或者对于那些更喜欢C#的人来说...(注意:此移植的代码未经过测试)

代码语言:javascript
复制
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;
}
票数 9
EN

Stack Overflow用户

发布于 2017-05-16 17:54:37

基于David's answer,这里有一个更好的实现,它使用P/Invoke来正确确定任务栏的位置和大小。到目前为止,我所知道的唯一限制是,当多个监视器被设置为以扩展模式显示时,它不会返回正确的边界。

包含所有后续更新的代码可在https://git.io/v9bCx上作为要点获得。

代码语言:javascript
复制
/******************************************************************************
 * 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;
        }
    }
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1264406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档