使用此帖子获取任务栏的坐标:
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 是任意的,可以在特殊条件下校准或更改为更好的东西。
那么我们就可以利用上面的帖子,根据任务栏的边缘位置以及托盘图标的位置和大小,精确计算自定义工具提示通知表单的期望位置。
或者我们可以简单地确定表格的角:
- 顶部 => 右上角
- 左 => 左下
- 底部 => 右下角
- 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
}
备注:这仅适用于主屏幕,它应该适应使用另一个。