2

好的最后一次尝试,我正在尝试解决 URL 下面详述的问题。我查看了 URL 中详细介绍的文章,但仍然无法隐藏相关图标。有人有什么想法吗?

http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons

http://social.msdn.microsoft.com/Forums/da/vbgeneral/thread/a11faa45-a3ea-4060-8de4-a6bc22e1516d

我希望能够隐藏由 Windows 语音识别加载的系统托盘图标(作为 Windows 7、Windows 8 和 Windows Vista 的一部分)。我需要在 C# 中执行此操作,并且过去几天一直在尝试 Google 解决方案,但无济于事。似乎最好的方法是使用以下代码:

//上面定义的NotifyIconData结构

private void button1_Click(object sender, EventArgs e)
{
    NOTIFYICONDATA pnid = new NOTIFYICONDATA();
    pnid.uCallbackMessage = 0x800;
    pnid.uFlags = 1;
    pnid.hwnd = ???;
    pnid.uID = 1;
    pnid.szTip = null;
    pnid.uFlags |= 2;
    pnid.hIcon = ???;
    pnid.uFlags |= 4;
    pnid.szTip = "Speech Recognition is listening";

    bool b = Shell_NotifyIcon(2, ref pnid);

Shell_NotifyIcon API 函数(2)的第一个参数是删除。问题是我不知道如何找到带有问号的参数,包括图标句柄。我尝试使用 ExtractIcon 使用窗口语音识别快捷方式指示的可执行文件和任务管理器文件位置 (%windir%\Speech\Common\sapisvr.exe -SpeechUX) 中指示的文件位置,但它告诉我可执行文件有没有关联的图标。我还使用我下载的免费应用程序验证了它,以检查具有该可执行文件的图标,它说的是同样的事情。

我可以使用以下方法获取图标托盘的窗口句柄:

    IntPtr hWnd = Win32API.FindWindow("Shell_TrayWnd", null);
    if(hWnd.ToInt32() > 0)
        {
            hWnd = Win32API.FindWindowEx(hWnd, IntPtr.Zero, "TrayNotifyWnd", null);
            if (hWnd.ToInt32() > 0)
            {
                hWnd = Win32API.FindWindowEx(hWnd,IntPtr.Zero, "SysPager", null);
                if (hWnd.ToInt32() > 0)
               {
                    hWnd = Win32API.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null);
                }                    
               // count = Win32API.SendMessage(hWnd, 1048 , 0, 0);
            }
        }

但是,即使有了句柄和图标的计数,我也不知道如何枚举图标句柄。

如果有人可以在 C# 中给我一个可行的解决方案,我很乐意支付咨询费用,就像我说你可以通过加载 Windows 7 和 Windows 8 免费提供的 Windows 语音识别来轻松尝试它,你会看到我的意思的图标。我可以使用 C++ 解决方案,但它必须完全使用托管 C++ (.NET)

4

1 回答 1

1
[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;
}

After you have the window handle, you can choose to iterate through the processes to find the ones that are in the system tray and do whatever work you need with them:

using System.Diagnostics;
Process [] processes = System.Diagnostics.Process.GetProcesses();

foreach (System.Diagnostics.Process process in processes)
{
    if (process.MainWindowHandle == hWndTray)
    {
        // ...
    }
}
于 2013-01-08T23:45:04.430 回答