#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