Jump to content
Sign in to follow this  
Decipher

_ToggleSystemTrayState with support for specific icons

Recommended Posts

I was helping another user the other day And decided To make a UDF so here it is. Let me know what ya think. ;)

#include-once
#include <GuiListView.au3>

Global Const $SW_HIDENA = 2, $SW_HIDENOACTIVE = 2

; Examples are below.

; #FUNCTION# ====================================================================================================================
; Name ..........: _ToggleSystemTrayState
; Description ...: Hide/Show System Tray Icons by Name or Set the State for all Icons
; Syntax ........: _ToggleSystemTrayState([$vTrayItems = ""[, $iStartSearchIndex = 0[, $iSystemTrayState = 0[, $iDebug = 0]]]])
; Parameters ....: $vTrayItems           - [optional] A variant value. Default is "".
;                $iStartSearchIndex - [optional] An integer value. Default is 0. Set this to -1 to search from end to start.
;                $iSystemTrayState - [optional] An integer value. Default is 0.
;                $iDebug             - [optional] An integer value. Default is 0. Set this to either @SW_SHOW or 1 to see dialogs and debug information.
; Return values .: None
; Author ........: Decipher
; Modified ......:
; Remarks .......: Tested only on XP
;
; $iSystemTrayState can be one of the following:
; @SW_SHOW == ALWAYS_SHOW == 5
; @SW_HIDE == ALWAYS_HIDE == 0
; $SW_HIDENA == HIDE WHEN INACTIVE == 2
;
; $vTrayItems can be a string for a specific icon or an array for multiple icons
; There is no error checking implemented but feel free to change it to your needs.
;
; Related .......:
; Link ..........:
; Example .......: Yes, The examples need to be uncommented to run. Remove the ( ;- ) prefix on the example to be ran.
; ===============================================================================================================================


    ;;;; Set all icons to hide when inactive. ;;;;
;-    _ToggleSystemTrayState($SW_HIDENA) ; Example #1

    ;;;; Hide all system tray icons. ;;;;
;-    _ToggleSystemTrayState(@SW_HIDE) ; Example #2

    ;;;; Show two specific icons. ;;;;
;-    Local $aIcons[2] = ["Local Area Connection", "Volume"] ; Example #3
;-    _ToggleSystemTrayState($aIcons, 0, @SW_SHOW)

    ;;;; Hide a specific icon. ;;;;
;-    _ToggleSystemTrayState("Volume", 0, @SW_HIDE) ; Example #4

    ;;;; Show all system tray icons. ;;;;
;-    _ToggleSystemTrayState(@SW_SHOW) ; Example #5

    ;;;; Hide all system tray icons but show the dialogs aka debug mode and log the names of the icons hidden. ;;;;
;-    _ToggleSystemTrayState("", 0, @SW_HIDE, 1) ; Example #6


Func _ToggleSystemTrayState($vTrayItems = "", $iStartSearchIndex = 0, $iSystemTrayState = 0, $iDebug = 0)
    If IsInt($vTrayItems) Then
        $iSystemTrayState = $vTrayItems
        $vTrayItems = ""
    EndIf
    Local Const $sOPTIONS_DIALOG_PROCESS = "rundll32.exe shell32.dll, Options_RunDLL 1"
    Local Const $sTASKBAR_PROPERTIES_TITLE = "[TITLE:Taskbar and Start Menu Properties; CLASS:#32770; INSTANCE:1]"
    Local Const $sCUSTOMIZE_BUTTON = "[ClassnameNN:Button10]", $sSENDKEYS = "!c"
    Local Const $sTASKBAR_CUSTOMIZE_TITLE = "[TITLE:Customize Notifications; CLASS:#32770; INSTANCE:1]"
    Local Const $sTRAYICONS_LISTVIEW = "[CLASS:SysListView32; INSTANCE:1]"
    Local Const $sLISTVIEW_COMBOX_CONTROL = "[CLASS:ComboBox; INSTANCE:1]"
    Local Const $sTASKBAR_CHILD_OK_BUTTON = "[CLASS:Button; INSTANCE:2]"
    Local Const $iRUNDLL32 = Run($sOPTIONS_DIALOG_PROCESS)
    WinWait($sTASKBAR_PROPERTIES_TITLE, "", 2000)
    Local Const $hTASKBAR_DIALOG = WinGetHandle($sTASKBAR_PROPERTIES_TITLE)
    WinSetState($hTASKBAR_DIALOG, "", $iDebug)
    ControlSend($hTASKBAR_DIALOG, "", ControlGetHandle($hTASKBAR_DIALOG, "", $sCUSTOMIZE_BUTTON), $sSENDKEYS)
    WinWait($sTASKBAR_CUSTOMIZE_TITLE, "", 2000)
    $hTASKBAR_CHILD_DIALOG = WinGetHandle($sTASKBAR_CUSTOMIZE_TITLE)
    WinSetState($hTASKBAR_CHILD_DIALOG, "", $iDebug)
    Local Const $hDIALOG_LISTVIEW = ControlGetHandle($hTASKBAR_CHILD_DIALOG, "", $sTRAYICONS_LISTVIEW)
    Local $iListViewItem = 0, $hComboBox_Instance = 0, $aTrayIcon[1], $iTrayIcon, $iSkipTask = False, $sTrayItemText
    If IsArray($vTrayItems) Or $vTrayItems <> "" Then
        If Not IsArray($vTrayItems) Then
            $aTrayIcon[0] = $vTrayItems
        Else
            $aTrayIcon = $vTrayItems
        EndIf
        For $i = 0 To UBound($aTrayIcon, 1) - 1 Step 1
            $iTrayIcon = _GUICtrlListView_FindInText($hDIALOG_LISTVIEW, $aTrayIcon[$i], $iStartSearchIndex)
            If $iDebug Then
                ConsoleWrite("Tray Icon: " & @TAB & _GUICtrlListView_GetItemText($hDIALOG_LISTVIEW, $iTrayIcon) & @CRLF)
            EndIf
            _GUICtrlListView_SetItemFocused($hDIALOG_LISTVIEW, $iTrayIcon)
            $hComboBox_Instance = ControlGetHandle($hTASKBAR_CHILD_DIALOG, "", $sLISTVIEW_COMBOX_CONTROL)
            ControlSend($hTASKBAR_CHILD_DIALOG, "", $hDIALOG_LISTVIEW, "{SPACE}")
            For $iLoopIndex = 1 To 3 Step 1
                ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{DOWN}")
            Next
            If $iSystemTrayState <> 5 Then
                ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{UP}")
                If $iSystemTrayState = 2 Then
                    ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{UP}")
                EndIf
            EndIf
        Next
        $iSkipTask = True
    EndIf
    While WinExists($hTASKBAR_CHILD_DIALOG)
        If $iSkipTask Then
            ExitLoop
        EndIf
        If $iListViewItem >= _GUICtrlListView_GetItemCount($hDIALOG_LISTVIEW) + 1 Then
            ExitLoop
        EndIf
        $iListViewItem += 1
        ControlFocus($hTASKBAR_CHILD_DIALOG, "", $hDIALOG_LISTVIEW)
        If $iDebug Then
            $sTrayItemText = _GUICtrlListView_GetItemText($hDIALOG_LISTVIEW, $iListViewItem)
            If $sTrayItemText <> "" Then
                ConsoleWrite("Tray Icon: " & @TAB & $sTrayItemText & @CRLF)
            EndIf
        EndIf
        $hComboBox_Instance = ControlGetHandle($hTASKBAR_CHILD_DIALOG, "", $sLISTVIEW_COMBOX_CONTROL)
        For $i = 1 To 3 Step 1
            ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{DOWN}")
        Next
        If $iSystemTrayState <> 5 Then
            ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{UP}")
            If $iSystemTrayState = 2 Then
                ControlSend($hTASKBAR_CHILD_DIALOG, "", $hComboBox_Instance, "{UP}")
            EndIf
        EndIf
        ControlSend($hTASKBAR_CHILD_DIALOG, "", $hDIALOG_LISTVIEW, "{DOWN}")
    WEnd
    ControlSend($hTASKBAR_CHILD_DIALOG, "", $sTASKBAR_CHILD_OK_BUTTON, "{ENTER}")
    WinClose($hTASKBAR_DIALOG)
    If ProcessExists($iRUNDLL32) Then
        ProcessClose($iRUNDLL32)
    EndIf
EndFunc   ;==>_ToggleSystemTrayState
Edited by Decipher

Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites

JohnOne,

Do you mind elaborating as to how your implementing the UDF?

Are you just running the example? What OS version are you using?

The best of my knowledge this function works as advertised when used appropiately. ;)

Anonymous


Spoiler

censored.jpg

 

Share this post


Link to post
Share on other sites

This UDF depends on the dialog's design remain unchanged which might not be the case with version of Windows after XP. I have updated the examples where you can understand how to use them.


Spoiler

censored.jpg

 

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By yffulf
      Is there probably a way to click ie popup button and hide or invisible popup button in the same time?
      I try to use WinSetState @SW_hide ,
      the result is ie crashing or no response because button hide and the next click command won't work...
      $oForm=_IEFormGetObjByName($oIE,"form1") $obutton=_IEFormElementGetObjByName($oForm,"btn_OK") $hWnd = _IEPropertyGet($oIE, "hwnd") _IEAction($obutton,"focus") ControlSend($hWnd, "", "[CLASS:Internet Explorer_Server; INSTANCE:1]", "{Enter}") WinWait("", "確定存檔嗎?") WinSetState("","確定存檔嗎?",@SW_Hide) ControlClick("", "確定存檔嗎?", "[CLASS:Button; TEXT:確定; Instance:1;]")  
    • By MONaH-Rasta
      Opt('TrayAutoPause', 0) $iTray1 = TrayCreateItem('Tray 1') TrayItemSetState(-1, 1) TrayCreateItem('') $iTrayMenu1 = TrayCreateMenu('Tray Menu 1') $iTray2 = TrayCreateItem('Tray 2', $iTrayMenu1, -1, 1) TrayItemSetState(-1, 1) $iTray3 = TrayCreateItem('Tray 3', $iTrayMenu1, -1, 1) $iTray4 = TrayCreateItem('Tray 4', $iTrayMenu1, -1, 1) TrayCreateItem('') $iTrayMenu2= TrayCreateMenu('Tray Menu 2') $iTray5 = TrayCreateItem('Tray 5', $iTrayMenu2, -1, 1) TrayItemSetState(-1, 1) $iTray6 = TrayCreateItem('Tray 6', $iTrayMenu2, -1, 1) $iTray7 = TrayCreateItem('Tray 7', $iTrayMenu2, -1, 1) TrayCreateItem('') $iTray8 = TrayCreateItem('Tray 8') $iTray9 = TrayCreateItem('Tray 9') $iTray10 = TrayCreateItem('Tray 10') TrayItemSetState(-1, 1) While True Sleep(1000*5) WEnd When I click on Tray 3 / Tray 4 / Tray 6 / Tray 7 nothing happens. Only Tray 2 and Tray 5 stay checked.
      I have tried setting 
      Opt("TrayMenuMode", 8) In this case radio menuitems act like normal menuitems only looks different.
      I'm using AutoIt v3.3.14.5.
      Tested on Windows 10 LTSC 2019 (1809) x64 version: 10.0.17763 build 17763.475 and Windows Server 2008 R2.
      Tried run script x64 and x86 same result.
      Is this kind a bug or something?
    • By morion84
      Hi, when I call a MsgBox function I can use a "$MB_SERVICE_NOTIFICATION" flag so it will be displayed "on the current active desktop, even if there is no user logged on to the computer.". That works just great. Is there a way to do the same to Autoit GUI Form so it will be visible on desktop even if running from system account and user is not logged?
    • By argumentum
      So I'm coding in win 10, ..every thing looks nice but then I think, what about XP, ...ugly, but I make it pretty again, no problem. Lets check in Win 7 and here is my conundrum.
      Win 10, DRM is on, XP is off ( well, non-existant ), so far so good. I decide to make it the "switch" to enable or disable the checkbox in the context menu.
      Win 7 ... I try to apply the same logic and:
      DRM on:

       
      DRM off:

       
      now, "Windows 7 Basic": DRM is off


      Question: how should I determine if to hide the check-mark or not?, Is there a way to know that this theme is ? or better yet, how can I know that the theme is classic ?
      Thanks
      PS: I know that the code is not here but I think that my trend of thought would make it irrelevant anyway.
       
    • By dimm
      Is it possible to compile script without any icon resources included?
      When I make exe it uses default system icon of current OS even if I compile as console application.
      On other versions of Windows it looks a little strange

       
      Update:
      It seems that the only way is remove icons from exe after compilation using resource editors like ResHacker.

       
      another bad solution:
      Using corrupted 35 bytes icon file. Windows can't load it and shows default system icon.
      #pragma compile(Icon, broken.ico) broken.ico
×
×
  • Create New...