static void FixTrayDataAnyCPU(ref SysTrayData trayData) { if (!Is64Bits()) { trayData.nMsg = (uint)trayData.wParam; trayData.wParam = trayData.uID; } }
static Dictionary <IntPtr, (uint nMsg, int wParam)> GetCallbackMessages(IntPtr handle) { try { var result = new Dictionary <IntPtr, (uint nMsg, int wParam)>(); if (handle == IntPtr.Zero) { return(result); } var count = (int)SendMessage(handle, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero); if (count == 0) { return(result); } if (GetWindowThreadProcessId(handle, out var pid) == 0) { return(result); } var process = OpenProcess(ProcessAccess.AllAccess, false, (int)pid); for (var i = 0; i < count; i++) { var sizeOfTbButton = Marshal.SizeOf(Is64Bits() ? typeof(TBBUTTON64) : typeof(TBBUTTON32)); // Allocate memory for TBBUTTON structure var pTBBUTTON = VirtualAllocEx(process, IntPtr.Zero, (uint)sizeOfTbButton, AllocationType.Commit, MemoryProtection.ReadWrite); // Ask explorer.exe to fill the structure we just allocated _ = SendMessage(handle, TB_GETBUTTON, new IntPtr(i), pTBBUTTON); // Read the structure from explorer.exe's memory object obj; obj = new TBBUTTON64(); _ = ReadProcessMemory(process, pTBBUTTON, obj, sizeOfTbButton, out int read); var tbbutton = ConvertToTBButton32(obj); _ = VirtualFreeEx(process, pTBBUTTON, sizeOfTbButton, FreeType.Decommit | FreeType.Release); // Get data associated with icon var data = new IntPtr((int)tbbutton.dwData); obj = new SysTrayData(); _ = ReadProcessMemory(process, data, obj, Marshal.SizeOf(typeof(SysTrayData)), out read); var trayData = (SysTrayData)obj; FixTrayDataAnyCPU(ref trayData); var window = (IntPtr)trayData.hwnd; if (result.ContainsKey(window)) { result[window] = (trayData.nMsg, trayData.wParam); } else { result.Add(window, (trayData.nMsg, trayData.wParam)); } } _ = CloseHandle(process); return(result); } catch (OverflowException) { return(new Dictionary <IntPtr, (uint nMsg, int wParam)>()); } }