如何设置 AppBar 自动隐藏 C# WinForm
How to set AppBar to autohide C# WinForm
我知道有一种方法可以将我的应用程序桌面工具栏设置为自动隐藏,但遗憾的是我不知道如何正确使用它。你能给我举个例子吗?我正在 C# WinForm
编程 AppBar
。
非常感谢
有一个代码,我用它来注册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;
}
未测试
首先,您的 SHAppBarMessage()
声明应该返回 IntPtr
:
[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
然后,根据 ABM_GETAUTOHIDEBAR and ABM_SETAUTOHIDEBAR 的文档,屏幕的每个边缘只能有一个带自动隐藏功能的 AppBar。因此,在您的 ABSetPos() 方法中填写您的 APPBARDATA 结构后(指定您要使用的边缘),您可以查询系统以查看该边缘上是否已经有一个自动隐藏条。如果返回 none,那么您可以注册您的应用程序栏...类似于:
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);
}
经过多次不成功的尝试,我决定用不同的方式解决自动隐藏问题。如果我将 appBar 设置为自动隐藏,我会将其注册到定义的边缘,但将其大小从该边缘更改为仅 5 像素,并且其中的所有控件设置为 visible = false,并将 appBar 背景设置为黑色。从现在开始,我检查鼠标的位置,一旦鼠标移动到 appbar,appBar 将再次增长到其原始大小 - 但不会重新注册,仅编辑大小并将控件设置为可见 = true!当鼠标离开 appBar 时,设置控件可见的大小。非常简单,经过测试,既实用又无故障。
我知道有一种方法可以将我的应用程序桌面工具栏设置为自动隐藏,但遗憾的是我不知道如何正确使用它。你能给我举个例子吗?我正在 C# WinForm
编程 AppBar
。
非常感谢
有一个代码,我用它来注册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;
}
未测试
首先,您的 SHAppBarMessage()
声明应该返回 IntPtr
:
[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
然后,根据 ABM_GETAUTOHIDEBAR and ABM_SETAUTOHIDEBAR 的文档,屏幕的每个边缘只能有一个带自动隐藏功能的 AppBar。因此,在您的 ABSetPos() 方法中填写您的 APPBARDATA 结构后(指定您要使用的边缘),您可以查询系统以查看该边缘上是否已经有一个自动隐藏条。如果返回 none,那么您可以注册您的应用程序栏...类似于:
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);
}
经过多次不成功的尝试,我决定用不同的方式解决自动隐藏问题。如果我将 appBar 设置为自动隐藏,我会将其注册到定义的边缘,但将其大小从该边缘更改为仅 5 像素,并且其中的所有控件设置为 visible = false,并将 appBar 背景设置为黑色。从现在开始,我检查鼠标的位置,一旦鼠标移动到 appbar,appBar 将再次增长到其原始大小 - 但不会重新注册,仅编辑大小并将控件设置为可见 = true!当鼠标离开 appBar 时,设置控件可见的大小。非常简单,经过测试,既实用又无故障。