C#如何判断hwnd是否在托盘图标中

标签 c# winforms system-tray enumerate

我正在尝试获取当前托盘图标的 hwnd。 我所做的是使用以下代码获取系统 trat 窗口的 hWnd:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpClassName, string lpWindowName);


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


static IntPtr GetSystemTrayHandle()
{           
    IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
    if (hWndTray != IntPtr.Zero)
    {
        hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "TrayNotifyWnd", null);
        if (hWndTray != IntPtr.Zero)
        {
            hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "SysPager", null);
            if (hWndTray != IntPtr.Zero)
            {
                hWndTray = FindWindowEx(hWndTray, IntPtr.Zero, "ToolbarWindow32", null);
                return hWndTray;
            }
        }
    }

    return IntPtr.Zero;
}

我从这里拿的:Finding which applications and services are listed in the System Tray?

然后我使用以下代码枚举了该 hWnd 的子窗口:

[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
    EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
    EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
    if (listHandle.IsAllocated)
    listHandle.Free();
}
return result;
}

private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
    throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
//  You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}

public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

我从这里拿的:enumchildwindows (user32)

然后我这样使用它:

IntPtr temp = GetSystemTrayHandle();
List<IntPtr> tst = GetChildWindows(temp);
MessageBox.Show(tst.Count.ToString());
foreach (IntPtr ip in tst)
{
    MessageBox.Show(ip.ToString());
}

但是List<IntPtr> tst是空的..知道为什么吗?我做错了吗?

最佳答案

ToolbarWindow32 的“子项”不是窗口。它们是工具栏按钮。您将使用 TB_BUTTONCOUNT 消息检索按钮的数量,使用 TB_GETBUTTONINFO 消息检索有关此类按钮的信息。顺便说一句,这很难做到,因为窗口属于另一个进程,仅使用 SendMessage() 是行不通的,因为指针无效。最终是徒劳的,这样的按钮不包含任何关于与图标相关联的进程类型的信息。这是隐藏在 shell 中的信息,您无法获取它。

关于C#如何判断hwnd是否在托盘图标中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5174120/

相关文章:

c# - 一键执行两个命令

c# - Method : String. 长度的计量单位

c# - 在 C# 中执行 throbber 的最佳方法是什么?

c# - 从 HtmlAgilityPack 调用 javascript 函数

c# - 得到错误变量 <variable name> 未声明或从未分配

c++ - 我可以区分单击和双击系统托盘图标吗?

macos - 使用 QSystemTrayIcon 为 OS X 创建单色托盘图标

c# - 将 fiddler 与 Windows 身份验证结合使用

.net - 在列表linq中选择重复项

c++ - 如何在 Windows 系统托盘提示中显示一个符号?