//Zero based index public RECT GetItemRect(int index) { RECT rect = new RECT(); int processId = 0; SUIWinAPIs.GetWindowThreadProcessId(WindowHandle, ref processId); IntPtr processHandle = SUIWinAPIs.OpenProcess(SUIMessage.PROCESS_ALL_ACCESS, false, processId); IntPtr data = SUIWinAPIs.VirtualAllocEx(processHandle, IntPtr.Zero, Marshal.SizeOf(rect), SUIMessage.MEM_COMMIT, SUIMessage.PAGE_READWRITE); IntPtr ptrLvi = IntPtr.Zero; try { ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(rect)); Marshal.StructureToPtr(rect, ptrLvi, false); IntPtr numReaded = new IntPtr(); SUIWinAPIs.WriteProcessMemory(processHandle, data, ptrLvi, Marshal.SizeOf(rect), out numReaded); SUIWinAPIs.SendMessage(WindowHandle, SUIMessage.HDM_GETITEMRECT, new IntPtr(index), data); SUIWinAPIs.ReadProcessMemory(processHandle, data, ptrLvi, Marshal.SizeOf(rect), out numReaded); rect = (RECT)Marshal.PtrToStructure(ptrLvi, rect.GetType()); } catch (Exception e) { throw new SUIException("Error getting rectangle of header item!", e); } finally { SUIWinAPIs.VirtualFreeEx(processHandle, data, Marshal.SizeOf(rect), SUIMessage.MEM_RESERVE); Marshal.FreeHGlobal(ptrLvi); SUIWinAPIs.CloseHandle(processHandle); } return(rect); }
private bool GetNotifyIcon_X86(string HP_Tray, TBBUTTON_32 tbButtonData, int processIndex) { Process[] Array_P = Process.GetProcessesByName(HP_Tray); ProcessThreadCollection ptc = Array_P[processIndex].Threads; int[] MSNID = new int[ptc.Count]; int index = 0; foreach (ProcessThread pt in ptc) { MSNID[index] = pt.Id; index++; } //int hWndNotifyIconHandle = MSNID[0]; IntPtr ptrTaskbar = FindWindow("Shell_TrayWnd", null); IntPtr ptrStartBtn = FindWindowEx(new HandleRef(this, ptrTaskbar), new HandleRef(this, IntPtr.Zero), "TrayNotifyWnd", null); IntPtr traysyspager = FindWindowEx(new HandleRef(this, ptrStartBtn), new HandleRef(this, IntPtr.Zero), "syspager", null); IntPtr hWndTray = FindWindowEx(new HandleRef(this, traysyspager), new HandleRef(this, IntPtr.Zero), "toolbarwindow32", null); int dwTrayProcessID = -1; GetWindowThreadProcessId(hWndTray, out dwTrayProcessID); Process TrayP = Process.GetProcessById(dwTrayProcessID); if (dwTrayProcessID <= 0) { return(false); } IntPtr hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if (hTrayProc == IntPtr.Zero) { return(false); } int intTrayButtonCount = (int)SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); if (intTrayButtonCount <= 0) { return(false); } IntPtr lpData = VirtualAllocEx(hTrayProc, IntPtr.Zero, Marshal.SizeOf(tbButtonData.GetType()), MEM_COMMIT, PAGE_READWRITE); if (lpData == IntPtr.Zero) { CloseHandle(hTrayProc); return(false); } bool bIconFound = false; for (int intButton = 0; intButton < intTrayButtonCount; intButton++) { // Get button data int dwBytesRead = -1; byte[] byteBuffer = new byte[Marshal.SizeOf(tbButtonData.GetType())]; SendMessage(hWndTray, TB_GETBUTTON, intButton, lpData); ReadProcessMemory(hTrayProc, lpData, byteBuffer, Marshal.SizeOf(tbButtonData.GetType()), out dwBytesRead); if (dwBytesRead < Marshal.SizeOf(tbButtonData.GetType())) { continue; } IntPtr ptrOut = Marshal.AllocHGlobal(Marshal.SizeOf(tbButtonData.GetType())); Marshal.Copy(byteBuffer, 0, ptrOut, byteBuffer.Length); tbButtonData = (TBBUTTON_32)Marshal.PtrToStructure(ptrOut, typeof(TBBUTTON_32)); // Get extra button data from .dwData base address dwBytesRead = -1; int[] dwExtraData = new int[2] { 0, 0 }; byte[] byteBuffer2 = new byte[Marshal.SizeOf(dwExtraData[0].GetType()) * dwExtraData.Length]; int intRetval2 = ReadProcessMemory(hTrayProc, (IntPtr)tbButtonData.dwData, byteBuffer2, (Marshal.SizeOf(dwExtraData[0].GetType()) * dwExtraData.Length), out dwBytesRead); if (dwBytesRead < (Marshal.SizeOf(dwExtraData[0]) * dwExtraData.Length)) { continue; } dwExtraData[1] = BitConverter.ToInt32(byteBuffer2, (byteBuffer2.Length / 2)); Array.Resize(ref byteBuffer2, (byteBuffer2.Length / 2)); dwExtraData[0] = BitConverter.ToInt32(byteBuffer2, 0); IntPtr hWndCurrentIconHandle = (IntPtr)dwExtraData[0]; int intCurrentIconID = (int)dwExtraData[1]; // Spin if this is not the target tray icon int dwCurrentThreadIconId = -1; dwCurrentThreadIconId = GetWindowThreadProcessId(hWndCurrentIconHandle, out dwCurrentThreadIconId); //if (dwCurrentThreadIconId != hWndNotifyIconHandle) bool found = false; foreach (int i in MSNID) { if (dwCurrentThreadIconId == i) { found = true; break; } } if (!found) { continue; } // Get rectangle of tray icon dwBytesRead = -1; RECT rectNotifyIcon = new RECT(0, 0, 0, 0); byte[] byteBuffer3 = new byte[Marshal.SizeOf(rectNotifyIcon.GetType())]; SendMessage(hWndTray, TB_GETITEMRECT, intButton, lpData); ReadProcessMemory(hTrayProc, lpData, byteBuffer3, Marshal.SizeOf(rectNotifyIcon.GetType()), out dwBytesRead); if (dwBytesRead < Marshal.SizeOf(rectNotifyIcon.GetType())) { continue; } IntPtr ptrOut2 = Marshal.AllocHGlobal(Marshal.SizeOf(rectNotifyIcon.GetType())); Marshal.Copy(byteBuffer3, 0, ptrOut2, byteBuffer3.Length); rectNotifyIcon = (RECT)Marshal.PtrToStructure(ptrOut2, typeof(RECT)); MapWindowPoints(hWndTray, IntPtr.Zero, ref rectNotifyIcon, 2); endPosition.X = Convert.ToInt32((rectNotifyIcon.Left + rectNotifyIcon.Right) / 2); endPosition.Y = Convert.ToInt32((rectNotifyIcon.Top + rectNotifyIcon.Bottom) / 2); SetCursorPos(endPosition.X, endPosition.Y); mouse_event(MouseEventFlag.RightDown, 0, 0, 0, UIntPtr.Zero); mouse_event(MouseEventFlag.RightUp, 0, 0, 0, UIntPtr.Zero); bIconFound = true; break; } // Free memory in parent process for system tray and close handle VirtualFreeEx(hTrayProc, lpData, 0, MEM_RELEASE); CloseHandle(hTrayProc); return(bIconFound); }
public static unsafe bool GetTBButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle, out NotificationAreaWindow notificationAreaWindow) { notificationAreaWindow = new NotificationAreaWindow(); // One page const int BUFFER_SIZE = 0x1000; var localBuffer = new byte[BUFFER_SIZE]; uint processId = 0; uint threadId = User32.GetWindowThreadProcessId(hToolbar, out processId); var hProcess = Kernel32.OpenProcess(ProcessRights.ALL_ACCESS, false, processId); if (hProcess == IntPtr.Zero) { Debug.Assert(false); return(false); } var ipRemoteBuffer = Kernel32.VirtualAllocEx( hProcess, IntPtr.Zero, new UIntPtr(BUFFER_SIZE), MemAllocationType.COMMIT, MemoryProtection.PAGE_READWRITE); if (ipRemoteBuffer == IntPtr.Zero) { Debug.Assert(false); return(false); } // TBButton fixed(TBBUTTON *pTbButton = &tbButton) { var ipTbButton = new IntPtr(pTbButton); var b = (int)User32.SendMessage(hToolbar, TB.GETBUTTON, (IntPtr)i, ipRemoteBuffer); if (b == 0) { Debug.Assert(false); return(false); } var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var b2 = Kernel32.ReadProcessMemory( hProcess, ipRemoteBuffer, ipTbButton, new UIntPtr((uint)sizeof(TBBUTTON)), ipBytesRead); if (!b2) { Debug.Assert(false); return(false); } } // button text fixed(byte *pLocalBuffer = localBuffer) { var ipLocalBuffer = new IntPtr(pLocalBuffer); var chars = (int)User32.SendMessage(hToolbar, TB.GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer); if (chars == -1) { Debug.Assert(false); return(false); } var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var b4 = Kernel32.ReadProcessMemory( hProcess, ipRemoteBuffer, ipLocalBuffer, new UIntPtr(BUFFER_SIZE), ipBytesRead); if (!b4) { Debug.Assert(false); return(false); } text = Marshal.PtrToStringUni(ipLocalBuffer, chars); if (text == " ") { text = String.Empty; } } // window handle fixed(byte *pLocalBuffer = localBuffer) { var ipLocalBuffer = new IntPtr(pLocalBuffer); var dwBytesRead = 0; var ipBytesRead = new IntPtr(&dwBytesRead); var ipRemoteData = tbButton.dwData; var b4 = Kernel32.ReadProcessMemory( hProcess, ipRemoteData, ipLocalBuffer, new UIntPtr(4), ipBytesRead); if (!b4) { Debug.Assert(false); return(false); } if (dwBytesRead != 4) { Debug.Assert(false); return(false); } var iWindowHandle = BitConverter.ToInt32(localBuffer, 0); if (iWindowHandle == -1) { Debug.Assert(false); } //return false; } ipWindowHandle = new IntPtr(iWindowHandle); } var rect = default(RECT); uint dwTrayProcessID = 0; GetWindowThreadProcessId(hToolbar, out dwTrayProcessID); if (dwTrayProcessID <= 0) { return(false); } var hTrayProc = Kernel32.OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if (hTrayProc == IntPtr.Zero) { return(false); } var lpData = Kernel32.VirtualAllocEx(hTrayProc, IntPtr.Zero, Marshal.SizeOf(tbButton.GetType()), MEM_COMMIT, PAGE_READWRITE); if (lpData == IntPtr.Zero) { Kernel32.CloseHandle(hTrayProc); return(false); } // Show tray icon if hidden //if ((tbButton.fsState & (byte)TBSTATE_HIDDEN) == (byte)TBSTATE_HIDDEN) SendMessage(hToolbar, TB_HIDEBUTTON, tbButton.idCommand, 1); // Get rectangle of tray icon var dwBytesRead2 = -1; var rectNotifyIcon = new RECT(0, 0, 0, 0); var byteBuffer3 = new byte[Marshal.SizeOf(rectNotifyIcon.GetType())]; SendMessage(hToolbar, TB.GETITEMRECT, tbButton.idCommand, lpData); Kernel32.ReadProcessMemory(hTrayProc, lpData, byteBuffer3, Marshal.SizeOf(rectNotifyIcon.GetType()), out dwBytesRead2); if (dwBytesRead2 < Marshal.SizeOf(rectNotifyIcon.GetType())) { return(false); } var ptrOut2 = Marshal.AllocHGlobal(Marshal.SizeOf(rectNotifyIcon.GetType())); Marshal.Copy(byteBuffer3, 0, ptrOut2, byteBuffer3.Length); rectNotifyIcon = (RECT)Marshal.PtrToStructure(ptrOut2, typeof(RECT)); //MapWindowPoints(hToolbar, IntPtr.Zero, ref rectNotifyIcon, 2); // Display coordinates var c = GetRect(hToolbar); System.Diagnostics.Debug.Print("{4} ICONS COORDINATES ARE: Top: {0}, Left: {1}, Bottom: {2}, Right: {3}", rectNotifyIcon.Top - c.Top, rectNotifyIcon.Left - c.Left, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height, rectNotifyIcon.Right - c.Right, text); Kernel32.VirtualFreeEx(hTrayProc, lpData, UIntPtr.Zero, MEM_RELEASE); Kernel32.CloseHandle(hTrayProc); rect = new RECT( rectNotifyIcon.Left - c.Left, rectNotifyIcon.Top - c.Top, rectNotifyIcon.Right - c.Right, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height); Kernel32.VirtualFreeEx( hProcess, ipRemoteBuffer, UIntPtr.Zero, MemAllocationType.RELEASE); Kernel32.CloseHandle(hProcess); notificationAreaWindow = new NotificationAreaWindow() { TBBUTTON = tbButton, MainWindowHandle = ipWindowHandle, ToolBarIconHandle = hToolbar, Text = text, RECT = rect }; return(true); }
public static unsafe bool GetTBButton(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle, out NotificationAreaWindow notificationAreaWindow) { notificationAreaWindow = new NotificationAreaWindow(); // One page const int BUFFER_SIZE = 0x1000; byte[] localBuffer = new byte[BUFFER_SIZE]; uint processId = 0; UInt32 threadId = User32.GetWindowThreadProcessId(hToolbar, out processId); IntPtr hProcess = Kernel32.OpenProcess(ProcessRights.ALL_ACCESS, false, processId); if (hProcess == IntPtr.Zero) { Debug.Assert(false); return false; } IntPtr ipRemoteBuffer = Kernel32.VirtualAllocEx( hProcess, IntPtr.Zero, new UIntPtr(BUFFER_SIZE), MemAllocationType.COMMIT, MemoryProtection.PAGE_READWRITE); if (ipRemoteBuffer == IntPtr.Zero) { Debug.Assert(false); return false; } // TBButton fixed (TBBUTTON* pTBButton = &tbButton) { IntPtr ipTBButton = new IntPtr(pTBButton); int b = (int)User32.SendMessage(hToolbar, TB.GETBUTTON, (IntPtr)i, ipRemoteBuffer); if (b == 0) { Debug.Assert(false); return false; } Int32 dwBytesRead = 0; IntPtr ipBytesRead = new IntPtr(&dwBytesRead); bool b2 = Kernel32.ReadProcessMemory( hProcess, ipRemoteBuffer, ipTBButton, new UIntPtr((uint)sizeof(TBBUTTON)), ipBytesRead); if (!b2) { Debug.Assert(false); return false; } } // button text fixed (byte* pLocalBuffer = localBuffer) { IntPtr ipLocalBuffer = new IntPtr(pLocalBuffer); int chars = (int)User32.SendMessage(hToolbar, TB.GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer); if (chars == -1) { Debug.Assert(false); return false; } Int32 dwBytesRead = 0; IntPtr ipBytesRead = new IntPtr(&dwBytesRead); bool b4 = Kernel32.ReadProcessMemory( hProcess, ipRemoteBuffer, ipLocalBuffer, new UIntPtr(BUFFER_SIZE), ipBytesRead); if (!b4) { Debug.Assert(false); return false; } text = Marshal.PtrToStringUni(ipLocalBuffer, chars); if (text == " ") text = String.Empty; } // window handle fixed (byte* pLocalBuffer = localBuffer) { IntPtr ipLocalBuffer = new IntPtr(pLocalBuffer); Int32 dwBytesRead = 0; IntPtr ipBytesRead = new IntPtr(&dwBytesRead); var ipRemoteData = tbButton.dwData; bool b4 = Kernel32.ReadProcessMemory( hProcess, ipRemoteData, ipLocalBuffer, new UIntPtr(4), ipBytesRead); if (!b4) { Debug.Assert(false); return false; } if (dwBytesRead != 4) { Debug.Assert(false); return false; } Int32 iWindowHandle = BitConverter.ToInt32(localBuffer, 0); if (iWindowHandle == -1) { Debug.Assert(false); }//return false; } ipWindowHandle = new IntPtr(iWindowHandle); } var rect = default(RECT); uint dwTrayProcessID = 0; GetWindowThreadProcessId(hToolbar, out dwTrayProcessID); if (dwTrayProcessID <= 0) { return false; } IntPtr hTrayProc = Kernel32.OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if (hTrayProc == IntPtr.Zero) { return false; } IntPtr lpData = Kernel32.VirtualAllocEx(hTrayProc, IntPtr.Zero, Marshal.SizeOf(tbButton.GetType()), MEM_COMMIT, PAGE_READWRITE); if (lpData == IntPtr.Zero) { Kernel32.CloseHandle(hTrayProc); return false; } // Show tray icon if hidden //if ((tbButton.fsState & (byte)TBSTATE_HIDDEN) == (byte)TBSTATE_HIDDEN) SendMessage(hToolbar, TB_HIDEBUTTON, tbButton.idCommand, 1); // Get rectangle of tray icon Int32 dwBytesRead2 = -1; var rectNotifyIcon = new RECT(0, 0, 0, 0); byte[] byteBuffer3 = new byte[Marshal.SizeOf(rectNotifyIcon.GetType())]; SendMessage(hToolbar, TB.GETITEMRECT, tbButton.idCommand, lpData); Kernel32.ReadProcessMemory(hTrayProc, lpData, byteBuffer3, Marshal.SizeOf(rectNotifyIcon.GetType()), out dwBytesRead2); if (dwBytesRead2 < Marshal.SizeOf(rectNotifyIcon.GetType())) { return false; } IntPtr ptrOut2 = Marshal.AllocHGlobal(Marshal.SizeOf(rectNotifyIcon.GetType())); Marshal.Copy(byteBuffer3, 0, ptrOut2, byteBuffer3.Length); rectNotifyIcon = (RECT)Marshal.PtrToStructure(ptrOut2, typeof(RECT)); //MapWindowPoints(hToolbar, IntPtr.Zero, ref rectNotifyIcon, 2); // Display coordinates var c = GetRect(hToolbar); System.Diagnostics.Debug.Print("{4} ICONS COORDINATES ARE: Top: {0}, Left: {1}, Bottom: {2}, Right: {3}", rectNotifyIcon.Top - c.Top, rectNotifyIcon.Left - c.Left, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height, rectNotifyIcon.Right - c.Right, text); Kernel32.VirtualFreeEx(hTrayProc, lpData, UIntPtr.Zero, MEM_RELEASE); Kernel32.CloseHandle(hTrayProc); rect = new RECT( rectNotifyIcon.Left - c.Left, rectNotifyIcon.Top - c.Top, rectNotifyIcon.Right - c.Right, (rectNotifyIcon.Bottom - c.Bottom) + rectNotifyIcon.Height); Kernel32.VirtualFreeEx( hProcess, ipRemoteBuffer, UIntPtr.Zero, MemAllocationType.RELEASE); Kernel32.CloseHandle(hProcess); notificationAreaWindow = new NotificationAreaWindow() { TBBUTTON = tbButton, MainWindowHandle = ipWindowHandle, ToolBarIconHandle = hToolbar, Text = text, RECT = rect }; return true; }