Jump to content

[Resolved] Clear lingering icons from systray of closed apps?


Recommended Posts

I have some great scripts that close some apps that I use when I don't want the apps that are scheduled to be run, yet I don't want to have to keep turning the scheduled tasks on and off all the time in the scheduler whenever it's not needed for them to run until the next time. The looping AI script has been the best solution for me. However, one side-effect is that the icons keep piling up. So if the app was closed 8 times in an hour, say, 8 icons are left in the systray until I move the mouse pointer over the tray, which clears it of them.

Can AI do this instead so that no lingering icons remain once apps are closed?

Thanks! :)

Edited by Diana (Cda)
Link to comment
Share on other sites

Awesome, thanks! This didn't come up in a search. Very different title: "_RefreshSystemTray(), Remove dead icons from Notification area" in the script forum. Kewl. Here is the script in question that clears the system tray:

; ===================================================================
; _RefreshSystemTray($nDealy = 1000)
;
; Removes any dead icons from the notification area.
; Parameters:
;    $nDelay - IN/OPTIONAL - The delay to wait for the notification area to expand with Windows XP's
;        "Hide Inactive Icons" feature (In milliseconds).
; Returns:
;    Sets @error on failure:
;        1 - Tray couldn't be found.
;        2 - DllCall error.
; ===================================================================
Func _RefreshSystemTray($nDelay = 1000)
; Save Opt settings
    Local $oldMatchMode = Opt("WinTitleMatchMode", 4)
    Local $oldChildMode = Opt("WinSearchChildren", 1)
    Local $error = 0
    Do; Pseudo loop
        Local $hWnd = WinGetHandle("classname=TrayNotifyWnd")
        If @error Then
            $error = 1
            ExitLoop
        EndIf

        Local $hControl = ControlGetHandle($hWnd, "", "Button1")
        
    ; We're on XP and the Hide Inactive Icons button is there, so expand it
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
            ControlClick($hWnd, "", $hControl)
            Sleep($nDelay)
        EndIf
        
        Local $posStart = MouseGetPos()
        Local $posWin = WinGetPos($hWnd)    
        
        Local $y = $posWin[1]
        While $y < $posWin[3] + $posWin[1]
            Local $x = $posWin[0]
            While $x < $posWin[2] + $posWin[0]
                DllCall("user32.dll", "int", "SetCursorPos", "int", $x, "int", $y)
                If @error Then
                    $error = 2
                    ExitLoop 3; Jump out of While/While/Do
                EndIf
                $x = $x + 8
            WEnd
            $y = $y + 8
        WEnd
        DllCall("user32.dll", "int", "SetCursorPos", "int", $posStart[0], "int", $posStart[1])
    ; We're on XP so we need to hide the inactive icons again.
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
            ControlClick($hWnd, "", $hControl)
        EndIf
    Until 1
    
; Restore Opt settings
    Opt("WinTitleMatchMode", $oldMatchMode)
    Opt("WinSearchChildren", $oldChildMode)
    SetError($error)
EndFunc; _RefreshSystemTray()
I tested it here at the office but couldn't see if it worked as no "dead" icons here at present. But will incorporate into my 2 scripts at home and test it there tomorrow.

Thanks! :)

Edited by Diana (Cda)
Link to comment
Share on other sites

I tried incorporating the refresh systray script above into my AI script but got error no matter where I put it. It's trouble with the "While" command again and understanding how to incorporate other stuff in with it so that it still works. Here's the original script I'm trying to change:

;
; AutoIt v3.0
;
#NoTrayIcon     ; AutoIt's icon doesn't show in systray
TraySetIcon(@ScriptDir & "\PUAC- CLOSE MP3Radio, SayTime, sndrec32.exe (wav).ico")


While 1

    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "MP3_RADIO.EXE" )
        ProcessClose ( "MP3_RADIO.EXE" )
    WEnd
    ;===== Close SayTime ===========================================
    While ProcessExists ( "SayTime95.exe" )
        ProcessClose ( "SayTime95.exe" )
    WEnd
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "sndrec32.exe" )
        ProcessClose ( "sndrec32.exe" )
    WEnd
    ;===============================================================
    
Sleep (10000)     ; Sleep for 60,000 units = 1 minute / 30,000=30 seconds / 15,000=15 seconds / 10,000=10 seconds / 5,000=5 seconds
WEnd

Any help appreciated. Thanks. :)

Link to comment
Share on other sites

Like I said above, this isn't working. Here is the complete script even though the icon clearing portion isn't in the right position (I'm guessing) for this to work. But I've included both portions so that people can see the complete script:

;
; AutoIt v3.0
;
#NoTrayIcon     ; AutoIt's icon doesn't show in systray
TraySetIcon(@ScriptDir & "\PUAC- CLOSE MP3Radio, SayTime, sndrec32.exe (wav).ico")


While 1

    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "MP3_RADIO.EXE" )
        ProcessClose ( "MP3_RADIO.EXE" )
    WEnd
    ;===== Close SayTime ===========================================
    While ProcessExists ( "SayTime95.exe" )
        ProcessClose ( "SayTime95.exe" )
    WEnd
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "sndrec32.exe" )
        ProcessClose ( "sndrec32.exe" )
    WEnd
    ;===============================================================
    
Sleep (10000)     ; Sleep for 60,000 units = 1 minute / 30,000=30 seconds / 15,000=15 seconds / 10,000=10 seconds / 5,000=5 seconds
WEnd


; ===================================================================
; _RefreshSystemTray($nDealy = 1000)
;
; Removes any dead icons from the notification area.
; Parameters:
;    $nDelay - IN/OPTIONAL - The delay to wait for the notification area to expand with Windows XP's
;        "Hide Inactive Icons" feature (In milliseconds).
; Returns:
;    Sets @error on failure:
;        1 - Tray couldn't be found.
;        2 - DllCall error.
; ===================================================================
Func _RefreshSystemTray($nDelay = 1000)
; Save Opt settings
    Local $oldMatchMode = Opt("WinTitleMatchMode", 4)
    Local $oldChildMode = Opt("WinSearchChildren", 1)
    Local $error = 0
    Do; Pseudo loop
        Local $hWnd = WinGetHandle("classname=TrayNotifyWnd")
        If @error Then
            $error = 1
            ExitLoop
        EndIf

        Local $hControl = ControlGetHandle($hWnd, "", "Button1")
       
    ; We're on XP and the Hide Inactive Icons button is there, so expand it
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
            ControlClick($hWnd, "", $hControl)
            Sleep($nDelay)
        EndIf
       
        Local $posStart = MouseGetPos()
        Local $posWin = WinGetPos($hWnd)   
       
        Local $y = $posWin[1]
        While $y < $posWin[3] + $posWin[1]
            Local $x = $posWin[0]
            While $x < $posWin[2] + $posWin[0]
                DllCall("user32.dll", "int", "SetCursorPos", "int", $x, "int", $y)
                If @error Then
                    $error = 2
                    ExitLoop 3; Jump out of While/While/Do
                EndIf
                $x = $x + 8
            WEnd
            $y = $y + 8
        WEnd
        DllCall("user32.dll", "int", "SetCursorPos", "int", $posStart[0], "int", $posStart[1])
    ; We're on XP so we need to hide the inactive icons again.
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then
            ControlClick($hWnd, "", $hControl)
        EndIf
    Until 1
   
; Restore Opt settings
    Opt("WinTitleMatchMode", $oldMatchMode)
    Opt("WinSearchChildren", $oldChildMode)
    SetError($error)
EndFunc; _RefreshSystemTray()
No matter where I've put the "clear icons in systray" portion (_RefreshSystemTray), I get error messages and the script doesn't work. If the clear icons portion is the correct syntax to clear the icon in the systray, then I believe, though it's just a guess, that it's because I'm dealing with a looping script.

Any help appreciated. Thanks! :)

p.s., lastly, can we make a UDF (is that the right term?) for the clear systray script? I just got to thinking that it might be nicer to just call this from the looping script above and to just stick all that code into the "Include" folder. Do I have that right? UDFs are what the scripts in the "Include" are called? Thx!

Link to comment
Share on other sites

Okay, trying again. I know there must be an answer to this; it's just perhaps maybe to ask in such a way that people understand my question (?). I guess I'm not doing a very good job of that. So here goes another stab at it.

As mentioned before, this script works just fine:

;
; AutoIt v3.0
;
#NoTrayIcon     ; AutoIt's icon doesn't show in systray
TraySetIcon(@ScriptDir & "\PUAC- CLOSE MP3Radio, SayTime, sndrec32.exe (wav).ico")


While 1
    
    SoundPlay (@ScriptDir & "\WAV-NEWYEAR21_TM01.WAV")     ; plays WAV file.
    
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "MP3_RADIO.EXE" )
        ProcessClose ( "MP3_RADIO.EXE" )
    WEnd
    ;===== Close SayTime ===========================================
    While ProcessExists ( "SayTime95.exe" )
        ProcessClose ( "SayTime95.exe" )
    WEnd
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "sndrec32.exe" )
        ProcessClose ( "sndrec32.exe" )
    WEnd
    ;===============================================================



Sleep (30000)     ; Sleep for 60,000 units = 1 minute / 30,000=30 seconds / 15,000=15 seconds / 10,000=10 seconds / 5,000=5 seconds
WEndoÝ÷ Øe¢l¦º)z¹rjw]¡ë-èèm8^b~'àz»®*m",µçZnÞy²yªåêæzËçhzËazƦz:{¦Ù趧©¥éì¶az'( zÖ°^néÜí馮)à{az̬¶¶²¶)e"f§¹©eÊ»§¶º»(®Þ®Ø^j·
¥u·­«b·lmçºÇßÛÞ¦ëmꮢ×%yªârìªê-¥ªí{azåÊZqâ¢}ý¶­jw«®Ú~׫¶v¥ªê-Yéݪê-nëiz¸Z¦ËajÝý³rجmÂäxØ^¬­Â­v$7ß}å¶-Z§"­¶­ªê-rW®'(Ê®¢Öâµ·¢·­ê®¢Ô¥yêwÓM4ªê-iº/zX¤zØb±«­¢+Ø%]¡¥±AɽÍÍá¥ÍÑÌ ÅÕ½Ðí͹ÉÌȹáÅÕ½Ðì¤($%AɽÍÍ
±½Í ÅÕ½Ðí͹ÉÌȹáÅÕ½Ðì¤(%]¹($ìôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô(((()m±È¥½¹ÌÍÉ¥ÁÑt(ìôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô(ì}IÉÍ¡MåÍѵQÉä ÀÌØí¹±äôÄÀÀÀ¤¸¸¸Ñ¸((((()M±À ÄÀÀÀÀ¤ìM±À½ÈØÀ°ÀÀÀÕ¹¥ÑÌôĵ¥¹ÕѼÌÀ°ÀÀÀôÌÀͽ¹Ì¼ÄÔ°ÀÀÀôÄÔͽ¹Ì¼ÄÀ°ÀÀÀôÄÀͽ¹Ì¼Ô°ÀÀÀôÔͽ¹Ì)]¹
I get this error:

Line 43 ...

Func_RefreshSystemTray($nDelay = 1000)

Error:  "While" statement has no matching "Wend" statement.

Anyone have any idea what will fix this? Thanks! :D

Link to comment
Share on other sites

The code by Valik that you've added to your script is the definition of a user-defined function. Adding it to your script and making no other changes doesn't change the behavior of your script; you need to add a call to Valik's function like:

_RefreshSystemTray()

...to make your script perform the action that the function is made to do. When calling a function defined like Valik's was you can either call it like I have above with nothing inside the parentheses and it will behave in a default manner, or if you understand the working of the function you can put your own value inside to change the behavior.

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

Okay, confusing. You guys know so much; me, not so much at all, so pls bear with me.

I tried this, first, because it looked like an INCLUDE file with the _ in front, so after dumping the file into the INCLUDE folder, I changed code to this:

;
; AutoIt v3.0
;
#Include <_RefreshSystemTray.au3>oÝ÷ Ø­¡÷(º»ax!j^çR¢ØZ·¬¦ºi¹rj«¨µÝýº®¢Ûax-¡Ú%¶-|°k*ÞÞvØZµ©Ý¶§¦[§çbµÚ0«¢YhÂËa¢è!¶¢Z.®)à¶]è§IÈØZ¶Øb³
.Ù÷öÜ(®BÙ÷öص©òzºè®g¬±¨²ØhºZºÚ"µÍÚ[HØÙÜÑ^ÝÈ
    ][ÝÜÛXÌÌ^I][ÝÈ
BØÙÜÐÛÜÙH
    ][ÝÜÛXÌÌ^I][ÝÈ
BÑ[ÏOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOBÔYÚÞÝ[U^K]LÂÛY
L
HÈÛYÜ
[]ÈHHZ[]HÈÌLÌÙXÛÛÈÈMKLMHÙXÛÛÈÈLLLÙXÛÛÈÈ
KMHÙXÛÛÂÑ[oÝ÷ Ù­¶¢rì²Ø¥ËZÊ)íë2²ÚÚÊéíR&j{«º{ayË«²è½êíë2²×¦¶¶²j·û^®­¶)àjw«®éj»"èÆØhº]¢}ý¶IèÂ'â·¬­éZµçm¢Øb²ÚâjZ+Hzw^vê©àx-æ¢÷­¡«­¢+Ø%]¹($ìôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôôô()M¡±±áÕÑ¡MÉ¥ÁѥȵÀìÅÕ½ÐìÀäÈí}IÉÍ¡MåÍѵQÉä¹ÔÌÅÕ½Ðì¤()M±À ÄÀÀÀÀ¤ìM±À½ÈØÀ°ÀÀÀÕ¹¥ÑÌôĵ¥¹ÕѼÌÀ°ÀÀÀôÌÀͽ¹Ì¼ÄÔ°ÀÀÀôÄÔͽ¹Ì¼ÄÀ°ÀÀÀôÄÀͽ¹Ì¼Ô°ÀÀÀôÔͽ¹Ì)]¹

But still nothing. I have to move the cursor over myself <sigh>.

_Now_ what am I doing wrong, pls?? :D

Link to comment
Share on other sites

perhaps...

;
; AutoIt v3.0
;
#NoTrayIcon     ; AutoIt's icon doesn't show in systray
TraySetIcon(@ScriptDir & "\PUAC- CLOSE MP3Radio, SayTime, sndrec32.exe (wav).ico")


While 1
    
    SoundPlay (@ScriptDir & "\WAV-NEWYEAR21_TM01.WAV")     ; plays WAV file.
    
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "MP3_RADIO.EXE" )
        ProcessClose ( "MP3_RADIO.EXE" )
    WEnd
    ;===== Close SayTime ===========================================
    While ProcessExists ( "SayTime95.exe" )
        ProcessClose ( "SayTime95.exe" )
    WEnd
    ;===== Close MP3Radio.exe ======================================
    While ProcessExists ( "sndrec32.exe" )
        ProcessClose ( "sndrec32.exe" )
    WEnd
    ;===============================================================
   
    _RefreshSystemTray()

   Sleep (30000)     ; Sleep for 60,000 units = 1 minute / 30,000=30 seconds / 15,000=15 seconds / 10,000=10 seconds / 5,000=5 seconds
WEnd

; ===================================================================
; _RefreshSystemTray($nDealy = 1000)
;
; Removes any dead icons from the notification area.
; Parameters:
;    $nDelay - IN/OPTIONAL - The delay to wait for the notification area to expand with Windows XP's
;        "Hide Inactive Icons" feature (In milliseconds).
; Returns:
;    Sets @error on failure:
;        1 - Tray couldn't be found.
;        2 - DllCall error.
; ===================================================================
Func _RefreshSystemTray($nDelay = 1000)
; Save Opt settings
    Local $oldMatchMode = Opt("WinTitleMatchMode", 4)
    Local $oldChildMode = Opt("WinSearchChildren", 1)
    Local $error = 0
    Do; Pseudo loop
        Local $hWnd = WinGetHandle("classname=TrayNotifyWnd")
        If @error Then
            $error = 1
            ExitLoop
        EndIf

        Local $hControl = ControlGetHandle($hWnd, "", "Button1")
        
    ; We're on XP and the Hide Inactive Icons button is there, so expand it
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then 
            ControlClick($hWnd, "", $hControl)
            Sleep($nDelay)
        EndIf
        
        Local $posStart = MouseGetPos()
        Local $posWin = WinGetPos($hWnd)    
        
        Local $y = $posWin[1]
        While $y < $posWin[3] + $posWin[1]
            Local $x = $posWin[0] 
            While $x < $posWin[2] + $posWin[0]
                DllCall("user32.dll", "int", "SetCursorPos", "int", $x, "int", $y)
                If @error Then
                    $error = 2
                    ExitLoop 3; Jump out of While/While/Do
                EndIf
                $x = $x + 8
            WEnd
            $y = $y + 8
        WEnd
        DllCall("user32.dll", "int", "SetCursorPos", "int", $posStart[0], "int", $posStart[1])
    ; We're on XP so we need to hide the inactive icons again.
        If $hControl <> "" And ControlCommand($hWnd, "", $hControl, "IsVisible") Then 
            ControlClick($hWnd, "", $hControl)
        EndIf
    Until 1
    
; Restore Opt settings
    Opt("WinTitleMatchMode", $oldMatchMode)
    Opt("WinSearchChildren", $oldChildMode)
    SetError($error)
EndFunc; _RefreshSystemTray()

f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Link to comment
Share on other sites

YES!!!

Gawd, always so easy when you know how. Know I know what _....() can do, that's how you "call" another function, I'm guessing. I didn't know this one.

And it seems to be working just great. I added it to two scripts that near to clear the sytray of icons once it closes apps. Perfect. Life just gets easier and easier once I have an AI solution to aggravations such as this. Such as coming back to the computer and having 16 icons still showing up taking up valuable systray real estate <lol>. Not any longer!!

Thanks! Much appreciated. :D

Edited by Diana (Cda)
Link to comment
Share on other sites

  • 3 months later...

(This post for other newbies, mainly.)

UDF = User Defined Function = #Include.
Taken me a bit, but out of all the things to remember in AI, I now know this ... finally! <g>.

I tried referencing the system refresh UDF again in all these types of scripts and they work just fine now. Could put the newly renamed "_SYSTRAY, refresh.au3" back into the "Include" UDF folder and just reference it from the scripts. I think what stumped me at the time may have been how to deal with something other than "$" symbol calling the UDF; the "_" and "()" must have thrown me back then. The tremendous amount of work and experience since then made it a breeze this morning when I tackled this again.

Edited and modified slightly, here is an example of the "close if running" type of script. Found that rather than turning off items in the scheduler, easier to run this manually. It's set to work every X number of seconds and has advantage that the freeware still manages to have enough time to speak the time with the frequency I need (sheduler launches that app every 5 minutes during the hectic part of getting ready in the morning!). SayTime95 has set times of speaking out time at every quarter hour, half hour and hour only! Nothing less than every 15 mins. So this AI systray script has added advantage that not only does it close all these app, then clears all the icons from systray but I still get benefit of hearing time every 5 minutes! Also, before adding the refresh part, if this closed those apps 6 or 7 times, I'd come back to a tray cluttered with residual icons no matter what XP settings there were!

;
; AutoIt 3x
;
#Include <_SYSTRAY, refresh.au3>
#NoTrayIcon     ; AutoIt's icon doesn't show in systray
TraySetIcon(@ScriptDir & "\PUAC- CLOSE MP3Radio, SayTime, sndrec32.exe.ico")


While 1

    ;===== Close MP3 player =========================================
    While ProcessExists("Xion.exe")     ; freeware MP3 player
        ProcessClose("Xion.exe")
    WEnd
    ;===== Close Sound Recorder ======================================
    While ProcessExists("sndrec32.exe")     ; default app for WAVs; set to automatically play sounds on app launch
        ProcessClose("sndrec32.exe")
    WEnd
    ;===== Close SayTime ===========================================
    While ProcessExists("SayTime95.exe")     ;  freeware that reads out time
        Sleep(750)
        ProcessClose("SayTime95.exe")
    WEnd
    ;===============================================================

_RefreshSystemTray()     ; (note:  "_...()" rather than what has been more usual for you till now "$")

Sleep (10000)     ; Sleep for 60,000 units = 1 minute / 30,000=30 seconds / 15,000=15 seconds / 10,000=10 seconds / 5,000=5 seconds
WEnd

Cheers! muttley

Edited by Diana (Cda)
Link to comment
Share on other sites

  • 13 years later...

Does the above code work by AutoIt moving the mouse? Is this something you can see, or does it happen instantly without noticing it? I came up with some simpler code, but you have to wait while it clears the phantom icons.

In order for this to work, you have to make sure the program icon is always visible on the taskbar which you can do by just dragging the icon from the upper part of the system tray to the taskbar or by selecting in Windows Settings that the icon should always be on the taskbar.  This code just moves the mouse over the icons.

If Mod($x, 10) = 0 Then
    MouseMove(@DesktopWidth - 150, @DesktopHeight - 15)
    MouseMove(@DesktopWidth - 600, @DesktopHeight - 15, 10)
    MouseMove(@DesktopWidth - 150, @DesktopHeight - 15)
    MouseMove(@DesktopWidth - 600, @DesktopHeight - 15, 10)
EndIf

The first and last lines are only necessary if you are closing and opening the program numerous times, and you want to clear them every 10 times of opening and closing the program. 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...