Wie erkenne ich mit AutoIT ein Icon im SystemTray?

  • Hallo,

    bin Neuling mit AutoIT, habe die verschiedenen Tutorien, HilfeSeiten usw durchgelesen, finde aber trotzdem nicht das was ich suche.

    Den folgenden Job hätte ich gerne mit AutoIt automatisiert, (siehe Bild anbei). Im SystemTray (rechts unten neben der Uhr) sind einige Icons, die Reihenfolge ist nicht immer gleich! Trotzdem möchte ich ein bestimmtes Icon auswählen, mit der rechten Maustaste draufklicken, im Untermenu einen Punkt auswählen.

    Wie sehen denn da die Aufrufe in AutoIt aus?

    Scheinbar kann AutoIT die Icons im SysTray nicht separieren, denn "AutoIt v3 Windows Info" malt nur einen schwarzen Kasten um alle Icons und zeigt unter "Basic Window Info" keinen Titel an sondern nur die Klasse Shell_TrayWnd.

    • Offizieller Beitrag
    Spoiler anzeigen
    [autoit]

    #include<Systray.au3>
    Opt('WinTitleMatchMode', 4)
    Global $title = "Check Point Integrity Agent"
    Global $prcoess = "icq.exe"
    ;Global $prcoess = "winampa.exe"

    [/autoit] [autoit][/autoit] [autoit]

    clickSysTrayByTitle($title, "secondary", 1)
    ;clickSysTrayByProcess($prcoess, "right")

    [/autoit] [autoit][/autoit] [autoit]

    Func clickSysTrayByTitle($winTitle, $click = "left", $times = 1)
    Local $a = _SysTrayIconTitles ()
    Local $p = MouseGetPos()
    For $i = 0 To UBound($a) - 1
    If $a[$i] = $winTitle Then
    $pos = _SysTrayIconPos ($i)
    MouseClick($click, $pos[0], $pos[1], $times, 1)
    ExitLoop
    EndIf
    Next
    MouseMove($p[0], $p[1], 1)
    EndFunc ;==>clickSysTrayByTitle

    [/autoit] [autoit][/autoit] [autoit]

    Func clickSysTrayByProcess($winProcess, $click = "left", $times = 1)
    If Not ProcessExists($winProcess) Then Return -1
    Local $a = _SysTrayIconProcesses ()
    Local $p = MouseGetPos()
    For $i = 0 To UBound($a) - 1
    If $a[$i] = $winProcess Then
    $pos = _SysTrayIconPos ($i)
    MouseClick($click, $pos[0], $pos[1], $times, 1)
    ExitLoop
    EndIf
    Next
    MouseMove($p[0], $p[1], 1)
    EndFunc ;==>clickSysTrayByProcess

    [/autoit]

    Systray.au3

    Spoiler anzeigen
    [autoit]

    ; ----------------------------------------------------------------------------
    ;
    ; AutoIt Version: 3.1.1 Beta
    ; Author: Tuape
    ;
    ; Script Function:
    ; Systray UDF - Functions for reading icon info from system tray / removing
    ; any icon.
    ;
    ; Last Update: 7/14/05
    ; Requirements: AutoIt3 Beta - tested on WindowsXP, might also work in win2000
    ;
    ; Functions:
    ; _SysTrayIconCount() - Get count of all systray icons
    ; _SysTrayIconTitles() - Get titles of all programs that have icon on systray
    ; _SysTrayIconProcesses() - Get list of all process names that have icon in systray (hidden or visible)
    ; _SysTrayIconPids() - Get list of all parent process id's that own an icon in systray (hidden or visible)
    ; _SysTrayIconRemove($index) - Remove icon (removes completely, not just hide)
    ; _SysTrayIconIndex($wintitle or $process) - Get icon index based on process name or wintitle
    ; _SysTrayIconTooltip($index) - Get tooltip text of an icon based on index
    ;
    ; Notes:
    ; Some systray icons are actually hidden, so _SysTrayIconCount will probably return more than you see on systray.
    ; Some icons don't have window title on them. However, _SysTrayIconPids() & _SysTrayIconProcesses
    ; do return correct (parent) pid or process name
    ; ----------------------------------------------------------------------------
    #NoTrayIcon

    [/autoit] [autoit][/autoit] [autoit]

    Const $TB_DELETEBUTTON = 1046
    Const $TB_GETBUTTON = 1047
    Const $TB_BUTTONCOUNT = 1048
    Const $TB_GETBUTTONTEXT = 1099
    Const $TB_GETBUTTONINFO = 1089
    Const $TB_HIDEBUTTON = 1028 ; WM_USER +4
    Const $TB_GETITEMRECT = 1053
    Const $TB_MOVEBUTTON = 1106 ; WM_USER +82
    Const $WM_GETTEXT = 13 ; Included in GUIConstants
    Const $PROCESS_ALL_ACCESS = 2035711
    Const $NO_TITLE = "---No title---" ; text that is used when icon window has no title

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconTitles()
    ; Description: Get list of all window titles that have systray icon
    ; Parameter(s): None
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns an array with all window titles
    ; On Failure - TO BE DONE
    ; Author(s): Tuape
    ;
    ;===============================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _SysTrayIconTitles()
    Local $i
    Local $j
    Local $max = _SysTrayIconCount()
    Local $info[$max]
    Local $titles[$max]
    Local $var

    ; Get info (hwnd) of all icons
    For $i=0 to $max-1
    $info[$i] = _SysTrayIconHandle($i)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ; Get window title text
    $var = WinList()
    For $i = 0 to $max-1
    For $j = 1 to $var[0][0]
    ;If $info[$i] = Dec($var[$j][1]) Then
    If $info[$i] = HWnd($var[$j][1]) Then
    If $var[$j][0] <> "" Then
    $titles[$i] = $var[$j][0]
    Else
    $titles[$i] = $NO_TITLE
    EndIf

    ExitLoop

    EndIf
    Next
    Next
    return $titles
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconProcesses()
    ; Description: Get list of all processes that have systray icon
    ; Parameter(s): None
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns an array with all process names
    ; On Failure - TO BE DONE
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconProcesses()
    Local $i
    Local $j
    Local $pids = _SysTrayIconPids()
    Local $processes[UBound($pids)]
    Local $list
    ; List all processes
    $list = ProcessList()
    For $i = 0 to Ubound($pids)-1
    For $j = 1 To $list[0][0]
    If $pids[$i] = $list[$j][1] Then
    $processes[$i] = $list[$j][0]
    ExitLoop
    EndIf
    Next
    Next
    return $processes
    EndFunc ;_SysTrayIconProcesses()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconPids()
    ; Description: Get list of all processes id's that have systray icon
    ; Parameter(s): None
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns an array with all process id's
    ; On Failure - TO BE DONE
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconPids()
    Local $i
    Local $titles = _SysTrayIconTitles()
    Local $processes[UBound($titles)]
    Local $ret

    For $i=0 to Ubound($titles)-1
    If $titles[$i] <> $NO_TITLE Then
    $processes[$i] = WinGetProcess($titles[$i])
    Else
    ; Workaround for systray icons that have no title
    $ret = DLLCall("user32.dll","int","GetWindowThreadProcessId", "int", _SysTrayIconHandle($i), "int*", -1)
    If Not @error Then
    $processes[$i] = $ret[2]

    EndIf


    EndIf
    Next

    return $processes

    [/autoit] [autoit][/autoit] [autoit]


    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconIndex($name, $mode=0)
    ; Description: Get list of all processes id's that have systray icon
    ; Parameter(s): $name = process name / window title text
    ; $mode 0 = get index by process name (default)
    ; 1 = get index by window title
    ; 2 = get index by icon's tooltip text
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns index of found icon
    ; On Failure - Returns -1 if icon for given process/wintitle
    ; was not found.
    ; - Sets error to 1 and returns -1 in case of bad
    ; arguments
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconIndex($name, $mode=0)
    Local $index = -1
    Local $process
    Local $i
    If $mode < 0 or $mode > 2 or Not IsInt($mode) Then
    SetError(1)
    return -1
    EndIf

    If $mode = 0 Then
    $process = _SysTrayIconProcesses()

    Else
    $process = _SysTrayIconTitles()
    EndIf

    For $i = 0 to Ubound($process)-1
    If $process[$i] = $name Then
    $index = $i
    EndIf
    Next

    return $index

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconPos($iIndex=0)
    ; Description: Gets x & y position of systray icon
    ; Parameter(s): $iIndex = icon index (Note: starting from 0)
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns x [0] and y [1] position of icon
    ; On Failure - Returns -1 if icon is hidden (Autohide on XP etc.)
    ; Sets error to 1 if some internal error happens
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconPos($iIndex=0)
    ;=========================================================
    ; Create the struct _TBBUTTON
    ; struct {
    ; int iBitmap;
    ; int idCommand;
    ; BYTE fsState;
    ; BYTE fsStyle;
    ;
    ; #ifdef _WIN64
    ; BYTE bReserved[6] // padding for alignment
    ; #elif defined(_WIN32)
    ; BYTE bReserved[2] // padding for alignment
    ; #endif
    ; DWORD_PTR dwData;
    ; INT_PTR iString;

    [/autoit] [autoit][/autoit] [autoit]

    ; }
    ;=========================================================
    Local $str = "int;int;byte;byte;byte[2];dword;int"
    Dim $TBBUTTON = DllStructCreate($str)
    Dim $TBBUTTON2 = DllStructCreate($str)
    Dim $ExtraData = DllStructCreate("dword[2]")
    Dim $lpData
    DIM $RECT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $pId
    Local $text
    Local $procHandle
    Local $index = $iIndex
    Local $bytesRead
    Local $info
    Local $pos[2]
    Local $hidden = 0
    Local $trayHwnd
    Local $ret

    [/autoit] [autoit][/autoit] [autoit]

    $trayHwnd = _FindTrayToolbarWindow()
    If $trayHwnd = -1 Then
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    SetError(1)
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $ret = DLLCall("user32.dll","int","GetWindowThreadProcessId", "hwnd", $trayHwnd, "int*", -1)
    If Not @error Then
    $pId = $ret[2]
    Else
    ConsoleWrite("Error: Could not find toolbar process id, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    SetError(1)
    Return -1
    EndIf
    $procHandle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', $PROCESS_ALL_ACCESS, 'int', False, 'int', $pId)
    If @error Then
    ConsoleWrite("Error: Could not read toolbar process memory, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    SetError(1)
    return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $lpData = DLLCall("kernel32.dll","int","VirtualAllocEx", "int", $procHandle[0], "int", 0, "int", DllStructGetSize ( $TBBUTTON ), "int", 0x1000, "int", 0x04)
    If @error Then
    ConsoleWrite(@CRLF & "VirtualAllocEx Error" & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    SetError(1)
    Return -1
    Else
    DLLCall("user32.dll","int","SendMessage", "hwnd", $trayHwnd, "int", $TB_GETBUTTON, "int", $index, "ptr",$lpData[0])
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', $lpData[0], 'ptr', DllStructGetPtr($TBBUTTON2), 'int', DllStructGetSize( $TBBUTTON), 'int', $bytesRead)
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', DllStructGetData($TBBUTTON2,6), 'int', DllStructGetPtr($ExtraData), 'int', DllStructGetSize( $ExtraData), 'int', $bytesRead)

    [/autoit] [autoit][/autoit] [autoit]

    $info = DllStructGetData($ExtraData,1,1)
    If Not BitAND(DllStructGetData($TBBUTTON2,3), 8) Then ; 8 = TBHIDDEN

    $str = "int;int;int;int"
    $RECT = DllStructCreate($str)

    [/autoit] [autoit][/autoit] [autoit]

    DLLCall("user32.dll","int","SendMessage", "hwnd", $trayHwnd, "int", $TB_GETITEMRECT, "int", $index, "ptr",$lpData[0])
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', $lpData[0], 'ptr', DllStructGetPtr($RECT), 'int', DllStructGetSize($RECT), 'int', $bytesRead)

    $ret = DLLCall("user32.dll","int","MapWindowPoints", "hwnd", $trayHwnd, "int", 0, 'ptr', DllStructGetPtr($RECT), "int",2)
    ConsoleWrite("Info: " & $info & "RECT[0](left): " & DllStructGetData($RECT,1) & "RECT[1](top): " & DllStructGetData($RECT,2) & "RECT[2](right): " & DllStructGetData($RECT,3) & "RECT[3](bottom): " & DllStructGetData($RECT,4) & @LF)

    ;MouseMove(DllStructGetData($RECT,1),DllStructGetData($RECT,2))
    ;Sleep(1000)
    ;MouseClick("left")
    $pos[0] = DllStructGetData($RECT,1)
    $pos[1] = DllStructGetData($RECT,2)
    $RECT = 0
    Else
    $hidden = 1
    EndIf

    DLLCall("kernel32.dll","int","VirtualFreeEx", "int", $procHandle[0], "ptr", $lpData[0], "int", 0, "int", 0x8000) ;DllStructGetSize ( $TBBUTTON ), "int", 0x8000)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $procHandle[0])
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0

    [/autoit] [autoit][/autoit] [autoit]

    If $hidden <> 1 Then
    return $pos
    Else
    Return -1
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconHandle($iIndex=0)
    ; Description: Utility function. Gets hwnd of window associated with
    ; systray icon of given index
    ; Parameter(s): $iIndex = icon index (Note: starting from 0)
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns hwnd of found icon
    ; On Failure - Returns -1 in error situations
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconHandle($iIndex=0)
    ;=========================================================
    ; Create the struct _TBBUTTON
    ; struct {
    ; int iBitmap;
    ; int idCommand;
    ; BYTE fsState;
    ; BYTE fsStyle;
    ;
    ; #ifdef _WIN64
    ; BYTE bReserved[6] // padding for alignment
    ; #elif defined(_WIN32)
    ; BYTE bReserved[2] // padding for alignment
    ; #endif
    ; DWORD_PTR dwData;
    ; INT_PTR iString;

    [/autoit] [autoit][/autoit] [autoit]

    ; }
    ;=========================================================
    Local $str = "int;int;byte;byte;byte[2];dword;int";char[128]"
    Dim $TBBUTTON = DllStructCreate($str)
    Dim $TBBUTTON2 = DllStructCreate($str)
    Dim $ExtraData = DllStructCreate("dword[2]")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $pId
    Local $text
    Local $procHandle
    Local $index = $iIndex
    Local $bytesRead
    Local $info
    Local $lpData
    Local $trayHwnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $trayHwnd = _FindTrayToolbarWindow()
    If $trayHwnd = -1 Then
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    SetError(1)
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret = DLLCall("user32.dll","int","GetWindowThreadProcessId", "hwnd", $trayHwnd, "int*", -1)
    If Not @error Then
    $pId = $ret[2]
    Else
    ConsoleWrite("Error: Could not find toolbar process id, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    Return -1
    EndIf
    $procHandle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', $PROCESS_ALL_ACCESS, 'int', False, 'int', $pId)
    If @error Then
    ConsoleWrite("Error: Could not read toolbar process memory, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $lpData = DLLCall("kernel32.dll","int","VirtualAllocEx", "int", $procHandle[0], "int", 0, "int", DllStructGetSize ( $TBBUTTON ), "int", 0x1000, "int", 0x04)
    If @error Then
    ConsoleWrite("VirtualAllocEx Error" & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    Return -1
    Else
    DLLCall("user32.dll","int","SendMessage", "hwnd", $trayHwnd, "int", $TB_GETBUTTON, "int", $index, "ptr", $lpData[0]);e(hwnd, TB_GETBUTTON, index, (LPARAM)lpData);
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', $lpData[0], 'ptr', DllStructGetPtr($TBBUTTON2), 'int', DllStructGetSize( $TBBUTTON), 'int', $bytesRead)
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', DllStructGetData($TBBUTTON2,6), 'int', DllStructGetPtr($ExtraData), 'int', DllStructGetSize( $ExtraData), 'int', $bytesRead);_MemRead($procHandle, $lpData[0], DllStructGetSize( $TBBUTTON))

    [/autoit] [autoit][/autoit] [autoit]

    $info = DllStructGetData($ExtraData,1)
    DLLCall("kernel32.dll","int","VirtualFreeEx", "int", $procHandle[0], "ptr", $lpData[0], "int", 0, "int", 0x8000) ;DllStructGetSize ( $TBBUTTON ), "int", 0x8000)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $procHandle[0])
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $lpData = 0
    return $info
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconTooltip($iIndex=0)
    ; Description: Utility function. Gets the tooltip text of
    ; systray icon of given index
    ; Parameter(s): $iIndex = icon index (Note: starting from 0)
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns tooltip text of icon
    ; On Failure - Returns -1 in error situations
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconTooltip($iIndex=0)
    ;=========================================================
    ; Create the struct _TBBUTTON
    ; struct {
    ; int iBitmap;
    ; int idCommand;
    ; BYTE fsState;
    ; BYTE fsStyle;
    ;
    ; #ifdef _WIN64
    ; BYTE bReserved[6] // padding for alignment
    ; #elif defined(_WIN32)
    ; BYTE bReserved[2] // padding for alignment
    ; #endif
    ; DWORD_PTR dwData;
    ; INT_PTR iString;

    [/autoit] [autoit][/autoit] [autoit]

    ; }
    ;=========================================================
    Local $str = "int;int;byte;byte;byte[2];dword;int"
    Dim $TBBUTTON = DllStructCreate($str)
    Dim $TBBUTTON2 = DllStructCreate($str)
    Dim $ExtraData = DllStructCreate("dword[2]")
    Dim $intTip = DllStructCreate("short[1024]")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $pId
    Local $text
    Local $procHandle
    Local $index = $iIndex
    Local $bytesRead
    Local $info
    Local $lpData
    Local $trayHwnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $trayHwnd = _FindTrayToolbarWindow()
    If $trayHwnd = -1 Then
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $intTip = 0
    ;SetError(1)
    Return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret = DLLCall("user32.dll","int","GetWindowThreadProcessId", "hwnd", $trayHwnd, "int*", -1)
    If Not @error Then
    $pId = $ret[2]
    Else
    ConsoleWrite("Error: Could not find toolbar process id, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $intTip = 0
    Return -1
    EndIf
    $procHandle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', $PROCESS_ALL_ACCESS, 'int', False, 'int', $pId)
    If @error Then
    ConsoleWrite("Error: Could not read toolbar process memory, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $intTip = 0
    return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $lpData = DLLCall("kernel32.dll","int","VirtualAllocEx", "int", $procHandle[0], "int", 0, "int", DllStructGetSize ( $TBBUTTON ), "int", 0x1000, "int", 0x04)
    If @error Then
    ConsoleWrite("VirtualAllocEx Error" & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $intTip = 0
    Return -1
    Else
    DLLCall("user32.dll","int","SendMessage", "hwnd", $trayHwnd, "int", $TB_GETBUTTON, "int", $index, "ptr",$lpData[0]);e(hwnd, TB_GETBUTTON, index, (LPARAM)lpData);
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', $lpData[0], 'ptr', DllStructGetPtr($TBBUTTON2), 'int', DllStructGetSize( $TBBUTTON), 'int', $bytesRead)
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', DllStructGetData($TBBUTTON2,7), 'int', DllStructGetPtr($intTip), 'int', DllStructGetSize( $intTip), 'int', 0);_MemRead($procHandle, $lpData[0], DllStructGetSize( $TBBUTTON))

    [/autoit] [autoit][/autoit] [autoit]

    ; go through every character
    $i = 1
    While $i < 1024
    $tipChar = ""

    #cs
    BOOL ReadProcessMemory(
    HANDLE hProcess,
    LPCVOID lpBaseAddress,
    LPVOID lpBuffer,
    SIZE_T nSize,
    SIZE_T* lpNumberOfBytesRead
    );
    #ce

    [/autoit] [autoit][/autoit] [autoit]


    $tipChar = Chr(DllStructGetData($intTip,1,$i))

    [/autoit] [autoit][/autoit] [autoit]

    If $tipChar = "" Then
    ExitLoop
    EndIf
    ;ConsoleWrite(@CRLF & $i & " Char: " & $tipChar & @LF)
    $info = $info & $tipChar

    [/autoit] [autoit][/autoit] [autoit]

    $i = $i + 1
    Wend

    If $info = "" Then
    $info = "No tooltip text"
    EndIf

    DLLCall("kernel32.dll","int","VirtualFreeEx", "int", $procHandle[0], "ptr", $lpData[0], "int", 0, "int", 0x8000) ;DllStructGetSize ( $TBBUTTON ), "int", 0x8000))
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $procHandle[0])
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    $ExtraData = 0
    $intTip = 0
    $lpData = 0
    return $info
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconCount
    ; Description: Utility function. Returns number of icons on systray
    ; Note: Hidden icons are also reported
    ; Parameter(s): None
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns number of icons found
    ; On Failure - Returns -1
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconCount()
    Local $hWnd = _FindTrayToolbarWindow()
    Local $count = 0
    $count = DLLCall("user32.dll","int","SendMessage", "hwnd", $hWnd, "int", $TB_BUTTONCOUNT, "int", 0, "int", 0)
    If @error Then Return -1
    return $count[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconVisible($flag, $index)
    ; Description: Hides / unhides any icon on systray
    ;
    ; Parameter(s): $flag = hide (1) or show (0) icon
    ; $index = icon index. Can be queried with _SysTrayIconIndex()
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns 1 if operation was successfull / 0 if
    ; icon was already hidden/unhidden
    ; On Failure - If invalid parameters, returns -1 and sets error
    ; to 1
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconVisible($flag, $index)
    If $flag < 0 or $flag > 1 or Not IsInt($flag) Then
    SetError(1)
    return -1
    EndIf

    Local $hWnd = _FindTrayToolbarWindow()
    Local $return

    Local $str = "int;int;byte;byte;byte[2];dword;int";char[128]"
    Dim $TBBUTTON = DllStructCreate($str)
    Dim $TBBUTTON2 = DllStructCreate($str)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $pId
    Local $text
    Local $procHandle
    Local $bytesRead
    Local $info
    Local $lpData

    [/autoit] [autoit][/autoit] [autoit]

    Local $ret = DLLCall("user32.dll","int","GetWindowThreadProcessId", "hwnd", $hWnd, "int*", -1)
    If Not @error Then
    $pId = $ret[2]
    Else
    ConsoleWrite("Error: Could not find toolbar process id, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    Return -1
    EndIf
    $procHandle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', $PROCESS_ALL_ACCESS, 'int', False, 'int', $pId)
    If @error Then
    ConsoleWrite("Error: Could not read toolbar process memory, " & @error & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    return -1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $lpData = DLLCall("kernel32.dll","int","VirtualAllocEx", "int", $procHandle[0], "int", 0, "int", DllStructGetSize ( $TBBUTTON ), "int", 0x1000, "int", 0x04)
    If @error Then
    ConsoleWrite("VirtualAllocEx Error" & @LF)
    $TBBUTTON = 0
    $TBBUTTON2 = 0
    Return -1
    Else
    DLLCall("user32.dll","int","SendMessage", "hwnd", $hWnd, "int", $TB_GETBUTTON, "int", $index, "ptr",$lpData[0]);e(hwnd, TB_GETBUTTON, index, (LPARAM)lpData);
    DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $procHandle[0], 'int', $lpData[0], 'ptr', DllStructGetPtr($TBBUTTON2), 'int', DllStructGetSize( $TBBUTTON), 'int', $bytesRead)

    $return = DLLCall("user32.dll","int","SendMessage", "hwnd", $hWnd, "int", $TB_HIDEBUTTON, "int", DllStructGetData($TBBUTTON2,2), "long", $flag)
    ;ConsoleWrite(@CRLF & "Return: " & $return[0])

    DLLCall("kernel32.dll","int","VirtualFreeEx", "int", $procHandle[0], "ptr", $lpData[0], "int", 0, "int", 0x8000) ;DllStructGetSize ( $TBBUTTON ), "int", 0x8000)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $procHandle[0])

    EndIf

    [/autoit] [autoit][/autoit] [autoit]


    $TBBUTTON = 0
    $TBBUTTON2 = 0

    return $return[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconMove($curPos, $newPos)
    ; Description: Moves systray icon
    ;
    ; Parameter(s): $curPos = icon's current index (0 based)
    ; $newPos = icon's new position
    ; ----> ($curPos+1 = one step to right, $curPos-1 = one step to left)
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns 1 if operation was successfull
    ; On Failure - If invalid parameters, returns -1 and sets error
    ; to 1
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconMove($curPos, $newPos)

    Local $iconCount = _SysTrayIconCount()
    If $curPos < 0 or $newPos < 0 or $curPos > $iconCount-1 or $newPos > $iconCount-1 or Not IsInt($curPos) or Not IsInt($newPos) Then
    SetError(1)
    return -1
    EndIf

    Local $hWnd = _FindTrayToolbarWindow()
    Local $return

    Local $return = DLLCall("user32.dll","int","SendMessage", "hwnd", $hWnd, "int", $TB_MOVEBUTTON, "int", $curPos, "int",$newPos)
    return $return[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _SysTrayIconRemove($index=0
    ; Description: Removes systray icon completely.
    ;
    ; Parameter(s): index = icon index. Can be queried with _SysTrayIconIndex()
    ; Default = 0
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns 1 if icon successfully removed
    ; On Failure - Sets error to 1 and returns -1
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _SysTrayIconRemove($index=0)
    If $index < 0 or $index > _SysTrayIconCount()-1 Then
    SetError(1)
    return -1
    EndIf

    Local $hWnd = _FindTrayToolbarWindow()
    DLLCall("user32.dll","int","SendMessage", "hwnd", $hWnd, "int", $TB_DELETEBUTTON, "int", $index, "int", 0)
    If Not @error Then
    return 1
    Else
    SetError(2)
    return -1
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _FindTrayToolbarWindow
    ; Description: Utility function for finding Toolbar window hwnd
    ; Parameter(s): None
    ;
    ; Requirement(s): AutoIt3 Beta
    ; Return Value(s): On Success - Returns Toolbar window hwnd
    ; On Failure - returns -1
    ;
    ; Author(s): Tuape
    ;
    ;===============================================================================
    Func _FindTrayToolbarWindow()
    Local $hWnd = DLLCall("user32.dll","hwnd","FindWindow", "str", "Shell_TrayWnd", "int", 0)

    if @error Then return -1
    $hWnd = DLLCall("user32.dll","hwnd","FindWindowEx", "hwnd", $hWnd[0], "int", 0, "str", "TrayNotifyWnd", "int", 0);FindWindowEx(hWnd,NULL,_T("TrayNotifyWnd"), NULL);
    if @error Then return -1
    If @OSVersion <> "WIN_2000" Then
    $hWnd = DLLCall("user32.dll","hwnd","FindWindowEx", "hwnd", $hWnd[0], "int", 0, "str", "SysPager", "int", 0);FindWindowEx(hWnd,NULL,_T("TrayNotifyWnd"), NULL);
    if @error Then return -1
    EndIf
    $hWnd = DLLCall("user32.dll","hwnd","FindWindowEx", "hwnd", $hWnd[0], "int", 0, "str", "ToolbarWindow32", "int", 0);FindWindowEx(hWnd,NULL,_T("TrayNotifyWnd"), NULL);
    if @error Then return -1

    Return $hWnd[0]
    EndFunc

    [/autoit]

    Mega

  • Puh, das war jetzt gar nicht so einfach, aber auf meinem Rechner funktioniert's perfekt. Kann sein, dass es mit anderen Einstellungen nicht klappt, weiß ich nicht, ich bin aber zuversichtlich! :thumbup:
    Beschreibung: Einfach _ArrayDisplay beim ersten Mal aktivieren, Skript starten, schauen welches Icon welche Checksum hat, in _ArraySearch eintragen und schon kanns los gehen!! :D
    Am besten einfach mal lassen wie es ist und testen ob's funktioniert!


    [autoit]

    #Include <Array.au3>
    Dim $IconWidth = 18

    [/autoit][autoit][/autoit][autoit]

    $Liste = WinList()
    $Tray_Pos = ControlGetPos("[CLASS:Shell_TrayWnd]","", "TrayNotifyWnd1")
    $Anzahl = (@DesktopWidth - 50 - $Tray_Pos[0] +2) / $IconWidth
    Global $Checksum[$Anzahl]

    [/autoit][autoit][/autoit][autoit]

    For $i = 0 To $Anzahl - 1
    $Checksum[$i] = PixelChecksum($Tray_Pos[0] +3 + $i * $Anzahl,@DesktopHeight-22, $Tray_Pos[0] -3 + ($i+1) * $Anzahl,@DesktopHeight- 15)
    Next

    [/autoit][autoit][/autoit][autoit]

    ;~ _ArrayDisplay($Checksum) ;Diese Zeile aktivieren, um zu schauen welches Icon welche Checksum hat

    [/autoit][autoit][/autoit][autoit]

    $Index = _ArraySearch($Checksum,"1136343058") ;Autoit-Icon; Hier kommt die Checksum von dem Programm das du willst rein
    ;~ $Index = _ArraySearch($Checksum,"381826595") ;Lautstärkeregelung; Hier kommt die Checksum von dem Programm das du willst rein
    ;~ $Index = _ArraySearch($Checksum,"3122802764") ;WLAN-Icon; Hier kommt die Checksum von dem Programm das du willst rein

    [/autoit][autoit][/autoit][autoit]

    MouseClick("right",$Tray_Pos[0] + 2 + $IconWidth/2 + $Index * $IconWidth,@DesktopHeight-16)

    [/autoit]


    Ich glaube jetzt habe ich mir einen Orden verdient! :rofl:

  • Hallo!

    Mich würde interessieren, ob mein gebasteltes Skript nur zufällig auf meinem Rechner (und mittlerweile auch auf einem 2. PC) läuft, oder ob es so auf mehreren Rechnern einsetzbar ist. Voraussetzung ist allerdings, dass die Uhr eingeschaltet ist und natürlich die Startleiste dauernd sichtbar ist.

    Danke

  • funkey
    Habe dein Skript (unter WIN2000) getestet, es läuft aber nicht rund.
    Meine beiden Netzwerkkarten werden (mit der ersten Erkennungsroutine Checksum) doppelt erkannt,
    das Icon für USB-Devices gar nicht,
    und die Positionierung des Mauszeigers klappt nicht (liegt immer irgendwo daneben bei einem anderen Icon).
    Wenn ich die Iconbreite (ganz oben im Skript) reduziere, erkennt es ganz abenteuerliche Checksum-Icon-Einträge ...

    Weiß auch nicht, ob Hugo22 damit klarkommen wird...

    Rasta

  • von hugo22 ---> funkey,

    vielen Dank für die schnelle Reaktion, habe das script getestet (Win XP, verschiedene PCs) und habe Probleme festgestellt (siehe Bilder anbei)SMSSender.zip diese Bild zeigt, dass mit jedem Aufruf des scripts ein neues Icon im Systray entsteht (beim 1.Aufruf sind es 5 Icons, beim 2.Aufruf sind es 6, beim 3.Aufruf sind es 7), und leider jedes Mal andere checksum. Ich dachte mir, dass das ev. daran liegt, dass das script ja 3 mal in parallel läuft und habe deshalb einmal mit und einmal ohne das Netzwerk-Icon das script laufen lassen Unbenannt.jpg, doch da sind auch keine identischen checksums herausgekommen.

    Also nochmals vielen, vielen Dank für die schnelle Reaktion, aber leider ist das script so nicht anwendbar.

  • hugo22 ---> Mega
    war überrascht von der schnellen Antwort, musste noch ein bischen basteln bis ich zu einem Ergebnis kam (das leider noch nicht befriedigend ist). Ich habe Dein script erweitert, damit ich die Titel der einzelnen Icons anzeigen konnte (siehe Bild). Unbenannt.jpg
    Leider zeigt sich was kurioses: der Windows Task-Manager zeigt sich 13 Mal, die MS firewall zeigt sich als "no title", dann zeigen sich hidden Icons als Connections Tray, einmal für Netzwerk und USB und ????, der Lautsprecher als "Energieanzeige", Avira und Sygate zeigen sich korrekt.

    Wie gesagt, ein Ergebnis, aber leider noch nicht befriedigend. Ich versuche nun über die tooltips das gesuchte Icon zu finden (UDF Systray.au3).

    Nochmals vielen Dank, hugo22

  • Hi Mega,

    leider ist das mit der Idee den "prgrammname.exe" zu nehmen nicht getan, wie aus dem Bild ersichtlich ist, unrardll.ziperscheint der gleiche programmname mehrmals.

    Ich bin mit der Idee die "tooltips" abzufragen weiter gekommen key.zip,

    Leider, weil Anfänger mit AutoIt, dauert es noch ein bischen, bis ich mit meinem script so weit bin, dass ich es hier posten kann.

    Vielen Dank und Grüße, hugo22

  • Ich bin einfach der Anfänger und komme nicht weiter,

    mittels UDF Systray.au3 (da ist übrigens ein kleiner Fehler drin, denn es verträgt sich nicht mit <Array.au3>) in meinem script kann ich jetzt den rechten Mausclick ausführen, es erscheint dann aber ein rahmenloses Fenster, mit dem ich in autoit nicht klar komme.

    Nehmen wir das Icon Lautsprecher, mit dem IconTooltip "Lautstärke" ist es auswählbar, nach rechter Mausclick erscheint das rahmenlose Fenster mit den 2 Menue-Punkten "Lautstärkeregelung öffnen" und "Audioeigenschaften einstellen", ich will per autoit-script auf "Lautstärkeregelung öffnen" klicken und dann das nächste Fenster bedienen.

    Kann mir da vielleicht einer einen Tip geben, wie ich mit dem rahmenlosen Fenster vorgehen kann?

    Vielen, vielen Dank im voraus, hugo22

  • Hi Mega,

    ich brauche, wie im Beispiel mit dem Lautsprecher beschrieben, ein tool, das mit verschiedenen Icons (Applikationen) im SystemTray klar kommt. Dann ein Rechtsklick auf das Icon, ein rahmenloses Fenster öffnet sich, jetzt ein Menuepunkt auswählen.

    Das soll sowohl für Netzwerk (mehrere Verbindungen) als auch mit Lautsprecher, USB und verschiedenen Applikationen funktionieren (wird dann kompiliert und auf verschiedenen PCs eingesetzt).

    hugo22