; https://www.autoitscript.com/forum/topic/134538-get-systray-icons-solved/ ;coded by rover 2k11 #NoTrayIcon #Include #include #include #include #include #include #Include #include #Include #Include #include Opt("MustDeclareVars", 1) Global Const $PROCESS_ACCESS = BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ) Global $iTbar = 0 Global $hOwnerWin, $hTrayWnd, $hTrayNotifyWnd, $hSysPager, $hToolbar, _ $iDLLUser32 = DllOpen("user32.dll"), $iDLLKrnl32 = DllOpen("kernel32.dll"), _ $tTBBUTTON, $pTBBUTTON, $iTBBUTTON, $tTRAYDATA, $pTRAYDATA, $iTRAYDATA, _ $iImg = 0, $iIdx = 0, $iCount, $iPIDExp, $hProcess, $pAddress, $iPID, $aRet, $sRet, $hIconTray, $hIcon $hTrayWnd = WinGetHandle("[CLASS:Shell_TrayWnd]") $hTrayNotifyWnd = ControlGetHandle($hTrayWnd, "", "[CLASS:TrayNotifyWnd]") $hSysPager = ControlGetHandle($hTrayNotifyWnd, "", "[CLASS:SysPager]") $hToolbar = ControlGetHandle($hSysPager, "", "[CLASS:ToolbarWindow32; INSTANCE:1]");User Promoted Notification Area/Notification Area/SysTray Switch @OSVersion Case "WIN_2008R2", "WIN_7" Switch $iTbar Case 1 ;Overflow Notification Area $hToolbar = ControlGetHandle(WinGetHandle("[CLASS:NotifyIconOverflowWindow]"), "", "[CLASS:ToolbarWindow32; INSTANCE:1]") Case 2 ;System Promoted Notification Area $hToolbar = ControlGetHandle($hTrayNotifyWnd, "", "[CLASS:ToolbarWindow32; INSTANCE:2]") EndSwitch EndSwitch $tTBBUTTON = DllStructCreate("int Bitmap;int Command;byte State;byte Style;align;dword_ptr Param;int_ptr String") $pTBBUTTON = DllStructGetPtr($tTBBUTTON) $iTBBUTTON = DllStructGetSize($tTBBUTTON) $tTRAYDATA = DllStructCreate("hwnd hwnd;uint uID;uint uCallbackMessage;dword Reserved[2];ptr hIcon") $pTRAYDATA = DllStructGetPtr($tTRAYDATA) $iTRAYDATA = DllStructGetSize($tTRAYDATA) $iPIDExp = WinGetProcess($hToolbar) If @error Or $iPIDExp = -1 Then exit $aRet = DllCall($iDLLKrnl32, "ptr", "OpenProcess", "dword", _ $PROCESS_ACCESS, "int", 0, "int", $iPIDExp) If @error Or $aRet[0] = 0 Then Exit $hProcess = $aRet[0] $aRet = DllCall($iDLLUser32, "lparam", "SendMessageW", "hwnd", _ $hToolbar, "int", $TB_BUTTONCOUNT, "wparam", 0, "lparam", 0) If @error Or $aRet[0] < 1 Then DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProcess) Exit EndIf $iCount = $aRet[0] - 1 $aRet = DllCall($iDLLKrnl32, "ptr", "VirtualAllocEx", "ptr", $hProcess, "ptr", 0, "ulong_ptr", _ $iTBBUTTON, "dword", BitOR($MEM_RESERVE, $MEM_COMMIT), "dword", $PAGE_READWRITE) If @error Or $aRet[0] = 0 Then DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProcess) Exit EndIf $pAddress = $aRet[0] GUICreate("Notification Icons", 600, 600) GUISetBkColor(0x494949) Global $hListView = GUICtrlCreateListView("", 2, 2, 596, 596) _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES)) Global $hImage = _GUIImageList_Create(16,16,5,5) _GUICtrlListView_SetImageList($hListView, $hImage, 1) _GUICtrlListView_AddColumn($hListView, "Tray", 38) _GUICtrlListView_AddColumn($hListView, "Proc", 38) _GUICtrlListView_AddColumn($hListView, "Process", 138) _GUICtrlListView_AddColumn($hListView, "Module", 138) _GUICtrlListView_SetColumnWidth($hListView, 3, $LVSCW_AUTOSIZE_USEHEADER) GUISetState() For $iID = 0 To $iCount If IsHWnd($hToolbar) = False Then ExitLoop $aRet = DllCall($iDLLUser32, "lparam", "SendMessageW", "hwnd", $hToolbar, _ "int", $TB_GETBUTTON, "wparam", $iID, "lparam", $pAddress) If @error Or $aRet[0] <> 1 Then ContinueLoop $aRet = DllCall($iDLLKrnl32, "int", "ReadProcessMemory", "ptr", $hProcess, _ "ptr", $pAddress, "ptr", $pTBBUTTON, "ulong_ptr", $iTBBUTTON, "ulong_ptr*", -1) If @error Or $aRet[5] <> $iTBBUTTON Then ContinueLoop ;If BitAND(DllStructGetData($tTBBUTTON, "State"), $TBSTATE_HIDDEN) = $TBSTATE_HIDDEN Then ContinueLoop $aRet = DllCall($iDLLKrnl32, "int", "ReadProcessMemory", "ptr", $hProcess, _ "dword_ptr", DllStructGetData($tTBBUTTON, "Param"), "ptr", $pTRAYDATA, "ulong_ptr", $iTRAYDATA, "ulong_ptr*", -1) If @error Or $aRet[5] <> $iTRAYDATA Then ContinueLoop $hOwnerWin = DllStructGetData($tTRAYDATA, 1) If @error Or $hOwnerWin = 0 Then ContinueLoop $iPID = WinGetProcess($hOwnerWin) If @error Or $iPID = -1 Then ContinueLoop $hIconTray = DllStructGetData($tTRAYDATA, 5) ;returned icon handles shared Local $hIconUID = DllStructGetData($tTRAYDATA, 2) ;returned icon handles shared $sRet = "" If Not _IsIconHandle($hIconTray, $sRet) Then ;ConsoleWrite('!VarGetType($hIconTray) = ' & VarGetType($hIconTray) & @CRLF) If IsPtr($hIconTray) Then $hIconTray = _WinAPI_Create32BitHICON($hIconTray) ;some icons like HDDLife's temp icons return an invalid icon handle, and won't display, but will when formatted by _WinAPI_Create32BitHICON If Not _IsIconHandle($hIconTray, $sRet) Then $hIconTray = _GetTrayIconHandle($hOwnerWin) ConsoleWrite("- Invalid Icon handle: OwnerWin: " & _WinAPI_GetClassName($hOwnerWin) & " Process Name: " & $iPID & @crlf) EndIf EndIf ;$hIconTray = _WinAPI_CopyImage($hIconTray, $IMAGE_ICON, 16, 16) _GUIImageList_ReplaceIcon($hImage, -1, $hIconTray) $hIcon = _WinAPI_ShellExtractAssociatedIcon(_WinAPI_GetProcessFileName($iPID), 1) $iImg = _GUIImageList_ReplaceIcon($hImage, -1, $hIcon) _GUICtrlListView_InsertItem($hListView, "", -1, $iImg-1) _GUICtrlListView_AddSubItem($hListView, $iIdx, "", 1, $iImg) _GUICtrlListView_AddSubItem($hListView, $iIdx, $hIconUID, 2) If $sRet = "" Then $sRet = _WinAPI_GetProcessFileName($iPID) _GUICtrlListView_AddSubItem($hListView, $iIdx, $sRet, 3) $iIdx += 1 ;ToolTip(_WinAPI_GetClassName($hOwnerWin), 1030, 850, $sRet, $hIconTray, 5) ;Sleep(500) _WinAPI_DestroyIcon($hIcon) _WinAPI_DestroyIcon($hIconTray) ;does not destroy traydata handles Next DllCall($iDLLKrnl32, "int", "VirtualFreeEx", "ptr", $hProcess, "ptr", $pAddress, "ulong_ptr", 0, "dword", $MEM_RELEASE) DllCall($iDLLKrnl32, "int", "CloseHandle", "ptr", $hProcess) DllClose($iDLLUser32) DllClose($iDLLKrnl32) ToolTip("") While GUIGetMsg() <> -3 WEnd _GUIImageList_Destroy($hImage) Exit Func _GetTrayIconHandle($hWnd, $hDLLUser32 = "User32.dll") If Not IsHWnd($hWnd) Then Return SetError(1, 1, -1) Local $iPID, $ParentPID, $aWinList $hIcon = _GetIcon($hWnd, $hDLLUser32) If Not @error And $hIcon <> -1 Then Return SetError(0, 0, $hIcon) $ParentPID = WinGetProcess($hWnd) If @error Or $ParentPID = -1 Then Return SetError(2, 2, -1) $aWinList = WinList() For $i = 1 to $aWinList[0][0] $iPID = WinGetProcess($aWinList[$i][1]) If @error Or $iPID = -1 Then ContinueLoop If $iPID = $ParentPID Then $hIcon = _GetIcon($aWinList[$i][1], $hDLLUser32) If Not @error And $hIcon <> -1 Then Return SetError(0, 0, $hIcon) EndIf Next Return SetError(2, 2, -1) EndFunc ;modified from ModernMenu Win2Tray - by Holger Kotsch Func _GetIcon(ByRef $hWnd, $hDLLUser32 = "User32.dll") If Not IsHWnd($hWnd) Then Return SetError(1, 1, -1) Local Const $GCL_HICON = -14 Local Const $GCL_HICONSM = -34 Local $hIcon $hIcon = _SendMessage($hWnd, $WM_GETICON, 2, 0) If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon)) $hIcon = _SendMessage($hWnd, $WM_GETICON, 0, 0) If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon)) $hIcon = _WinAPI_GetClassLongEx($hWnd, $GCL_HICONSM) If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon)) $hIcon = _WinAPI_GetClassLongEx($hWnd, $GCL_HICON) If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon)) Return SetError(2, 2, -1) EndFunc Func _IsIconHandle($hIcon, ByRef $sMod) ;rover 2k11 Local $aRet Switch @OSVersion Case "WIN_2008R2", "WIN_7", "WIN_2008", "WIN_VISTA" $aRet = _WinAPI_GetIconInfoEx($hIcon) If @error Then Return SetError(1, 1, False) DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", $aRet[3]) DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", $aRet[4]) If $aRet[0] = 0 Then Return SetError(2, 2, False) $sMod = $aRet[6] Return SetError(0, 0, True) Case "WIN_2003", "WIN_XP" Local $tIconInfo = DllStructCreate("int fIcon;int xHotspot;int yHotspot;ptr hbmMask;ptr hbmColor") Local $aRet = DllCall("User32.dll", "int", "GetIconInfo", "ptr", $hIcon, "ptr", DllStructGetPtr($tIconInfo)) If @error Or UBound($aRet) <> 3 Or $aRet[0] = 0 Then Return SetError(1, 1, False) DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", DllStructGetData($tIconInfo, 4)) DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", DllStructGetData($tIconInfo, 5)) If Not DllStructGetData($tIconInfo, 1) Then Return SetError(2, 2, False) Return SetError(0, 0, True) EndSwitch EndFunc