gpt4 book ai didi

c# - .NET:如何将我的窗口放在通知区域(系统托盘)附近?

转载 作者:可可西里 更新时间:2023-11-01 09:09:39 31 4
gpt4 key购买 nike

我想在通知区域旁边显示一个小弹出窗口。它类似于 Outlook/Skype/Live! Messenger/etc 在显示有关新消息的通知时会执行此操作。在我的例子中,它将有一些输入控件(文本框、日期时间选择器、按钮......),所以一个简单的气泡是行不通的。

诀窍是在用户有多个显示器和/或任务栏不在屏幕底部时正确执行此操作。我找不到任何可以让我确定任务栏/通知区域的位置和方向的函数。

最佳答案

使用 WinAPI 调用找到任务栏位置,并根据它定位您的窗口

C# Example

class Program
{
static void Main(string[] args)
{
Taskbar taskbar = new Taskbar();
Console.WriteLine("Position: {0}, AlwaysOnTop: {1}; AutoHide: {2}; Bounds: {3}", taskbar.Position, taskbar.AlwaysOnTop, taskbar.AutoHide, taskbar.Bounds);

Console.ReadLine();
}
}

public enum TaskbarPosition
{
Unknown = -1,
Left,
Top,
Right,
Bottom,
}

public sealed class Taskbar
{
private const string ClassName = "Shell_TrayWnd";

public Rectangle Bounds
{
get;
private set;
}
public TaskbarPosition Position
{
get;
private set;
}
public Point Location
{
get
{
return this.Bounds.Location;
}
}
public Size Size
{
get
{
return this.Bounds.Size;
}
}
//Always returns false under Windows 7
public bool AlwaysOnTop
{
get;
private set;
}
public bool AutoHide
{
get;
private set;
}

public Taskbar()
{
IntPtr taskbarHandle = User32.FindWindow(Taskbar.ClassName, null);

APPBARDATA data = new APPBARDATA();
data.cbSize = (uint) Marshal.SizeOf(typeof(APPBARDATA));
data.hWnd = taskbarHandle;
IntPtr result = Shell32.SHAppBarMessage(ABM.GetTaskbarPos, ref data);
if (result == IntPtr.Zero)
throw new InvalidOperationException();

this.Position = (TaskbarPosition) data.uEdge;
this.Bounds = Rectangle.FromLTRB(data.rc.left, data.rc.top, data.rc.right, data.rc.bottom);

data.cbSize = (uint) Marshal.SizeOf(typeof(APPBARDATA));
result = Shell32.SHAppBarMessage(ABM.GetState, ref data);
int state = result.ToInt32();
this.AlwaysOnTop = (state & ABS.AlwaysOnTop) == ABS.AlwaysOnTop;
this.AutoHide = (state & ABS.Autohide) == ABS.Autohide;
}
}

public enum ABM : uint
{
New = 0x00000000,
Remove = 0x00000001,
QueryPos = 0x00000002,
SetPos = 0x00000003,
GetState = 0x00000004,
GetTaskbarPos = 0x00000005,
Activate = 0x00000006,
GetAutoHideBar = 0x00000007,
SetAutoHideBar = 0x00000008,
WindowPosChanged = 0x00000009,
SetState = 0x0000000A,
}

public enum ABE : uint
{
Left = 0,
Top = 1,
Right = 2,
Bottom = 3
}

public static class ABS
{
public const int Autohide = 0x0000001;
public const int AlwaysOnTop = 0x0000002;
}

public static class Shell32
{
[DllImport("shell32.dll", SetLastError = true)]
public static extern IntPtr SHAppBarMessage(ABM dwMessage, [In] ref APPBARDATA pData);
}

public static class User32
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}

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

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

关于c# - .NET:如何将我的窗口放在通知区域(系统托盘)附近?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2712247/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com