Jump to content
Sign in to follow this  
Decipher

_ToggleSystemTrayState with support for specific icons

Recommended Posts

Decipher

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
Decipher

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
Decipher

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  

  • Similar Content

    • dimm
      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
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      First, I want to apologize with you for the title not very clear, but I thought a little bit on which title to set at the thread, and this is the one that came in mind.
      Now, let me explain what I'm trying to understand.

      I am making an application ( with n clients ), with an SQLite Database, which has a Main form, and n sub-forms... 
      Since these sub-forms are called several times, because they are used to add or update records to the Database, I put the code that generates the GUI of these sub-forms in Functions.
      There are two sub-forms which are "treated" as two main forms, since even them have n sub-forms, which perform various tasks.
      Where am I stucked?

      For the Main form I created a Status Bar, in order to display messages ( add/delete/update/search results ), and it works perfectly with all the forms which don't have other sub-forms.
      For the two forms, which indeed have n sub-forms, I created two separated Status Bars, which are (re)created everytime I call the function that then displays the form.
      Practically, I can't set icons to these two Status Bars, and I don't know why.
      I'm really sorry that I don't feel clear enough, so, here you are an example of what I am saying.
      I recreated exactly what my script does:
      #include <GuiButton.au3> #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $frmSubForm, _ $txtSubFormField, _ $sbSubFormStatusBar, _ $objSB_IconError = _WinAPI_LoadShell32Icon(109), _ $objSB_IconInformation = _WinAPI_LoadShell32Icon(277) #Region ### START Koda GUI section ### Form= $frmMainForm = GUICreate("Main Form", 300, 300, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "ExitApplication") $sbMainStatusBar = _GUICtrlStatusBar_Create($frmMainForm) $btnCreateSubForm = GUICtrlCreateButton("Create Sub Form", 105, 110, 75, 41, BitOR($BS_CENTER,$BS_VCENTER,$BS_MULTILINE)) GUICtrlSetOnEvent(-1, "GenerateSubForm") GUICtrlSetFont(-1, 10, 400, 0, "Arial") _GUICtrlStatusBar_SetSimple($sbMainStatusBar) _GUICtrlStatusBar_SetText($sbMainStatusBar, "") GUISetState(@SW_SHOW, $frmMainForm) #EndRegion ### END Koda GUI section ### While 1 Sleep(100) WEnd Func ExitApplication() Exit EndFunc Func GenerateSubForm() #Region ### START Koda GUI section ### Form= $frmSubForm = GUICreate("Sub-Form", 300, 300, -1, -1, -1, -1, $frmMainForm) GUISetOnEvent($GUI_EVENT_CLOSE, "DeleteSubForm") $txtSubFormField = GUICtrlCreateInput("", 0, 0, 100, 20) $btnCheckSubFormField = GUICtrlCreateButton("Check Field", 105, 110, 75, 41, BitOR($BS_CENTER,$BS_VCENTER,$BS_MULTILINE)) GUICtrlSetOnEvent(-1, "CheckSubFormField") GUICtrlSetFont(-1, 10, 400, 0, "Arial") $sbSubFormStatusBar = _GUICtrlStatusBar_Create($frmSubForm) _GUICtrlStatusBar_SetSimple($sbSubFormStatusBar) _GUICtrlStatusBar_SetText($sbSubFormStatusBar, "") GUISetState(@SW_SHOW, $frmSubForm) GUISetState(@SW_DISABLE, $frmMainForm) #EndRegion ### END Koda GUI section ### EndFunc Func DeleteSubForm() ; Declared Globally => $frmSubForm GUIDelete($frmSubForm) GUISetState(@SW_ENABLE, $frmMainForm) EndFunc Func WriteToStatusBar($sbStatusBar, $objSB_Icon, $strText) _GUICtrlStatusBar_SetIcon($sbStatusBar, 0, $objSB_Icon) _GUICtrlStatusBar_SetText($sbStatusBar, $strText) ConsoleWrite("Icon Handle: " & $objSB_Icon & @CRLF) EndFunc Func CheckSubFormField() ; Declared Globally => $txtSubFormField If GUICtrlRead($txtSubFormField) = "" Then ; Declared Globally => $sbStatusBar WriteToStatusBar($sbSubFormStatusBar, $objSB_IconError, "Field NOK.") Else WriteToStatusBar($sbSubFormStatusBar, $objSB_IconInformation, "Field OK.") EndIf EndFunc The text is set, but icon is not.
      Could someone please tell me why?
      Thanks everyone in advance  

      Best Regards.
    • buymeapc
      By buymeapc
      Hi all,
      I'm trying to create a listview with subitem icons and I achieved this by simply rearranging the order of the columns, so that the first column is in the middle, thus appearing as a subitem with an icon - this method prevents the "icon clipping" that happens when using subitem icons in a listview. My issue is that when I select a row that does not have an icon, the space where the icon would be is white. Is there a way to make this transparent, so it looks like the entire row is selected?
      Here's an example - click the second listview item/row to see a blank space where the icon would be.
      #include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <GuiImageList.au3> #include <WindowsConstants.au3> _Main() Func _Main() Local $hGui, $listview, $hImage Local $iLV_EXStyle_NoChecks = BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_DOUBLEBUFFER, $LVS_EX_HEADERDRAGDROP) $hGui = GUICreate("Listview Test With Icons", 400, 300) $listview = GUICtrlCreateListView("Col 1|Col 2|Col 3", 2, 2, 394, 268, BitOR($LVS_REPORT, $LVS_SHAREIMAGELISTS)) _GUICtrlListView_SetExtendedListViewStyle($listview, $iLV_EXStyle_NoChecks) GUISetState() ; Create the image list $hImage = _GUIImageList_Create(16, 16, 5, 3) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 165) _GUICtrlListView_SetImageList($listview, $hImage, 1) ; Set the order so the first column is moved to the middle, ; acting like a subitem with an icon _GUICtrlListView_SetColumnOrder($listview, "1|0|2") ; Add the items GUICtrlCreateListViewItem("Item1|Item2|Item3", $listview) GUICtrlCreateListViewItem("Item4|Item5|Item6", $listview) ; Set an icon for just the first item _GUICtrlListView_SetItemImage($listview, 0, 0) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>_Main  
    • ur
      By ur
      I need to read the status of OneDrive icon running in the taskbar and update the status in a log file.
      2nd part I can complete
      But the first part, how to read the status of tray menu icon.

      I need the text above from the tray icon.
      I looked into , but not that helpful.
       
       
    • GordonFreeman
      By GordonFreeman
      Hi, i searched some topics but cannot found a simple way to do that:
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 615, 438, 192, 124) GUISetState(@SW_SHOW) ; I tried this but user reported that it work in 2006, not seems work actually $filemenu = GUICtrlCreateMenu ("&File") $fileitem = GUICtrlCreateMenuitem ("Open",$filemenu) GuiCtrlSetImage($fileitem, "shell32.dll", 4) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Also tried:
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 615, 438, 192, 124) GUISetState(@SW_SHOW) $filemenu = TrayCreateMenu("&File") $fileitem = TrayCreateItem("Open",$filemenu) ;GuiCtrlSetImage($fileitem, "shell32.dll", 4) ;GuiCtrlSetImage(TrayItemGetHandle($fileitem), "shell32.dll", 4) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Well.. thanks in advance!
       
      Ok. I found this working example from Yashied. If i cannot find a simple then i will go with it
      #Include <GUIConstantsEx.au3> #Include <GUIMenu.au3> #Include <Constants.au3> #Include <WinAPI.au3> #Include <WindowsConstants.au3> Opt('MustDeclareVars', 1) Global $hMenu, $hForm, $hFile = 1000, $idNew, $idExit $hForm = GUICreate('Menu', 400, 300) $hFile = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_InsertMenuItem ($hFile, 0, ' &Favorites', $idNew) _GUICtrlMenu_InsertMenuItem ($hFile, 1, '', 0) _GUICtrlMenu_InsertMenuItem($hFile, 2, ' E&xit', $idExit) $hMenu = _GUICtrlMenu_CreateMenu() _GUICtrlMenu_InsertMenuItem($hMenu, 0, '&File', 0, $hFile) _GUICtrlMenu_SetMenu($hForm, $hMenu) _GUICtrlMenu_SetItemBmp($hFile, 0, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 43, 16, 16)) _GUICtrlMenu_SetItemBmp($hFile, 2, _CreateBitmapFromIcon(_WinAPI_GetSysColor($COLOR_MENU), @SystemDir & '\shell32.dll', 27, 16, 16)) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func _CreateBitmapFromIcon($iBackground, $sIcon, $iIndex, $iWidth, $iHeight) Local $hDC, $hBackDC, $hBackSv, $hIcon, $hBitmap $hDC = _WinAPI_GetDC(0) $hBackDC = _WinAPI_CreateCompatibleDC($hDC) $hBitmap = _WinAPI_CreateSolidBitmap(0, $iBackground, $iWidth, $iHeight) $hBackSv = _WinAPI_SelectObject($hBackDC, $hBitmap) $hIcon = _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight) If Not @error Then _WinAPI_DrawIconEx($hBackDC, 0, 0, $hIcon, 0, 0, 0, 0, $DI_NORMAL) _WinAPI_DestroyIcon($hIcon) EndIf _WinAPI_SelectObject($hBackDC, $hBackSv) _WinAPI_ReleaseDC(0, $hDC) _WinAPI_DeleteDC($hBackDC) Return $hBitmap EndFunc ;==>_CreateBitmapFromIcon Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight) Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd') Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0) If (@error) Or ($Ret[0] = 0) Then Return SetError(1, 0, 0) EndIf $hIcon = DllStructGetData($tIcon, 1) If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then Return SetError(1, 0, 0) EndIf Return $hIcon EndFunc ;==>_WinAPI_PrivateExtractIcon Ok, i noticed that is a pain create submenu with _GUICtrlMenu_CreatePopup to do like in Tray, and Tray better located, then i need images/icon with Tray functions, some workaround?? 
×