public NotificationIcon(NotificationIconInfo data) { _data = data; _toolTip = new ToolTip(); _toolTip.ShowAlways = true; _singleClickTimer.Interval = SystemInformation.DoubleClickTime; _singleClickTimer.Tick += new EventHandler(_singleClickTimer_Tick); }
/// <summary> /// Get information about all icons /// </summary> public static List <NotificationIconInfo> GetVisibleIcons() { try { var toolbarWindow = GetUserToolbar(); var result = new List <NotificationIconInfo>(); if (toolbarWindow.Handle == IntPtr.Zero) { return(result); } int count = (int)Native.SendMessage(toolbarWindow.Handle, (uint)Native.WindowMessage.TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero); if (count == 0) { return(result); } uint pid; Native.GetWindowThreadProcessId(toolbarWindow.Handle, out pid); bool hr; IntPtr hproc = IPCNative.OpenProcess(IPCNative.ProcessAccess.AllAccess, false, (int)pid); for (int i = 0; i < count; i++) { int sizeOfTbButton = Marshal.SizeOf(Is64Bits() ? typeof(Native.TBBUTTON64) : typeof(Native.TBBUTTON32)); // Allocate memory for TBBUTTON structure IntPtr pTBBUTTON = IPCNative.VirtualAllocEx(hproc, IntPtr.Zero, (uint)sizeOfTbButton, IPCNative.AllocationType.Commit, IPCNative.MemoryProtection.ReadWrite); // Ask explorer.exe to fill the structure we just allocated Native.SendMessage(toolbarWindow.Handle, (uint)Native.WindowMessage.TB_GETBUTTON, new IntPtr(i), pTBBUTTON); // Read the structure from explorer.exe's memory int read; object obj; if (Is64Bits()) { obj = new Native.TBBUTTON64(); } else { obj = new Native.TBBUTTON32(); } hr = IPCNative.ReadProcessMemory(hproc, pTBBUTTON, obj, sizeOfTbButton, out read); Native.TBBUTTON32 tbbutton = ConvertToTBButton32(obj); hr = IPCNative.VirtualFreeEx(hproc, pTBBUTTON, sizeOfTbButton, IPCNative.FreeType.Decommit | IPCNative.FreeType.Release); // Get data associated with icon IntPtr data = new IntPtr((int)tbbutton.dwData); obj = new Native.SysTrayData(); IPCNative.ReadProcessMemory(hproc, data, obj, Marshal.SizeOf(typeof(Native.SysTrayData)), out read); Native.SysTrayData trayData = (Native.SysTrayData)obj; FixTrayDataAnyCPU(ref trayData); if (trayData.wParam < 0) { continue; } // Get tooltip length int size = (int)Native.SendMessage(toolbarWindow.Handle, (uint)Native.WindowMessage.TB_GETBUTTONTEXT, (IntPtr)tbbutton.idCommand, IntPtr.Zero); size *= 2; // because it is unicode // Alloc memory for explorer.exe to write tooltip to IntPtr pText = IPCNative.VirtualAllocEx(hproc, IntPtr.Zero, (uint)size, IPCNative.AllocationType.Commit, IPCNative.MemoryProtection.ReadWrite); Native.SendMessage(toolbarWindow.Handle, (uint)Native.WindowMessage.TB_GETBUTTONTEXT, (IntPtr)tbbutton.idCommand, pText); // Read tooltip from memory byte[] objstr = new byte[size]; IPCNative.ReadProcessMemory(hproc, pText, objstr, size, out read); hr = IPCNative.VirtualFreeEx(hproc, pText, size, IPCNative.FreeType.Decommit | IPCNative.FreeType.Release); string tooltip = UnicodeEncoding.Unicode.GetString(objstr); NotificationIconInfo icon = new NotificationIconInfo { BitmapIndex = tbbutton.iBitmap, DataIdentifier = tbbutton.dwData, Data = trayData, Tooltip = tooltip }; result.Add(icon); } hr = IPCNative.CloseHandle(hproc); return(result); } catch (OverflowException) { return(new List <NotificationIconInfo>()); } }
protected override void UpdateNotificationIconInternal(NotificationIcon nid, bool updateContextMenu) { try { NotificationIconInfo nii = new NotificationIconInfo(); if (!notificationIconInfo.ContainsKey(nid)) { nii.hIndicator = Internal.AppIndicator.Methods.app_indicator_new(nid.Name, nid.IconNameDefault, Internal.AppIndicator.Constants.AppIndicatorCategory.ApplicationStatus); notificationIconInfo.Add(nid, nii); // Internal.AppIndicator.Methods.app_indicator_set_label(hIndicator, nid.Text, "I don't know what this is for"); // Internal.AppIndicator.Methods.app_indicator_set_title(hIndicator, nid.Text); } else { nii = notificationIconInfo[nid]; } if (updateContextMenu) { IntPtr hMenu = Internal.GTK.Methods.gtk_menu_new(); IntPtr hMenuTitle = Internal.GTK.Methods.gtk_menu_item_new(); Internal.GTK.Methods.gtk_widget_set_sensitive(hMenuTitle, false); Internal.GTK.Methods.gtk_menu_shell_append(hMenu, hMenuTitle); nii.hMenuItemTitle = hMenuTitle; IntPtr hMenuSeparator = Internal.GTK.Methods.gtk_separator_menu_item_new(); Internal.GTK.Methods.gtk_menu_shell_append(hMenu, hMenuSeparator); if (nid.ContextMenu != null) { foreach (MenuItem mi in nid.ContextMenu.Items) { InitMenuItem(mi, hMenu); } } Internal.GTK.Methods.gtk_widget_show_all(hMenu); Internal.AppIndicator.Methods.app_indicator_set_menu(nii.hIndicator, hMenu); } if (nii.hMenuItemTitle != IntPtr.Zero) { Internal.GTK.Methods.gtk_menu_item_set_label(nii.hMenuItemTitle, nid.Text); } Internal.AppIndicator.Methods.app_indicator_set_attention_icon(nii.hIndicator, nid.IconNameAttention); switch (nid.Status) { case NotificationIconStatus.Hidden: { Internal.AppIndicator.Methods.app_indicator_set_status(nii.hIndicator, Internal.AppIndicator.Constants.AppIndicatorStatus.Passive); break; } case NotificationIconStatus.Visible: { Internal.AppIndicator.Methods.app_indicator_set_status(nii.hIndicator, Internal.AppIndicator.Constants.AppIndicatorStatus.Active); break; } case NotificationIconStatus.Attention: { Internal.AppIndicator.Methods.app_indicator_set_status(nii.hIndicator, Internal.AppIndicator.Constants.AppIndicatorStatus.Attention); break; } } } catch { } }