Tray button handles in Windows 10

北城余情 提交于 2020-01-16 08:48:31

问题


I have a project that I developed about seven years ago in Win95, and works in Win7. It is developed in Visual Studio 2005. This application looks for the "You have new email" tray icon that appears in the tray (in various forms) by most email applications. I use it to blink an LED on a serial port, so I can glance in the room to see if I have email, rather than going to the computer, moving the mouse to wake the screen, and looking at the tray or the email program itself. It's a time-saver and aggravation-reducer.

It works by getting the system tray handle, and then using this handle, iterates all the buttons in the tray, and comparing the button text for a specific string. Here is the part that is having a problem in Windows 10:

        IntPtr hWndTray = GetSystemTrayHandle();
        listBoxIcons.Items.Add(string.Format("Tray handle=0x{0:X}", (int)hWndTray));

        UInt32 count = User32.SendMessage(hWndTray, TB.BUTTONCOUNT, 0, 0);
        listBoxIcons.Items.Add(string.Format("Tray button count={0:D}", count));

The call to GetSystemTrayHandle() works fine, I get a non-null value. The call to SendMessage(hWndTray, TB.BUTTONCOUNT, ...) returns zero, even though in the test case I'm using, there are nine buttons in the tray. Did the concept of "tray icons", or the API calls to get them, change in Windows 10? Here are the API calls I am using:

    [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);

From User32.cs:

internal class TB
{
    public const uint GETBUTTON       = WM.USER + 23 ;
    public const uint BUTTONCOUNT     = WM.USER + 24 ;
    public const uint CUSTOMIZE       = WM.USER + 27 ;
    public const uint GETBUTTONTEXTA  = WM.USER + 45 ;
    public const uint GETBUTTONTEXTW  = WM.USER + 75 ;
}

Here is the GetSystemTrayHandle() method:

    private 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;
    }

The "SendMessage" call has existed since about the inception of Windows, so if it no longer works, TB.BUTTONCOUNT may have been redefined or superceded in Windows 10. I cannot find any information on this.
Edit: Developed on Win98, not Win95.


回答1:


Remy's message spurred further research into notification icons. The answer was found using information at http://www.ghacks.net/2015/03/11/manage-and-display-system-tray-icons-in-windows-10/. Once notifications were enabled, for example "email" and "volume," this program, as written, can now see them.



来源:https://stackoverflow.com/questions/34102114/tray-button-handles-in-windows-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!