コード例 #1
0
        private SafeNotifyIconData GetTrayItemIconData(TrayItem trayItem)
        {
            SafeNotifyIconData nid = new SafeNotifyIconData();

            nid.hWnd             = trayItem.hWnd;
            nid.uID              = trayItem.uID;
            nid.uCallbackMessage = trayItem.uCallbackMessage;
            nid.szTip            = trayItem.szIconText;
            nid.hIcon            = trayItem.hIcon;
            nid.uVersion         = trayItem.uVersion;
            nid.guidItem         = trayItem.guidItem;
            nid.dwState          = (int)trayItem.dwState;
            nid.uFlags           = NIF.GUID | NIF.MESSAGE | NIF.TIP | NIF.STATE;

            if (nid.hIcon != IntPtr.Zero)
            {
                nid.uFlags |= NIF.ICON;
            }
            else
            {
                ShellLogger.Warning($"ExplorerTrayService: Unable to use {trayItem.szIconText} icon handle for NOTIFYICONDATA struct");
            }

            return(nid);
        }
コード例 #2
0
        public NotificationBalloon(SafeNotifyIconData nicData, NotifyIcon notifyIcon)
        {
            NotifyIcon = notifyIcon;

            Title    = nicData.szInfoTitle;
            Info     = nicData.szInfo;
            Flags    = nicData.dwInfoFlags;
            Timeout  = (int)nicData.uVersion;
            Received = DateTime.Now;

            if (Flags.HasFlag(NIIF.ERROR))
            {
                Icon = GetSystemIcon(SystemIcons.Error.Handle);
            }
            else if (Flags.HasFlag(NIIF.INFO))
            {
                Icon = GetSystemIcon(SystemIcons.Information.Handle);
            }
            else if (Flags.HasFlag(NIIF.WARNING))
            {
                Icon = GetSystemIcon(SystemIcons.Warning.Handle);
            }
            else if (Flags.HasFlag(NIIF.USER))
            {
                if (nicData.hBalloonIcon != 0)
                {
                    SetIconFromHIcon((IntPtr)nicData.hBalloonIcon);
                }
                else if (nicData.hIcon != IntPtr.Zero)
                {
                    SetIconFromHIcon(nicData.hIcon);
                }
            }
        }
コード例 #3
0
        private void GetTrayItems()
        {
            IntPtr toolbarHwnd = FindExplorerTrayToolbarHwnd();

            if (toolbarHwnd == IntPtr.Zero)
            {
                return;
            }

            int count = GetNumTrayIcons(toolbarHwnd);

            if (count < 1)
            {
                return;
            }

            GetWindowThreadProcessId(toolbarHwnd, out var processId);
            IntPtr hProcess = OpenProcess(ProcessAccessFlags.All, false, (int)processId);
            IntPtr hBuffer  = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)Marshal.SizeOf(new TBBUTTON()), AllocationType.Commit,
                                             MemoryProtection.ReadWrite);

            for (int i = 0; i < count; i++)
            {
                TrayItem trayItem = GetTrayItem(i, hBuffer, hProcess, toolbarHwnd);

                if (trayItem.hWnd == IntPtr.Zero || !IsWindow(trayItem.hWnd))
                {
                    ShellLogger.Debug($"ExplorerTrayService: Ignored notify icon {trayItem.szIconText} due to invalid handle");
                    continue;
                }

                SafeNotifyIconData nid = GetTrayItemIconData(trayItem);

                if (trayDelegate != null)
                {
                    if (!trayDelegate((uint)NIM.NIM_ADD, nid))
                    {
                        ShellLogger.Debug("ExplorerTrayService: Ignored notify icon message");
                    }
                }
                else
                {
                    ShellLogger.Debug("ExplorerTrayService: trayDelegate is null");
                }
            }

            VirtualFreeEx(hProcess, hBuffer, 0, AllocationType.Release);

            CloseHandle((int)hProcess);
        }
コード例 #4
0
        private void handleBalloonData(SafeNotifyIconData nicData, NotifyIcon notifyIcon)
        {
            if (string.IsNullOrEmpty(nicData.szInfoTitle))
            {
                return;
            }

            NotificationBalloon          balloonInfo = new NotificationBalloon(nicData, notifyIcon);
            NotificationBalloonEventArgs args        = new NotificationBalloonEventArgs
            {
                Balloon = balloonInfo
            };

            ShellLogger.Debug($"NotificationArea: Received notification \"{balloonInfo.Title}\" for {notifyIcon.Title}");

            NotificationBalloonShown?.Invoke(this, args);

            if (!args.Handled)
            {
                notifyIcon.TriggerNotificationBalloon(balloonInfo);
            }
        }
コード例 #5
0
        private bool SysTrayCallback(uint message, SafeNotifyIconData nicData)
        {
            if (nicData.hWnd == IntPtr.Zero)
            {
                return(false);
            }

            NotifyIcon trayIcon = new NotifyIcon(this, nicData.hWnd);

            trayIcon.UID = nicData.uID;

            lock (_lockObject)
            {
                if ((NIM)message == NIM.NIM_ADD || (NIM)message == NIM.NIM_MODIFY)
                {
                    try
                    {
                        bool exists       = false;
                        bool titleChanged = false;

                        // hide icons while we are shell which require UWP support & we have a separate implementation for
                        if (nicData.guidItem == new Guid(VOLUME_GUID) && ((EnvironmentHelper.IsAppRunningAsShell && EnvironmentHelper.IsWindows10OrBetter) || GroupPolicyHelper.HideScaVolume))
                        {
                            return(false);
                        }

                        // hide icons per group policy
                        if ((nicData.guidItem == new Guid(HEALTH_GUID) && GroupPolicyHelper.HideScaHealth) ||
                            (nicData.guidItem == new Guid(MEETNOW_GUID) && GroupPolicyHelper.HideScaMeetNow) ||
                            (nicData.guidItem == new Guid(NETWORK_GUID) && GroupPolicyHelper.HideScaNetwork) ||
                            (nicData.guidItem == new Guid(POWER_GUID) && GroupPolicyHelper.HideScaPower))
                        {
                            return(false);
                        }

                        foreach (NotifyIcon ti in TrayIcons)
                        {
                            if (ti.Equals(nicData))
                            {
                                exists   = true;
                                trayIcon = ti;
                                break;
                            }
                        }

                        if ((NIF.STATE & nicData.uFlags) != 0)
                        {
                            trayIcon.IsHidden = nicData.dwState == 1;
                        }

                        if ((NIF.TIP & nicData.uFlags) != 0 && !string.IsNullOrEmpty(nicData.szTip))
                        {
                            trayIcon.Title = nicData.szTip;
                            titleChanged   = true;
                        }

                        if ((NIF.ICON & nicData.uFlags) != 0)
                        {
                            if (nicData.hIcon != IntPtr.Zero)
                            {
                                System.Windows.Media.ImageSource icon = IconImageConverter.GetImageFromHIcon(nicData.hIcon, false);

                                if (icon != null)
                                {
                                    trayIcon.Icon = icon;
                                }
                                else if (icon == null && trayIcon.Icon == null)
                                {
                                    // Use default only if we don't have a valid icon already
                                    trayIcon.Icon = IconImageConverter.GetDefaultIcon();
                                }
                            }
                            else
                            {
                                trayIcon.Icon = null;
                            }
                        }

                        trayIcon.HWnd = nicData.hWnd;
                        trayIcon.UID  = nicData.uID;

                        if ((NIF.GUID & nicData.uFlags) != 0)
                        {
                            trayIcon.GUID = nicData.guidItem;
                        }

                        if (nicData.uVersion > 0 && nicData.uVersion <= 4)
                        {
                            trayIcon.Version = nicData.uVersion;
                        }

                        if ((NIF.MESSAGE & nicData.uFlags) != 0)
                        {
                            trayIcon.CallbackMessage = nicData.uCallbackMessage;
                        }

                        if (!exists)
                        {
                            // default placement to a menu bar-like rect
                            trayIcon.Placement = defaultPlacement;

                            // set properties used for pinning
                            trayIcon.Path = ShellHelper.GetPathForWindowHandle(trayIcon.HWnd);
                            trayIcon.SetPinValues();

                            if (trayIcon.Icon == null)
                            {
                                trayIcon.Icon = IconImageConverter.GetDefaultIcon();
                            }

                            TrayIcons.Add(trayIcon);

                            if ((NIF.INFO & nicData.uFlags) != 0)
                            {
                                handleBalloonData(nicData, trayIcon);
                            }

                            ShellLogger.Debug($"NotificationArea: Added: {trayIcon.Title} Path: {trayIcon.Path} Hidden: {trayIcon.IsHidden} GUID: {trayIcon.GUID} UID: {trayIcon.UID} Version: {trayIcon.Version}");

                            if ((NIM)message == NIM.NIM_MODIFY)
                            {
                                // return an error to the notifyicon as we received a modify for an icon we did not yet have
                                return(false);
                            }
                        }
                        else
                        {
                            if ((NIF.INFO & nicData.uFlags) != 0)
                            {
                                handleBalloonData(nicData, trayIcon);
                            }

                            if (titleChanged && trayIcon.GUID == default && !trayIcon.IsPinned)
                            {
                                // set properties used for pinning
                                trayIcon.SetPinValues();
                            }

                            ShellLogger.Debug($"NotificationArea: Modified: {trayIcon.Title}");
                        }
                    }
                    catch (Exception ex)
                    {
                        ShellLogger.Error("NotificationArea: Unable to modify the icon in the collection.", ex);
                    }
                }
                else if ((NIM)message == NIM.NIM_DELETE)
                {
                    try
                    {
                        foreach (var icon in TrayIcons)
                        {
                            if (icon.Equals(trayIcon))
                            {
                                TrayIcons.Remove(trayIcon);

                                ShellLogger.Debug($"NotificationArea: Removed: {icon.Title}");

                                return(true);
                            }
                        }

                        return(false);
                    }
                    catch (Exception ex)
                    {
                        ShellLogger.Error("NotificationArea: Unable to remove the icon from the collection.", ex);
                    }
                }
                else if ((NIM)message == NIM.NIM_SETVERSION)
                {
                    if (nicData.uVersion > 4)
                    {
                        return(false);
                    }

                    foreach (NotifyIcon ti in TrayIcons)
                    {
                        if (ti.Equals(nicData))
                        {
                            ti.Version = nicData.uVersion;
                            ShellLogger.Debug($"NotificationArea: Modified version to {ti.Version} on: {ti.Title}");
                            break;
                        }
                    }
                }
            }
            return(true);
        }
コード例 #6
0
ファイル: NotifyIcon.cs プロジェクト: cairoshell/ManagedShell
 public bool Equals(SafeNotifyIconData other)
 {
     return((HWnd.Equals(other.hWnd) && UID.Equals(other.uID)) || (other.guidItem != Guid.Empty && GUID.Equals(other.guidItem)));
 }