微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何根据任务栏的系统托盘图标的位置设置通知自定义表单的正上方或下方的位置?

如何解决如何根据任务栏的系统托盘图标的位置设置通知自定义表单的正上方或下方的位置?

c# winforms 有没有办法识别系统托盘的位置?

enter image description here

我想创建一个放置在系统托盘上方或下方的表单,具体取决于系统托盘的位置。

我计划创建一个自定义表单而不是上下文菜单,因为我需要增强 UI,但我对如何将我的表单放置在系统托盘上方/下方感到困惑。

我附上了我想象的表格位置的图片

解决方法

使用此帖子获取任务栏的坐标:

Taskbar location

static public Rectangle GetTaskbarCoordonates()
{
  var data = new NativeMethods.APPBARDATA();
  data.cbSize = Marshal.SizeOf(data);
  IntPtr retval = NativeMethods.SHAppBarMessage(NativeMethods.ABM_GETTASKBARPOS,ref data);
  if ( retval == IntPtr.Zero ) 
    throw new Win32Exception("Windows Taskbar Error in " + nameof(GetTaskbarCoordonates));
  return new Rectangle(data.rc.left,data.rc.top,data.rc.right - data.rc.left,data.rc.bottom - data.rc.top);
}

此方法将任务栏的锚点样式返回到屏幕边缘:

public const int TaskbarWidthCheckTrigger = 250;

static public AnchorStyles GetTaskbarAnchorStyle()
{
  var coordonates = GetTaskbarCoordonates();
  if ( coordonates.Left == 0 && coordonates.Top == 0 )
    if ( coordonates.Width > TaskbarWidthCheckTrigger )
      return AnchorStyles.Top;
    else
      return AnchorStyles.Left;
  else
  if ( coordonates.Width > TaskbarWidthCheckTrigger )
    return AnchorStyles.Bottom;
  else
    return AnchorStyles.Right;
}

这个值 250 是任意的,可以在特殊条件下校准或更改为更好的东西。

然后我们就可以根据上面的帖子,根据任务栏的边缘位置以及托盘图标的位置和大小,精确计算自定义工具提示通知表单的所需位置。

或者我们可以简单地确定表单的角点:

  • 顶部 => 右上角
  • 左 => 左下
  • 底部 => 右下
  • 右 => 右下

例如:

var form = new Form();
form.StartPosition = FormStartPosition.Manual;
var anchor = DisplayManager.GetTaskbarAnchorStyle();
switch ( anchor )
{
  case AnchorStyles.Top:
    form.SetLocation(ControlLocation.TopRight);
    break;
  case AnchorStyles.Left:
    form.SetLocation(ControlLocation.BottomLeft);
    break;
  case AnchorStyles.Bottom:
  case AnchorStyles.Right:
    form.SetLocation(ControlLocation.BottomRight);
    break;
}
form.Show();

有:

static public void SetLocation(this Form form,ControlLocation location)
{
  if ( form == null ) return;
  var area = SystemInformation.WorkingArea;
  switch ( location )
  {
    case ControlLocation.TopLeft:
      form.Location = new Point(area.Left,area.Top);
      break;
    case ControlLocation.TopRight:
      form.Location = new Point(area.Left + area.Width - form.Width,area.Top);
      break;
    case ControlLocation.BottomLeft:
      form.Location = new Point(area.Left,area.Top + area.Height - form.Height);
      break;
    case ControlLocation.BottomRight:
      form.Location = new Point(area.Left + area.Width - form.Width,area.Top + area.Height - form.Height);
      break;
    case ControlLocation.Center:
      form.Center(area);
      break;
    case ControlLocation.Fixed:
      form.CenterToMainFormElseScreen();
      break;
    case ControlLocation.Loose:
      break;
    default:
      throw new NotImplementedExceptionEx(location);
  }
}

然后:

[Serializable]
public enum ControlLocation
{
  Loose,TopLeft,TopRight,BottomLeft,BottomRight,Center,Fixed
}

备注:这仅适用于主屏幕,应调整以使用其他屏幕。

,

我试图查看您的参考资料,并在此基础上有了一个想法,这是修复方法:

  1. 创建notifyicon控件然后设置是点击方法调用我的表单的方法
  2. 表单将显示在鼠标位置上方,因为无论工具箱的位置如何,通知图标控件始终放置在系统托盘上。

通过鼠标位置定位表单的代码片段

 var form = new Form1();
                    form.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
                    form.SetDesktopLocation(MousePosition.X - form.Width / 2,MousePosition.Y - form.Height - 20);
                    form.Show();
                    form.Activate();
                    form.TopMost = true;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。