如何将AppBar设置为自动隐藏C#WinForm

时间:2017-06-06 12:15:09

标签: c# winforms appbar

我知道有一种方法可以将我的应用程序桌面工具栏设置为自动隐藏,但遗憾的是我不知道如何正确使用它。你能告诉我一个例子吗?我在AppBar编程C# WinForm

非常感谢

有一个代码,我用它来注册AppBar

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct APPBARDATA
    {
        public int cbSize;
        public IntPtr hWnd;
        public int uCallbackMessage;
        public int uEdge;
        public RECT rc;
        public IntPtr lParam;
    }

    private enum ABMsg : int
    {
        ABM_NEW = 0,
        ABM_REMOVE,
        ABM_QUERYPOS,
        ABM_SETPOS,
        ABM_GETSTATE,
        ABM_GETTASKBARPOS,
        ABM_ACTIVATE,
        ABM_GETAUTOHIDEBAR,
        ABM_SETAUTOHIDEBAR,
        ABM_WINDOWPOSCHANGED,
        ABM_SETSTATE
    }

    private enum ABNotify : int
    {
        ABN_STATECHANGE = 0,
        ABN_POSCHANGED,
        ABN_FULLSCREENAPP,
        ABN_WINDOWARRANGE
    }

    private enum ABEdge : int
    {
        ABE_LEFT = 0,
        ABE_TOP,
        ABE_RIGHT,
        ABE_BOTTOM
    }

    private bool isBarRegistered = false;
    private int uCallBack;

    [DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
    private static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

    [DllImport("USER32")]
    private static extern int GetSystemMetrics(int Index);

    [DllImport("User32.dll", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);

    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    private static extern int RegisterWindowMessage(string msg);

    private void RegisterBar(bool dvojty)
    {
        APPBARDATA abd = new APPBARDATA();
        abd.cbSize = Marshal.SizeOf(abd);
        abd.hWnd = this.Handle;
        if (!isBarRegistered)
        {
            if (Properties.Settings.Default.Strana.ToLower() == "ano")
            {
                this.Width = minSirka;
                this.Height = Screen.FromPoint(this.Location).WorkingArea.Height;
            }
            else
            {
                this.Width = Screen.FromPoint(this.Location).WorkingArea.Width;
                this.Height = minVyska;
            }
            uCallBack = RegisterWindowMessage("AppBarMessage");
            abd.uCallbackMessage = uCallBack;

            uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
            isBarRegistered = true;

            ABSetPos(hrana);
        }
        else
        {
            toolBar = new Rectangle(0, 0, 0, 0);
            SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref abd);
            isBarRegistered = false;
            //this.TopMost = true;

            if (dvojty)
            {
                if (Properties.Settings.Default.Strana.ToLower() == "ano")
                {
                    this.Width = minSirka;
                    this.Height = Screen.FromPoint(this.Location).WorkingArea.Height;
                }
                else
                {
                    this.Width = Screen.FromPoint(this.Location).WorkingArea.Width;
                    this.Height = minVyska;
                }
                uCallBack = RegisterWindowMessage("AppBarMessage");
                abd.uCallbackMessage = uCallBack;

                uint ret = SHAppBarMessage((int)ABMsg.ABM_NEW, ref abd);
                isBarRegistered = true;

                ABSetPos(hrana);
            }
        }
    }

    private void ABSetPos(string edge)
    {
        APPBARDATA abd = new APPBARDATA();
        //SHAppBarMessage((int)ABMsg.ABM_SETAUTOHIDEBAR, ref abd);
        abd.cbSize = Marshal.SizeOf(abd);
        abd.hWnd = this.Handle;

        if (edge == "" || edge == "top")
        {
            abd.uEdge = (int)ABEdge.ABE_TOP;
        }
        else if (edge == "right")
        {
            abd.uEdge = (int)ABEdge.ABE_RIGHT;
        }
        else if (edge == "left")
        {
            abd.uEdge = (int)ABEdge.ABE_LEFT;
        }
        else if (edge == "bottom")
        {
            abd.uEdge = (int)ABEdge.ABE_BOTTOM;
        }
        else
        {
            abd.uEdge = (int)ABEdge.ABE_TOP;
        }

        if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT)
        {
            abd.rc.top = 0;
            abd.rc.bottom = SystemInformation.PrimaryMonitorSize.Height;

            if (abd.uEdge == (int)ABEdge.ABE_LEFT)
            {
                abd.rc.left = 0;
                abd.rc.right = Size.Width;
                okraj = "left";
            }
            else
            {
                abd.rc.right = SystemInformation.PrimaryMonitorSize.Width;
                abd.rc.left = abd.rc.right - Size.Width;
                okraj = "right";
            }

        }
        else
        {
            abd.rc.left = Screen.FromControl(this).WorkingArea.Left;
            abd.rc.right = Screen.FromControl(this).WorkingArea.Right;
            if (abd.uEdge == (int)ABEdge.ABE_TOP)
            {
                abd.rc.top = Screen.FromControl(this).WorkingArea.Top;
                abd.rc.bottom = Size.Height;
                okraj = "top";  
            }
            else
            {
                abd.rc.bottom = Screen.FromControl(this).WorkingArea.Bottom;
                abd.rc.top = abd.rc.bottom - Size.Height;
                okraj = "bottom";
            }
        }

        SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd);

        switch (abd.uEdge)
        {
            case (int)ABEdge.ABE_LEFT:
                abd.rc.right = abd.rc.left + Size.Width;
                break;
            case (int)ABEdge.ABE_RIGHT:
                abd.rc.left = abd.rc.right - Size.Width;
                break;
            case (int)ABEdge.ABE_TOP:
                abd.rc.bottom = abd.rc.top + Size.Height;
                break;
            case (int)ABEdge.ABE_BOTTOM:
                abd.rc.top = abd.rc.bottom - Size.Height;
                break;
        }

        this.Top -= 1;
        SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd);
        MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top, Size.Width, Size.Height, true);
        toolBar = new Rectangle(abd.rc.left, abd.rc.top, Size.Width, Size.Height);
        left = this.Left;
        top = this.Top;
    }

2 个答案:

答案 0 :(得分:0)

<强>未测试

首先,您的SHAppBarMessage()声明应该返回IntPtr

[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

然后,根据ABM_GETAUTOHIDEBARABM_SETAUTOHIDEBAR的文档,每个屏幕边缘只能有一个带有AutoHide的AppBar。因此,在您的ABSetPos()方法中填写APPBARDATA结构(指定您将要使用的边缘)后,您可以查询系统以查看该边缘上是否已存在自动隐藏栏。如果没有返回,那么您可以注册您的appbar ......如:

IntPtr curAutoHide = SHAppBarMessage((int)ABMsg.ABM_GETAUTOHIDEBAR, ref abd);
if (curAutoHide.Equals(IntPtr.Zero)) // if there is no current appbar with autohide set for that edge...
{
    abd.lParam = new IntPtr(1); // true
    SHAppBarMessage((int)ABMsg.ABM_SETAUTOHIDEBAR, ref abd);
}

答案 1 :(得分:0)

在尝试了许多失败之后,我决定以其他方式解决自动隐藏问题。如果将appBar设置为自动隐藏,则将其注册到定义的边缘,但将其大小从该边缘更改为仅5个像素,并且其中的所有控件均设置为visible = false,并将appBar背景设置为黑色。从现在开始,我检查鼠标的位置,一旦鼠标移动到appbar,appBar将再次增长到其原始大小-但不会重新注册,仅编辑大小并将控件设置为visible = true!当鼠标离开appBar时,将尺寸设置为可见。它非常简单,经过测试,既实用又无故障。