Jump to content
wraithdu

_SysTray UDF

Recommended Posts

Melba23

wraithdu,

Works fine on Vista with taskbar showing and auto-hidden.

In return, could I ask you a follow-on question?

Do you know of any way to display an auto-hidden taskbar so that the icons are available for clicking, other than by this rather crude method?

Send("{CTRLDOWN}") ; send <ctrl>-<esc> to bring up the Taskbar if hidden
Send("{ESC}")
Send("{CTRLUP}")
Send("{ESC}") ; get rid of the Start Menu to avoid confusion

It came up in a recent topic and I could not find a "programmatic" way of doing it.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
wraithdu

Hmm, no. You could move the mouse to the bottom of the screen momentarily, or maybe ControlSend() a click to the taskbar window?

Share this post


Link to post
Share on other sites
ResNullius

This should work on Win2000+, but some testers on XP and Vista would be appreciated.

Example works on XP; haven't tested other functions yet.

Share this post


Link to post
Share on other sites
jadeiceman

Hi, I used your script in Windows 7 x64 Professional, and it clears all the visible system tray icons instead of the dead ones. Do you know what might be happening? I'm new to AutoIt, so maybe I did something wrong with your code? I saved the first one as _SysTray.au3 and the second set of code as Example.au3 and ran Example.au3.

Share this post


Link to post
Share on other sites
wraithdu

This is not tested or coded for X64. It reads directly from explorer.exe's memory which is going to be different on X64. No big surprise it didn't work correctly.

Edited by wraithdu

Share this post


Link to post
Share on other sites
wraithdu

Ok, I've updated the UDF for possible X64 compatibility. Someone's gonna have to test that for me though.

Share this post


Link to post
Share on other sites
JavaAutomater

A quick update : I just ran the example script in the post and it deleted ALL the notification area icons!

I have 9 icons in the area, all of which are visible and the example script gives me this output:

Count visible tray:  9
index:  8   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  7   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  6   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  5   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  4   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  3   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  2   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  1   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
index:  0   visible:  -3    handle:  -3 pid:  -1    proc:       title:  0       tooltip:  -3
>Exit code: 0    Time: 0.312

This means that _SysTrayIconHandle fails, and I think that _SysTrayGetButtonInfo is failing.

Right away, off the top of my head, I think that ReadProcessMemory etc is failing as I don't have Admin privileges/debug rights.

Any clues?

Share this post


Link to post
Share on other sites
KaFu

A quick update : I just ran the example script in the post and it deleted ALL the notification area icons!

Same happened here :), though I have admin rights.

Share this post


Link to post
Share on other sites
JavaAutomater

Same happened here :), though I have admin rights.

Hmmm.. thanks for the feedback.

Can you confirm if you have the SeDebugPrivilige ?

I believe this is required for the functions to succeed.

Can the author(s) of this script please have a look into this?

Share this post


Link to post
Share on other sites
KaFu

Can you confirm if you have the SeDebugPrivilige ?

Confirmed, all tray-icons deleted, still happens with the example below.

#NoTrayIcon
#include <_SysTray.au3>
#include <Process.au3>
#include <WinAPI.au3>

_GetPrivilege_SEDEBUG()

$count = _SysTrayIconCount()
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 @OSVersion = "WIN_7" Then
    ConsoleWrite("-====================-" & @CRLF)
    $countwin7 = _SysTrayIconCount(2)
    ConsoleWrite("Count Win7 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



; By wraithdu
; http://www.autoitscript.com/forum/index.php?showtopic=88214&view=findpost&p=634408
; ####################### Below Func is Part of example - Needed to get commandline from more processes. ############
; ####################### Thanks for this function, wraithdu! (Didn't know it was your.) smile.gif #########################
Func _GetPrivilege_SEDEBUG()
    Local $tagLUIDANDATTRIB = "int64 Luid;dword Attributes"
    Local $count = 1
    Local $tagTOKENPRIVILEGES = "dword PrivilegeCount;byte LUIDandATTRIB[" & $count * 12 & "]" ; count of LUID structs * sizeof LUID struct
    Local $TOKEN_ADJUST_PRIVILEGES = 0x20
    Local $call = DllCall("advapi32.dll", "int", "OpenProcessToken", "ptr", _WinAPI_GetCurrentProcess(), "dword", $TOKEN_ADJUST_PRIVILEGES, "ptr*", "")
    Local $hToken = $call[3]
    $call = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", Chr(0), "str", "SeDebugPrivilege", "int64*", "")
    ;msgbox(262144,"",$call[3] & " " & _WinAPI_GetLastErrorMessage())
    Local $iLuid = $call[3]
    Local $TP = DllStructCreate($tagTOKENPRIVILEGES)
    Local $LUID = DllStructCreate($tagLUIDANDATTRIB, DllStructGetPtr($TP, "LUIDandATTRIB"))
    DllStructSetData($TP, "PrivilegeCount", $count)
    DllStructSetData($LUID, "Luid", $iLuid)
    DllStructSetData($LUID, "Attributes", $SE_PRIVILEGE_ENABLED)
    $call = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "ptr", $hToken, "int", 0, "ptr", DllStructGetPtr($TP), "dword", 0, "ptr", Chr(0), "ptr", Chr(0))
    Return ($call[0] <> 0) ; $call[0] <> 0 is success
EndFunc   ;==>_GetPrivilege_SEDEBUG

Share this post


Link to post
Share on other sites
JavaAutomater

KaFu, It now works with a little patch:

http://www.autoitscript.com/forum/index.php?showtopic=105650&view=findpost&p=746750

:)

Share this post


Link to post
Share on other sites
wraithdu

What version of AutoIt are you using? I guess 'dword_ptr' was introduced in a beta somewhere that you don't have. Good catch Authenticity. I'll change the UDF for safety.

Edited by wraithdu

Share this post


Link to post
Share on other sites
idbirch

Ok, I've updated the UDF for possible X64 compatibility. Someone's gonna have to test that for me though.

Thanks for taking the time to update this UDF wraithd, it's extremely useful. I'm running Win7 x64 and some of the functions are't working for me.

_SysTrayIconCount() works OK and returns the correct number of tray icons but when I try to get down to the interesting stuff, nothing works. For example, _SysTrayIconProcesses() returns an array of blank elements and _SysTrayIconTitles() returns 3 zeroes.

Share this post


Link to post
Share on other sites
wraithdu

I'm not sure what to tell you. What version of AutoIt are you using?

I just tested on my Win7 Pro x64 system with beta 3.3.1.5 and both of those functions work correctly. I tried running from Scite (runs as an x64 process), and compiled as both 32-bit and 64-bit. All 3 return the correct information, both titles and process names. Very simple script to test:

#include <_SysTray.au3>
#include <Array.au3>

$a = _SysTrayIconTitles()
_ArrayDisplay($a)
$a = _SysTrayIconProcesses()
_ArrayDisplay($a)
Edited by wraithdu

Share this post


Link to post
Share on other sites
idbirch

Resolved the problem - I had to copy the UDF from a cached copy of the page yesterday as I was unable to reach autoitscript.com, now that I've re-copied it from the proper page, it's working correctly.

Share this post


Link to post
Share on other sites
idbirch

One more question - the reason for using this was to retrieve the tooltip text from the network icon but instead of getting "Network - Internet Access", I'm getting "Network System Icon".

When I hover the mouse over the tray icon, I see "Network - Internet Access" - is there any way to retrieve this text?

Edited by idbirch

Share this post


Link to post
Share on other sites
wraithdu

You're probably just using the wrong function. See the example I posted. It shows how to get both the icon title and the tooltip.

Share this post


Link to post
Share on other sites
idbirch

No, I'm definitely using the right function. Here's the console output for the Win7 x64 network tray icon using your example script:

index: 2 visible: True handle: 0x00000000000101B4 pid: 1796 proc: explorer.exe title: Network Flyout tooltip: Network System Icon

I have no idea where it's getting that Tooltip text from as that's not what appears when I hover over it.

EDIT: Ugh, turns out the Win7 network icon is a bit temperamental at best, the icon's status was no longer updating in my systray when the connection status changed. I rebooted and now the tips are being read correctly.

Edited by idbirch

Share this post


Link to post
Share on other sites
rogdog

Do you know of any way to display an auto-hidden taskbar so that the icons are available for clicking, other than by this rather crude method?

Send("{CTRLDOWN}") ; send <ctrl>-<esc> to bring up the Taskbar if hidden
Send("{ESC}")
Send("{CTRLUP}")
Send("{ESC}") ; get rid of the Start Menu to avoid confusion

It came up in a recent topic and I could not find a "programmatic" way of doing it.

M23

; locates and right clicks the Icon for this script

#include <GuiToolbar.au3>
#include <_SysTray.au3>

$ToolTipString = 'Autoit - '&@ScriptName

$count = _SysTrayIconCount()
For $i = 0 to $count - 1
    $tooltip = _SysTrayIconTooltip($i)
    ConsoleWrite("index:  " & $i & @TAB & "tooltip:  " & $tooltip & @CRLF)
    If $tooltip = $ToolTipString then $Index = $i
Next

$hWnd = ControlGetHandle('[Class:Shell_TrayWnd]', '', '[Class:ToolbarWindow32;Instance:1]')
$iCommandID = _GUICtrlToolbar_IndexToCommand($hWnd, $Index)
$aRect = _GUICtrlToolbar_GetButtonRect ($hWnd, $iCommandID)
ControlClick($hWnd, '', '','Secondary',1,$aRect[0],$aRect[1])

Example code to locate and right click a notification(systray) icon even if the taskbar is hidden.


My Scripts[topic="73325"]_ReverseDNS()[/topic]Favourite scripts by other members[topic="81687"]SNMP udf[/topic][topic="70759"]Using SNMP - MIB protocol[/topic][topic="39050"]_SplitMon:Section off your monitor!, split your monitor into sections for easy management[/topic][topic="73425"]ZIP.au3 UDF in pure AutoIt[/topic][topic="10534"]WMI ScriptOMatic tool for AutoIt[/topic][topic="51103"]Resources UDF embed/use any data/files into/from AutoIt compiled EXE files[/topic]

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

×