Что нового

Найти кнопку в Shell_TrayWnd

badhabit

Новичок
Сообщения
36
Репутация
0
День добрый! Подскажите как через AutoIt можно найти кнопку (иконку приложения) по названию программы в в shell tray (с отключенной группировкой, т.е. каждая программа отражается своей отдельно "кнопкой" в трее) и кликнуть по ней мышкой?
 
Автор
B

badhabit

Новичок
Сообщения
36
Репутация
0
badhabit сказал(а):
День добрый! Подскажите как через AutoIt можно найти кнопку (иконку приложения) по названию программы в в shell tray (с отключенной группировкой, т.е. каждая программа отражается своей отдельно "кнопкой" в трее) и кликнуть по ней мышкой?
Что, получается это невозможно?
 

sngr

AutoIT Гуру
Сообщения
1,015
Репутация
411
Код:
#include 'SysTray_UDF.au3'
_SysTrayIconPos

Сколько я помню координаты будут относительно трея.
 

johnmarshall

Осваивающий
Сообщения
202
Репутация
39
Код:
#cs ------------------------------------------------------------------------
	Версия AutoIt:  3.3.8.1
	Автор:          rover 2k11
	Описание:       save icon from tary by name
					in example of egui.exe
        Tested: true
        In lib: damien2008
#ce ------------------------------------------------------------------------

; Код программы

#NoTrayIcon
#include <WinAPIEx.au3>
#include <WinAPI.au3>
#include <Process.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <Constants.au3>
#include <APIConstants.au3>
#include <WindowsConstants.au3>
#include <ToolBarConstants.au3>
#include <ProcessConstants.au3>
#include <MemoryConstants.au3>

Opt("MustDeclareVars", 1)
Global $procc, $ex = 0

Global Const $PROCESS_ACCESS = BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ)
Global $iTbar = 0
Global $hOwnerWin, $hTrayWnd, $hTrayNotifyWnd, $hSysPager, $hToolbar, _
		$iDLLUser32 = DllOpen("user32.dll"), $iDLLKrnl32 = DllOpen("kernel32.dll"), _
		$tTBBUTTON, $pTBBUTTON, $iTBBUTTON, $tTRAYDATA, $pTRAYDATA, $iTRAYDATA, _
		$iImg = 0, $iIdx = 0, $iCount, $iPIDExp, $hProcess, $pAddress, $iPID, $aRet, $sRet, $hIconTray, $hIcon
$hTrayWnd = WinGetHandle("[CLASS:Shell_TrayWnd]")
$hTrayNotifyWnd = ControlGetHandle($hTrayWnd, "", "[CLASS:TrayNotifyWnd]")
$hSysPager = ControlGetHandle($hTrayNotifyWnd, "", "[CLASS:SysPager]")
$hToolbar = ControlGetHandle($hSysPager, "", "[CLASS:ToolbarWindow32; INSTANCE:1]");User Promoted Notification Area/Notification Area/SysTray

Switch @OSVersion
	Case "WIN_2008R2", "WIN_7"
		Switch $iTbar
			Case 1 ;Overflow Notification Area
				$hToolbar = ControlGetHandle(WinGetHandle("[CLASS:NotifyIconOverflowWindow]"), "", "[CLASS:ToolbarWindow32; INSTANCE:1]")
			Case 2 ;System Promoted Notification Area
				$hToolbar = ControlGetHandle($hTrayNotifyWnd, "", "[CLASS:ToolbarWindow32; INSTANCE:2]")
		EndSwitch
EndSwitch

$tTBBUTTON = DllStructCreate("int Bitmap;int Command;byte State;byte Style;align;dword_ptr Param;int_ptr String")
$pTBBUTTON = DllStructGetPtr($tTBBUTTON)
$iTBBUTTON = DllStructGetSize($tTBBUTTON)
$tTRAYDATA = DllStructCreate("hwnd hwnd;uint uID;uint uCallbackMessage;dword Reserved[2];ptr hIcon")
$pTRAYDATA = DllStructGetPtr($tTRAYDATA)
$iTRAYDATA = DllStructGetSize($tTRAYDATA)
$iPIDExp = WinGetProcess($hToolbar)
If @error Or $iPIDExp = -1 Then Exit
$aRet = DllCall($iDLLKrnl32, "ptr", "OpenProcess", "dword", _
		$PROCESS_ACCESS, "int", 0, "int", $iPIDExp)
If @error Or $aRet[0] = 0 Then Exit
$hProcess = $aRet[0]
$aRet = DllCall($iDLLUser32, "lparam", "SendMessageW", "hwnd", _
		$hToolbar, "int", $TB_BUTTONCOUNT, "wparam", 0, "lparam", 0)
If @error Or $aRet[0] < 1 Then
	DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProcess)
	Exit
EndIf
$iCount = $aRet[0] - 1
$aRet = DllCall($iDLLKrnl32, "ptr", "VirtualAllocEx", "ptr", $hProcess, "ptr", 0, "ulong_ptr", _
		$iTBBUTTON, "dword", BitOR($MEM_RESERVE, $MEM_COMMIT), "dword", $PAGE_READWRITE)
If @error Or $aRet[0] = 0 Then
	DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProcess)
	Exit
EndIf
$pAddress = $aRet[0]


For $iID = 0 To $iCount
	If IsHWnd($hToolbar) = False Then ExitLoop
	$aRet = DllCall($iDLLUser32, "lparam", "SendMessageW", "hwnd", $hToolbar, _
			"int", $TB_GETBUTTON, "wparam", $iID, "lparam", $pAddress)
	If @error Or $aRet[0] <> 1 Then ContinueLoop
	$aRet = DllCall($iDLLKrnl32, "int", "ReadProcessMemory", "ptr", $hProcess, _
			"ptr", $pAddress, "ptr", $pTBBUTTON, "ulong_ptr", $iTBBUTTON, "ulong_ptr*", -1)
	If @error Or $aRet[5] <> $iTBBUTTON Then ContinueLoop
	;If BitAND(DllStructGetData($tTBBUTTON, "State"), $TBSTATE_HIDDEN) = $TBSTATE_HIDDEN Then ContinueLoop
	$aRet = DllCall($iDLLKrnl32, "int", "ReadProcessMemory", "ptr", $hProcess, _
			"dword_ptr", DllStructGetData($tTBBUTTON, "Param"), "ptr", $pTRAYDATA, "ulong_ptr", $iTRAYDATA, "ulong_ptr*", -1)
	If @error Or $aRet[5] <> $iTRAYDATA Then ContinueLoop
	$hOwnerWin = DllStructGetData($tTRAYDATA, 1)
	If @error Or $hOwnerWin = 0 Then ContinueLoop
	$iPID = WinGetProcess($hOwnerWin)
	If @error Or $iPID = -1 Then ContinueLoop
	$hIconTray = DllStructGetData($tTRAYDATA, 5) ;returned icon handles shared
;~ 	ConsoleWrite($sRet & @CRLF)
	$procc = _ProcessGetName($iPID)
	If $procc = 'egui.exe' Then
		_WinAPI_SaveHICONToFile(@ScriptDir & '\MyIcon.ico', $hIconTray)
		$ex = 1
	EndIf
	$sRet = ""
	$iIdx += 1
	_WinAPI_DestroyIcon($hIcon)
	_WinAPI_DestroyIcon($hIconTray) ;does not destroy traydata handles
	If $ex Then ExitLoop
Next

DllCall($iDLLKrnl32, "int", "VirtualFreeEx", "ptr", $hProcess, "ptr", $pAddress, "ulong_ptr", 0, "dword", $MEM_RELEASE)
DllCall($iDLLKrnl32, "int", "CloseHandle", "ptr", $hProcess)
DllClose($iDLLUser32)
DllClose($iDLLKrnl32)
ToolTip("")
Exit

Func _GetTrayIconHandle($hWnd, $hDLLUser32 = "User32.dll")
	If Not IsHWnd($hWnd) Then Return SetError(1, 1, -1)
	Local $iPID, $ParentPID, $aWinList
	$hIcon = _GetIcon($hWnd, $hDLLUser32)
	If Not @error And $hIcon <> -1 Then Return SetError(0, 0, $hIcon)
	$ParentPID = WinGetProcess($hWnd)
	If @error Or $ParentPID = -1 Then Return SetError(2, 2, -1)
	$aWinList = WinList()
	For $i = 1 To $aWinList[0][0]
		$iPID = WinGetProcess($aWinList[$i][1])
		If @error Or $iPID = -1 Then ContinueLoop
		If $iPID = $ParentPID Then
			$hIcon = _GetIcon($aWinList[$i][1], $hDLLUser32)
			If Not @error And $hIcon <> -1 Then Return SetError(0, 0, $hIcon)
		EndIf
	Next
	Return SetError(2, 2, -1)
EndFunc   ;==>_GetTrayIconHandle

;modified from ModernMenu Win2Tray - by Holger Kotsch
Func _GetIcon(ByRef $hWnd, $hDLLUser32 = "User32.dll")
	If Not IsHWnd($hWnd) Then Return SetError(1, 1, -1)
	Local Const $GCL_HICON = -14
	Local Const $GCL_HICONSM = -34
	Local $hIcon
	$hIcon = _SendMessage($hWnd, $WM_GETICON, 2, 0)
	If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon))
	$hIcon = _SendMessage($hWnd, $WM_GETICON, 0, 0)
	If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon))
	$hIcon = _WinAPI_GetClassLongEx($hWnd, $GCL_HICONSM)
	If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon))
	$hIcon = _WinAPI_GetClassLongEx($hWnd, $GCL_HICON)
	If Not @error And _IsIconHandle($hIcon, $sRet) = True Then Return SetError(0, 0, Ptr($hIcon))
	Return SetError(2, 2, -1)
EndFunc   ;==>_GetIcon

Func _IsIconHandle($hIcon, ByRef $sMod)
	;rover 2k11
	Local $aRet
	Switch @OSVersion
		Case "WIN_2008R2", "WIN_7", "WIN_2008", "WIN_VISTA"
			$aRet = _WinAPI_GetIconInfoEx($hIcon)
			If @error Then Return SetError(1, 1, False)
			DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", $aRet[3])
			DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", $aRet[4])
			If $aRet[0] = 0 Then Return SetError(2, 2, False)
			$sMod = $aRet[6]
			Return SetError(0, 0, True)
		Case "WIN_2003", "WIN_XP"
			Local $tIconInfo = DllStructCreate("int fIcon;int xHotspot;int yHotspot;ptr hbmMask;ptr hbmColor")
			Local $aRet = DllCall("User32.dll", "int", "GetIconInfo", "ptr", $hIcon, "ptr", DllStructGetPtr($tIconInfo))
			If @error Or UBound($aRet) <> 3 Or $aRet[0] = 0 Then Return SetError(1, 1, False)
			DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", DllStructGetData($tIconInfo, 4))
			DllCall("gdi32.dll", "bool", "DeleteObject", "ptr", DllStructGetData($tIconInfo, 5))
			If Not DllStructGetData($tIconInfo, 1) Then Return SetError(2, 2, False)
			Return SetError(0, 0, True)
	EndSwitch
EndFunc   ;==>_IsIconHandle
 
Автор
B

badhabit

Новичок
Сообщения
36
Репутация
0
damien2008, а не подскажете где в коде место где можно по имени заголовка программы найти его "кнопку" на трее?
 
Верх