Moderators SmOke_N Posted April 5, 2013 Moderators Posted April 5, 2013 (edited) Any way to refresh all trayicons to remove dead once form the tryiconarea ? I didn't use the findtraybarwindow function wraithdu provides, to be honest, I didn't see it until I had already written this out. This is similar to something I used in the past. expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> #cs ; un-comment to see example run and clear systray _systray_clearDead() #ce Func _systray_clearDead($v_tray = "", $v_title = "") Local $h_systray = $v_tray If Not IsHWnd($h_systray) Then If StringLen($v_tray) = 0 Then $h_systray = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", _ "[CLASS:ToolbarWindow32; INSTANCE:1]") ElseIf IsString($v_tray) Then If $v_title Then $h_systray = ControlGetHandle($v_title, "", $v_tray) Else $h_systray = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", $v_tray) EndIf EndIf If Not IsHWnd($h_systray) Then Return SetError(1, 0, 0) EndIf Local $a_pos = WinGetPos($h_systray) If Not IsArray($a_pos) Then Return SetError(2, 0, 0) Local $i_midy = ($a_pos[1] - $a_pos[3]) / 2 Local $i_width = ($a_pos[0] - $a_pos[2]) Local $i_word For $i = $i_width To 0 Step -4 $i_word = _WinAPI_MakeQWord($i, $i_midy) _WinAPI_PostMessage($h_systray, $WM_MOUSEMOVE, 0, $i_word) Next Return 1 EndFunc Edited April 5, 2013 by SmOke_N reversed for/next array Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
guinness Posted April 5, 2013 Posted April 5, 2013 I've used this...but I will check out your version SmOke_N. Func _Taskbar_Refresh() ; By rasim - http://www.autoitscript.com/forum/topic/66629-systemtray-refresh/ Local Const $hTaskBar = _WinAPI_FindWindow('Shell_TrayWnd', '') Local Const $hParent = ControlGetHandle($hTaskBar, '', 'TrayNotifyWnd1') Local Const $hWnd = ControlGetHandle($hParent, '', 'ToolbarWindow321') Local Const $tWinRect = _WinAPI_GetWindowRect($hWnd) Local Const $aMouseGetPos = MouseGetPos() Local Const $iLeft = DllStructGetData($tWinRect, 'Left') Local Const $iRight = DllStructGetData($tWinRect, 'Right') Local Const $iTop = DllStructGetData($tWinRect, 'Top') For $i = $iLeft To $iRight MouseMove($i, $iTop, 0) Next MouseMove($aMouseGetPos[0], $aMouseGetPos[1], 0) EndFunc ;==>_Taskbar_Refresh UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018
Moderators SmOke_N Posted April 5, 2013 Moderators Posted April 5, 2013 (edited) I've used this...but I will check out your version SmOke_N.Valik did something similar years ago like what you provided. I used to use mine in a ,maintenance program I had on a scheduler. This made a "mousemove" too obtrusive in case I was trying to use it for my own benefit, even if it tried to go back to the original position. Edited April 5, 2013 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
wraithdu Posted April 5, 2013 Author Posted April 5, 2013 Any way to refresh all trayicons to remove dead once form the tryiconarea ?My example in the 1st post already does this, see the linesIf $pid = -1 Then _SysTrayIconRemove()However I've noticed even though it works in Win7, it may create an empty space at the right edge of the sys tray until you expand the overflow window. I have no idea why.
KaFu Posted April 5, 2013 Posted April 5, 2013 (edited) However I've noticed even though it works in Win7, it may create an empty space at the right edge of the sys tray until you expand the overflow window. I have no idea why. for the removal of icons ... two post above that I've also posted a function to hide / unhide systray icons. Edited April 6, 2013 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
WhiteLion Posted April 12, 2013 Posted April 12, 2013 I didn't use the findtraybarwindow function wraithdu provides, to be honest, I didn't see it until I had already written this out. This is similar to something I used in the past. expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> #cs ; un-comment to see example run and clear systray _systray_clearDead() #ce Func _systray_clearDead($v_tray = "", $v_title = "") Local $h_systray = $v_tray If Not IsHWnd($h_systray) Then If StringLen($v_tray) = 0 Then $h_systray = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", _ "[CLASS:ToolbarWindow32; INSTANCE:1]") ElseIf IsString($v_tray) Then If $v_title Then $h_systray = ControlGetHandle($v_title, "", $v_tray) Else $h_systray = ControlGetHandle("[CLASS:Shell_TrayWnd]", "", $v_tray) EndIf EndIf If Not IsHWnd($h_systray) Then Return SetError(1, 0, 0) EndIf Local $a_pos = WinGetPos($h_systray) If Not IsArray($a_pos) Then Return SetError(2, 0, 0) Local $i_midy = ($a_pos[1] - $a_pos[3]) / 2 Local $i_width = ($a_pos[0] - $a_pos[2]) Local $i_word For $i = $i_width To 0 Step -4 $i_word = _WinAPI_MakeQWord($i, $i_midy) _WinAPI_PostMessage($h_systray, $WM_MOUSEMOVE, 0, $i_word) Next Return 1 EndFunc I've used this...but I will check out your version SmOke_N. Func _Taskbar_Refresh() ; By rasim - http://www.autoitscript.com/forum/topic/66629-systemtray-refresh/ Local Const $hTaskBar = _WinAPI_FindWindow('Shell_TrayWnd', '') Local Const $hParent = ControlGetHandle($hTaskBar, '', 'TrayNotifyWnd1') Local Const $hWnd = ControlGetHandle($hParent, '', 'ToolbarWindow321') Local Const $tWinRect = _WinAPI_GetWindowRect($hWnd) Local Const $aMouseGetPos = MouseGetPos() Local Const $iLeft = DllStructGetData($tWinRect, 'Left') Local Const $iRight = DllStructGetData($tWinRect, 'Right') Local Const $iTop = DllStructGetData($tWinRect, 'Top') For $i = $iLeft To $iRight MouseMove($i, $iTop, 0) Next MouseMove($aMouseGetPos[0], $aMouseGetPos[1], 0) EndFunc ;==>_Taskbar_Refresh I tried both scripts (used as they where posted above on Win 7 x64) but non of them removed the dead trayicons. (to make it clear: I am talking about the trayicons which are in the "out faded area" (what ever its called in english)) btw should I give special parameters to the function "_systray_clearDead" !? - Which ?
power1power1 Posted May 13, 2013 Posted May 13, 2013 (edited) Hey KaFu, Can you be more specific on how your "fix" applies to wraithdu's script? Thanks! By the way, there are still some missing information as WhiteLion has mentioned in previous post ... Edited May 14, 2013 by power1power1
wraithdu Posted May 13, 2013 Author Posted May 13, 2013 (edited) A big thanks to KaFu for the Shell_NotifyIcon functions. I've integrated that method into my UDF for the Hide/Remove functions. It works well on Win7 for the dead icons as well. I've been meaning to revisit those functions to implement that method for quite some time, but I've been really lazy about it. I've done some general code cleanup and better error reporting as well. Beware there are some probably script breaking changes if you directly used the _SysTrayGetButtonInfo function. Try the example for the dead icons issue. Edited May 13, 2013 by wraithdu
power1power1 Posted May 14, 2013 Posted May 14, 2013 (edited) Hi wraithdu, Thanks a lot for updating the scripts. It seems the issue of dead icons has gone away for me as well and I have Windows 8. Thanks again! Edited May 14, 2013 by power1power1
NoTolerance Posted September 27, 2013 Posted September 27, 2013 I consider myself a relative beginner. I've written a few scripts here and there to help with a few things, but that's about it. So this may be a really stupid suggestion on my part, but couldn't you "OS-proof" the UDF by doing something like this for the default function arguments: If @OSVersion = "WIN_VISTA" Or @OSVersion = "WIN_2003" Or @OSVersion = "WIN_XP" Or @OSVersion = "WIN_XPe" Or @OSVersion = "WIN_2000" Then $myos = 1 Else $myos = 2 EndIf I have a utility script that I wrote that runs on various machines, so I ended up doing that in my script and then using your UDF like so: If @OSVersion = "WIN_VISTA" Or @OSVersion = "WIN_2003" Or @OSVersion = "WIN_XP" Or @OSVersion = "WIN_XPe" Or @OSVersion = "WIN_2000" Then $myos = 1 Else $myos = 2 EndIf $count = _SysTrayIconCount($myos) ConsoleWrite("Count visible tray: " & $count & @CRLF) For $i = $count - 1 To 0 Step -1 $handle = _SysTrayIconHandle($i) $visible = _SysTrayIconVisible($i) $pid = WinGetProcess($handle) $name = _ProcessGetName($pid) $title = WinGetTitle($handle) $tooltip = _SysTrayIconTooltip($i) ConsoleWrite("index: " & $i & @TAB & "visible: " & $visible & @TAB & "handle: " & $handle & @TAB & "pid: " & _ $pid & @TAB & "proc: " & $name & @TAB & @TAB & "title: " & $title & @TAB & @TAB & "tooltip: " & $tooltip & @CRLF) If $pid = -1 Then _SysTrayIconRemove($i) Next If _FindTrayToolbarWindow($myos) <> -1 Then ConsoleWrite("-====================-" & @CRLF) $countwin7 = _SysTrayIconCount($myos) ConsoleWrite("Count overflow area: " & $countwin7 & @CRLF) For $i = $countwin7 - 1 To 0 Step -1 $handle = _SysTrayIconHandle($i, 2) $visible = _SysTrayIconVisible($i, 2) $pid = WinGetProcess($handle) $name = _ProcessGetName($pid) $title = WinGetTitle($handle) $tooltip = _SysTrayIconTooltip($i, 2) ConsoleWrite("index: " & $i & @TAB & "visible: " & $visible & @TAB & "handle: " & $handle & @TAB & "pid: " & _ $pid & @TAB & "proc: " & $name & @TAB & @TAB & "title: " & $title & @TAB & @TAB & "tooltip: " & $tooltip & @CRLF) If $pid = -1 Then _SysTrayIconRemove($i, 2) Next EndIf It works like a peach on both WinXP and Win7. I would think you could basically do the same thing in the UDF to set the default, but still allow the user to override the value if they choose. Like I said, sorry if I'm way off-base here. Thanks for this great UDF regardless. I have a script that runs in a constant loop (it's polling for data regularly) and another script that needs to kill that process once a day before it can run, so I get stuck with multiple tray icons for the first script since it's not exiting gracefully. This UDF has eliminated that problem for me.
wraithdu Posted September 27, 2013 Author Posted September 27, 2013 Your suggestion is not out of line, just my choice not to do the checking for you. Either way, this would be a bit cleaner. StringRegExp(@OSVersion, "WIN_(200(0|3)|XP|V)")
masvil Posted November 24, 2016 Posted November 24, 2016 It works great on Windows 10 too. @wraithdu well done!
yukycg Posted April 17, 2017 Posted April 17, 2017 I need some help. First is it possible to do a right click on an hidden overflow icon? I searched but can't confirm it or a thread to show how. My PC is a win7 x64. My current workaround is unhide tray icons by registry, reload explorer.exe to show all icons, match the tooltips, right clicks and do my task, update registry to hide it, and reload explorer.
Mbee Posted February 23, 2018 Posted February 23, 2018 This isn't working on 64-bit Windows 10. For example, when I call _SysTrayIconCount( 2 ) [2 = Win 7+], I always get zero, whereas there are 10 of them showing. I also tried using the functions provided in this thread: Manipulate system tray program? from 2014, but it was hardly better. It reported only 1 icon. What I want to do is to bring up the GUI window for something running in the system tray that doesn't have a GUI until the tray icon is clicked. Curiously, a call to WinExists() always reports the GUI window does exist, even though it actually doesn't. Thus when I try to activate that window with WinActivate(), the GUI never appears! How can this be done under 64-bit Windows 10, please? Thanks!
Deye Posted February 23, 2018 Posted February 23, 2018 Probably getting the wrong handle on win10 ( wrong instance number ) $hSysTray = ControlGetHandle("[Class:Shell_TrayWnd]", "", "[Class:ToolbarWindow32;Instance:" & (@OSVersion = "WIN_10" ? 3 : 1) & "]") Mbee 1
Mbee Posted February 25, 2018 Posted February 25, 2018 On 2/23/2018 at 11:51 AM, Deye said: Probably getting the wrong handle on win10 ( wrong instance number ) $hSysTray = ControlGetHandle("[Class:Shell_TrayWnd]", "", "[Class:ToolbarWindow32;Instance:" & (@OSVersion = "WIN_10" ? 3 : 1) & "]") Many thanks indeed, kind Deye! I changed this UDF as per your code and modified it to accept an iWin value of 3 to represent Windows 10 ("2" for 7+ simply won't work under Win 10). After doing so, the icon count and icon title lists and so forth are working correctly, thanks to you! I'm continuing to try to modify the UDF to fully support Windows 10 and it's new NOTIFYICONDATA struct and all the other "system tray"-related changes made after Windows 7 (though I don't have any Windows 8 machines, so I don't know if that OS included these changes). This is certainly stretching my AutoIt / Windows knowledge! Perhaps you might be willing to examine the resulting code when I'm finished (which won't be very soon, I'm afraid...)
masvil Posted October 14, 2018 Posted October 14, 2018 On 2/25/2018 at 7:00 AM, Mbee said: I'm continuing to try to modify the UDF to fully support Windows 10 @Mbee can you please share your update version? I hope @wraithdu will update the original UDF soon or later.
masvil Posted October 14, 2018 Posted October 14, 2018 (edited) The following example should be "universal" because it checks ALL existing/valid instances on both hidden and visible icons. So it should be working on all past and future Windows vers unless the class(es) name will change. Note: there are some programs using a no-standard instance, but with my method you can catch those icons as well. expandcollapse popup#NoTrayIcon #include <GuiToolBar.au3> Local $VisibleIcons Local $HiddenIcons Local $Instance ; Find systray handle for "User Promoted Notification Area" $Instance = 0 While 1 $Instance = $Instance + 1 Local $hSysTray_Handle = ControlGetHandle("[Class:Shell_TrayWnd]", "", "[Class:ToolbarWindow32;Instance:" & $Instance & "]") If @error Then ExitLoop If Not @Compiled Then ConsoleWrite("VISIBLE at Istance #" & $Instance & ":" & @CRLF) Local $iSysTray_ButCount = _GUICtrlToolbar_ButtonCount($hSysTray_Handle) ; Get vidible systray icon count For $iSystray_ButtonNumber = 0 To $iSysTray_ButCount - 1 $text = _GUICtrlToolbar_GetButtonText($hSysTray_Handle, $iSystray_ButtonNumber) If Not @Compiled Then ConsoleWrite($text & @CRLF) Next If Not @Compiled Then ConsoleWrite(@CRLF) WEnd ; Find systray handle for "Overflow Notification Area" i.e. hidden icons $Instance = 0 While 1 $Instance = $Instance + 1 Local $hSysTray_Handle_Hidden = ControlGetHandle("[Class:NotifyIconOverflowWindow]", "", "[Class:ToolbarWindow32;Instance:" & $Instance & "]") If @error Then ExitLoop If Not @Compiled Then ConsoleWrite("HIDDEN at Istance #" & $Instance & ":" & @CRLF) $iSysTray_ButCount = _GUICtrlToolbar_ButtonCount($hSysTray_Handle_Hidden) ; Get hidden systray icon count For $iSystray_ButtonNumber = 0 To $iSysTray_ButCount - 1 $text = _GUICtrlToolbar_GetButtonText($hSysTray_Handle_Hidden, $iSystray_ButtonNumber) If Not @Compiled Then ConsoleWrite($text & @CRLF) Next WEnd Exit Edited October 14, 2018 by masvil
kosamja Posted July 3, 2019 Posted July 3, 2019 (edited) Just adding example for removing systray icon after explorer restart: expandcollapse popup;www.autoitscript.com/forum/topic/134538-get-systray-icons-solved #NoTrayIcon #RequireAdmin #include <Constants.au3> #include <GUIConstants.au3> #include <ScrollBarsConstants.au3> #include <WinAPISys.au3> #include <WinAPIProc.au3> #include <WinAPIMem.au3> #include <WinAPIHObj.au3> #include <WinAPIShellEx.au3> #include <WinAPISysWin.au3> #include <GuiToolbar.au3> #include <Process.au3> #include <Array.au3> Opt('SendKeyDelay', 0) Opt('MouseClickDelay', 0) Opt('SendKeyDownDelay', 0) Opt('MouseClickDownDelay', 0) Opt('MouseClickDragDelay', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) $SystrayIconsInfo = _GetAllSystrayIconsInfo() If IsArray($SystrayIconsInfo) Then _ArrayDisplay($SystrayIconsInfo) _RemoveSystrayIcon('process', 0, '', 'explorer.exe', 1225) _RegisterWinEventHook($EVENT_OBJECT_CREATE, $EVENT_OBJECT_LOCATIONCHANGE) If @error Then MsgBox($MB_OK, 'Info', 'Failed to register event hook.') Exit EndIf While 1 Sleep(1000) WEnd Func _RegisterWinEventHook($sEventMin, $sEventMax, $sProcessPid = 0, $sCallbackFunc = '_WinEventProc') $sWinEventProc = DllCallbackRegister($sCallbackFunc, 'none', 'ptr;dword;hwnd;long;long;dword;dword') $sWinEventHook = _WinAPI_SetWinEventHook($sEventMin, $sEventMax, DllCallbackGetPtr($sWinEventProc), $sProcessPid) Switch $sWinEventHook Case 0 Return SetError(1, 0, 0) Case Else Return SetExtended($sWinEventProc, $sWinEventHook) EndSwitch EndFunc Func _WinEventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) If not IsDeclared('__SystrayIconsCountList') Then Global $__SystrayIconsCountList[3][2] = [['Shell_TrayWnd', 'NotifyIconOverflowWindow'], [0, 0], [False, False]] Switch $iEvent Case $EVENT_OBJECT_CREATE, $EVENT_OBJECT_LOCATIONCHANGE If ($iEvent = $EVENT_OBJECT_CREATE and $iObjectID = $OBJID_CLIENT) or ($iEvent = $EVENT_OBJECT_LOCATIONCHANGE and $iObjectID = $OBJID_WINDOW) Then If _WinAPI_GetClassName($hWnd) = 'ToolbarWindow32' Then $sParentWndClass = _WinAPI_GetClassName(_WinAPI_GetAncestor($hWnd, $GA_ROOT)) Switch $sParentWndClass Case 'Shell_TrayWnd', 'NotifyIconOverflowWindow' $sParentWndIndex = 0 If $sParentWndClass = 'NotifyIconOverflowWindow' Then $sParentWndIndex = 1 $sSystrayIconsCount = _GUICtrlToolbar_ButtonCount($hWnd) If $sSystrayIconsCount < $__SystrayIconsCountList[1][$sParentWndIndex] Then $__SystrayIconsCountList[1][$sParentWndIndex] = 0 If $sSystrayIconsCount <> $__SystrayIconsCountList[1][$sParentWndIndex] Then $__SystrayIconsCountList[1][$sParentWndIndex] = $sSystrayIconsCount $__SystrayIconsCountList[2][$sParentWndIndex] = False Else If $iEvent = $EVENT_OBJECT_LOCATIONCHANGE and $__SystrayIconsCountList[1][$sParentWndIndex] > 0 and $__SystrayIconsCountList[2][$sParentWndIndex] = False Then $__SystrayIconsCountList[2][$sParentWndIndex] = True _RemoveSystrayIcon('process', 0, '', 'explorer.exe', 1225) EndIf EndIf EndSwitch EndIf EndIf EndSwitch EndFunc Func _GetAllSystrayIconsInfo($sSystrayWndHandle = 0) $sSystrayIconsTrayDataDllStructList = _GetSystrayIconsTrayDataDllStructList($sSystrayWndHandle) If @error Then Return SetError(1, @error, '') Local $sSystrayIconsInfoList[UBound($sSystrayIconsTrayDataDllStructList)][3] = [['Icon Text', 'Process Name', 'Icon Uid']] For $i = 1 to UBound($sSystrayIconsTrayDataDllStructList) - 1 $tTrayData = $sSystrayIconsTrayDataDllStructList[$i][2] $sSystrayIconsInfoList[$i][0] = _GUICtrlToolbar_GetButtonText($sSystrayIconsTrayDataDllStructList[$i][0], $sSystrayIconsTrayDataDllStructList[$i][1]) $sSystrayIconsInfoList[$i][1] = _ProcessGetName(WinGetProcess(DllStructGetData($tTrayData, 'hWnd'))) $sSystrayIconsInfoList[$i][2] = DllStructGetData($tTrayData, 'uID') Next Return $sSystrayIconsInfoList EndFunc Func _RemoveSystrayIcon($sMode, $sSystrayWndHandle = 0, $sSystrayIconTitle = '', $sProcessName = '', $sSystrayIconUid = 0) ;$sSystrayIconTitle contains list of full or partial icon titles (with | as delimiter) related to wanted systray icon ;$sMode values: title or process If $sMode <> 'title' and $sMode <> 'process' Then Return SetError(1, 0, False) If $sProcessName = 'explorer.exe' and not WinExists('[CLASS:PNIHiddenWnd]') Then Return SetError(2, 0, False) $sSystrayIconTrayDataInfoList = _GetSystrayIconTrayDataInfo($sMode, $sSystrayWndHandle, $sSystrayIconTitle, $sProcessName, $sSystrayIconUid) If @error Then Return SetError(3, @error, False) $tTrayData = $sSystrayIconTrayDataInfoList[2] If $sProcessName = 'explorer.exe' Then $sFuncReturn = _GUICtrlToolbar_DeleteButton($sSystrayIconTrayDataInfoList[0], $sSystrayIconTrayDataInfoList[1]) Else $tNotifyIconData = DllStructCreate($tagNOTIFYICONDATA) DllStructSetData($tNotifyIconData, 'Size', DllStructGetSize($tNotifyIconData)) DllStructSetData($tNotifyIconData, 'hWnd', DllStructGetData($tTrayData, 'hWnd')) DllStructSetData($tNotifyIconData, 'ID', DllStructGetData($tTrayData, 'uID')) $sFuncReturn = _WinAPI_ShellNotifyIcon($NIM_DELETE, $tNotifyIconData) EndIf If $sFuncReturn = False Then Return SetError(4, 0, False) If $sProcessName = 'explorer.exe' Then If @TrayIconVisible = 1 Then TraySetState($TRAY_ICONSTATE_HIDE) TraySetState($TRAY_ICONSTATE_SHOW) Else TraySetState($TRAY_ICONSTATE_SHOW) TraySetState($TRAY_ICONSTATE_HIDE) EndIf EndIf Return True EndFunc Func _GetSystrayIconTrayDataInfo($sMode, $sSystrayWndHandle = 0, $sSystrayIconTitle = '', $sProcessName = '', $sSystrayIconUid = 0) ;$sSystrayIconTitle contains list of full or partial icon titles (with | as delimiter) related to wanted systray icon ;$sMode values: title or process Local $sSystrayIconTrayDataInfoList[3] If $sMode <> 'title' and $sMode <> 'process' Then Return SetError(1, 0, '') $sSystrayIconsTrayDataDllStructList = _GetSystrayIconsTrayDataDllStructList($sSystrayWndHandle) If @error Then Return SetError(2, @error, '') $sMatchFound = False For $i = 1 to UBound($sSystrayIconsTrayDataDllStructList) - 1 $tTrayData = $sSystrayIconsTrayDataDllStructList[$i][2] Switch $sMode Case 'title' $sSystrayIconTitleList = StringSplit($sSystrayIconTitle, '|', $STR_ENTIRESPLIT) $sSystrayIconText = _GUICtrlToolbar_GetButtonText($sSystrayIconsTrayDataDllStructList[$i][0], $sSystrayIconsTrayDataDllStructList[$i][1]) For $j = 1 to $sSystrayIconTitleList[0] If StringInStr($sSystrayIconText, $sSystrayIconTitleList[$j]) Then $sMatchFound = True ExitLoop EndIf Next Case 'process' If _ProcessGetName(WinGetProcess(DllStructGetData($tTrayData, 'hWnd'))) = $sProcessName and DllStructGetData($tTrayData, 'uID') = $sSystrayIconUid Then $sMatchFound = True EndSwitch If $sMatchFound = True Then $sSystrayIconTrayDataInfoList[0] = $sSystrayIconsTrayDataDllStructList[$i][0] $sSystrayIconTrayDataInfoList[1] = $sSystrayIconsTrayDataDllStructList[$i][1] $sSystrayIconTrayDataInfoList[2] = $tTrayData ExitLoop EndIf Next If $sMatchFound = False Then Return SetError(3, 0, '') Return $sSystrayIconTrayDataInfoList EndFunc Func _GetSystrayIconsTrayDataDllStructList($sSystrayWndHandle = 0) Local $sReadBytes Local $sSystrayIconsTrayDataDllStructList[1][3] = [['Systray toolbar handle', 'Icon command identifier', 'TrayData DllStruct']] If @OSBuild < 7600 or IsHWnd($sSystrayWndHandle) or RegRead('HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer', 'EnableAutoTray') = '0' Then $sSystrayWndCount = 1 Else $sSystrayWndCount = 2 EndIf $sProcessHandle = _WinAPI_OpenProcess(BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ), False, WinGetProcess(WinGetHandle('[CLASS:Shell_TrayWnd]')), True) If $sProcessHandle = 0 Then Return SetError(1, 0, '') $sAllSystrayIconsCount = 0 For $i = 1 to $sSystrayWndCount If IsHWnd($sSystrayWndHandle) Then $sSystrayToolbarHandle = _GetSystrayToolbarHandle($sSystrayWndHandle) Else Switch $i Case 1 $sSystrayToolbarHandle = _GetSystrayToolbarHandle(WinGetHandle('[CLASS:Shell_TrayWnd]')) Case 2 $sSystrayToolbarHandle = _GetSystrayToolbarHandle(WinGetHandle('[CLASS:NotifyIconOverflowWindow]')) EndSwitch EndIf If IsHWnd($sSystrayToolbarHandle) Then $sSystrayIconsCount = _GUICtrlToolbar_ButtonCount($sSystrayToolbarHandle) If $sSystrayIconsCount > 0 Then ReDim $sSystrayIconsTrayDataDllStructList[UBound($sSystrayIconsTrayDataDllStructList) + $sSystrayIconsCount][3] For $j = 0 to $sSystrayIconsCount - 1 $sSystrayIconCommandId = _GUICtrlToolbar_IndexToCommand($sSystrayToolbarHandle, $j) $sSystrayIconParam = _GUICtrlToolbar_GetButtonParam($sSystrayToolbarHandle, $sSystrayIconCommandId) $tTrayData = DllStructCreate('hwnd hWnd;uint uID;uint uCallbackMessage;dword Reserved[2];ptr hIcon') _WinAPI_ReadProcessMemory($sProcessHandle, $sSystrayIconParam, DllStructGetPtr($tTrayData), DllStructGetSize($tTrayData), $sReadBytes) $sAllSystrayIconsCount +=1 $sSystrayIconsTrayDataDllStructList[$sAllSystrayIconsCount][0] = $sSystrayToolbarHandle $sSystrayIconsTrayDataDllStructList[$sAllSystrayIconsCount][1] = $sSystrayIconCommandId $sSystrayIconsTrayDataDllStructList[$sAllSystrayIconsCount][2] = $tTrayData Next EndIf EndIf Next _WinAPI_CloseHandle($sProcessHandle) ReDim $sSystrayIconsTrayDataDllStructList[$sAllSystrayIconsCount + 1][3] If UBound($sSystrayIconsTrayDataDllStructList) - 1 = 0 Then Return SetError(2, 0, '') Return $sSystrayIconsTrayDataDllStructList EndFunc Func _GetSystrayToolbarHandle($sSystrayWndHandle) Switch _WinAPI_GetClassName($sSystrayWndHandle) Case 'Shell_TrayWnd' If @OSBuild < 10240 Then Return ControlGetHandle($sSystrayWndHandle, '', '[CLASS:ToolbarWindow32; INSTANCE:1]') Else Return ControlGetHandle($sSystrayWndHandle, '', '[CLASS:ToolbarWindow32; INSTANCE:3]') EndIf Case 'NotifyIconOverflowWindow' Return ControlGetHandle($sSystrayWndHandle, '', '[CLASS:ToolbarWindow32; INSTANCE:1]') Case Else Return SetError(1, 0, 0) EndSwitch EndFunc Systray Icons Remover.au3 Edited July 5, 2019 by kosamja
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now