private static Native.TBBUTTON32 ConvertToTBButton32(object obj) { if (obj is Native.TBBUTTON32) { return((Native.TBBUTTON32)obj); } Native.TBBUTTON64 tbb64 = (Native.TBBUTTON64)obj; return(new Native.TBBUTTON32 { dwData = tbb64.dwData, fsState = tbb64.fsState, fsStyle = tbb64.fsStyle, iBitmap = tbb64.iBitmap, idCommand = tbb64.idCommand, iString = tbb64.iString }); }
/// <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>()); } }