簡體   English   中英

如何根據任務欄系統托盤圖標的 position 設置通知自定義表單的位置在上方或下方?

[英]How to set the location of a notification custom form just above or below depending on the position of the system Tray Icon of the Taskbar?

有沒有辦法在 c# winforms 中識別系統托盤的 position?

在此處輸入圖像描述

我想創建一個放置在系統托盤上方或下方的表單,具體取決於系統托盤在 position 的位置。

我計划創建一個自定義表單而不是上下文菜單,因為我需要增強 UI,但我對 position 我的表單如何在系統托盤上方/下方感到困惑。

我附上了我想象我的表格將是 position 的圖像。

使用這篇文章獲取任務欄的坐標:

任務欄位置

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 是任意的,可以在特殊條件下校准或更改為更好的東西。

然后我們可以使用上面的帖子,考慮任務欄的邊緣位置以及托盤圖標的位置和大小,精確計算自定義工具提示通知表單所需的 position。

或者我們可以簡單地確定表格的角:

  • 頂部 => 右上角
  • 左 => 左下角
  • 底部 => 右下角
  • Rigth => 右下角

例如:

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 控件,然后在 click 方法上設置方法來調用我的表單
  2. 該表單將顯示在鼠標的 position 上方,因為無論工具箱的 position 可能是什么,通知圖標控件始終放置在系統托盤上。

position 的代碼片段通過鼠標 position 您的表單

 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM