Что нового

Отображение прогресса выполнения на иконке в трее

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Функция отображения прогресса выполнения в процентах на иконке в трее.
Теперь в двух трех вариантах.
1. _TraySetIconProgressLight() - практически без опций:
Код:
#include <APIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

Opt('TrayMenuMode', 1)
Opt('MustDeclareVars', 1)

Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $iCount = -1, $iMax = 333

_GDIPlus_Startup()
OnAutoItExitRegister('_Exit')
_WinAPI_EmptyWorkingSet()

MsgBox(64, 'Info', 'Start')
_Count()
AdlibRegister('_Count', 100)

While 1
	Sleep(50)
WEnd

Func _Count()
	Local $i_Persent
	$iCount += 1
	$i_Persent = 100 * $iCount / $iMax
	_TraySetIconProgressLight($i_Persent)
	If @error Then
		ConsoleWrite(@error & @LF)
	EndIf
	If $iCount = $iMax Then
		AdlibUnRegister('_Count')
		;TraySetIcon()
		;TraySetToolTip()
		MsgBox(64, 'Info', $i_Persent & '%')
		Exit
	EndIf
EndFunc   ;==>_Count

Func _Exit()
	_GDIPlus_Shutdown()
EndFunc   ;==>_Exit


; #FUNCTION# ====================================================================================================
; Name...........: _TraySetIconProgressLight
; Description....: Отображает прогресс выполнения на иконке в трее в процентах.
; Syntax.........: _SetTrayIconProgress($i_Persent, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC, $f_ToolTip = False)
; Parameters.....: $i_Persent - процент (от 0 до 100)
;                  $i_Color [Optional] - цвет полосы прогресса. По умолчанию зеленый (0x00FF00).
;                  $i_BkColor [Optional] - цвет фона. По умолчанию серый (0xDCDCDC).
;				   $f_ToolTip [Optional] - True или <> 0 отображать процент с использованием TraySetToolTip в формате I.FF%;
;                  False или 0 не отображать
;                  По умолчанию True отображать.
;
; Return values..: Success - 1
;                  Failure - 0 и флаг @error не равный 0
;
; Author.........: madmasles
;
; Remarks........: Идеи для реализации взяты здесь:
;                  Yashied   http://autoit-script.ru/index.php?topic=10661.msg70606#msg70606
;                  Yashied, http://autoit-script.ru/index.php?topic=7010.msg48475#msg48475
;                  Используется функция _GDIPlus_LineBrushCreateFromRect() из GDIP.au3
;                  (http://autoit-script.ru/index.php/topic,1384.0.html)
;
; Link...........: http://autoit-script.ru/index.php/topic,8343.0.html
; Example........: Есть
; ===============================================================================================================
Func _TraySetIconProgressLight($i_Persent, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC, $f_ToolTip = True)

	Static $h__IconProgress = 0
	Static $i__PersentProgress = -1

	Local $t_NID, $ah_Bitmap[2], $h_Icon, $h_Graphic, $h_Image, $t_Data, $t_Rect, $i_Start, $i_End, $i_Error

	If $f_ToolTip Then
		TraySetToolTip(StringFormat('%.2f%', $i_Persent))
	EndIf
	$i_Persent = Abs(Int($i_Persent / 6))
	If $i_Persent > 16 Then $i_Persent = 16
	If $i__PersentProgress = $i_Persent Then Return
	$i__PersentProgress = $i_Persent
	If Not $i_Persent Then
		$i_Start = 1
		$i_End = 2
	ElseIf $i_Persent = 16 Then
		$i_Start = 3
		$i_End = 4
	Else
		$i_Start = 1
		$i_End = 4
	EndIf
	$i_Color += 0xFF000000
	$i_BkColor += 0xFF000000

	Local $ah_Brush[5][7] = [[4],[0, 16 - $i_Persent, 0x00FFFFFF, $i_BkColor, $i_Persent, 0, 16 - $i_Persent], _
			[0, 16 - $i_Persent, $i_BkColor, 0x00FFFFFF, $i_Persent, 8, 16 - $i_Persent], _
			[0, $i_Persent, 0x00FFFFFF, $i_Color, 0, 0, $i_Persent], _
			[0, $i_Persent, $i_Color, 0x00FFFFFF, 0, 8, $i_Persent]]

	For $j = 1 To 1
		$t_Rect = DllStructCreate($tagGDIPRECTF)
		DllStructSetData($t_Rect, 1, 0)
		DllStructSetData($t_Rect, 2, 0)
		DllStructSetData($t_Rect, 4, 8)
		For $i = $i_Start To $i_End
			DllStructSetData($t_Rect, 3, $ah_Brush[$i][1])
			$ah_Brush[$i][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_Brush[$i][2], $ah_Brush[$i][3], 1)
			If @error Then ExitLoop 2
		Next
		$h_Image = _GDIPlus_CreateBitmapFromScan0(16, 16)
		If @error Then ExitLoop
		$h_Graphic = _GDIPlus_ImageGetGraphicsContext($h_Image)
		If @error Then ExitLoop
		For $i = $i_Start To $i_End
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_Brush[$i][4], $ah_Brush[$i][5], $ah_Brush[$i][6], 8, $ah_Brush[$i][0])
			If @error Then ExitLoop 2
		Next
		$ah_Bitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
		If @error Then ExitLoop
		$t_Data = _GDIPlus_BitmapLockBits($h_Image, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
		If @error Then ExitLoop
		_WinAPI_SetBitmapBits($ah_Bitmap[0], 1024, DllStructGetData($t_Data, 'Scan0'))
		If @error Then ExitLoop
		_GDIPlus_BitmapUnlockBits($ah_Bitmap, $t_Data)
		If @error Then ExitLoop
		$ah_Bitmap[1] = _WinAPI_CreateBitmap(16, 16)
		If @error Then ExitLoop
		$h_Icon = _WinAPI_CreateIconIndirect($ah_Bitmap[0], $ah_Bitmap[1])
		If @error Then ExitLoop
		$t_NID = DllStructCreate($tagNOTIFYICONDATA)
		DllStructSetData($t_NID, 'Size', DllStructGetSize($t_NID))
		DllStructSetData($t_NID, 'hWnd', $hAutoIt)
		DllStructSetData($t_NID, 'Flags', $NIF_ICON)
		DllStructSetData($t_NID, 'ID', 1)
		DllStructSetData($t_NID, 'hIcon', $h_Icon)
		_WinAPI_ShellNotifyIcon($NIM_MODIFY, $t_NID)
	Next
	$i_Error = @error
	For $i = $i_Start To $i_End
		_GDIPlus_BrushDispose($ah_Brush[$i][0])
	Next
	_GDIPlus_GraphicsDispose($h_Graphic)
	_GDIPlus_ImageDispose($h_Image)
	For $i = 0 To 1
		_WinAPI_DeleteObject($ah_Bitmap[$i])
	Next
	If $h__IconProgress Then
		_WinAPI_DestroyIcon($h__IconProgress)
	EndIf
	$h__IconProgress = $h_Icon
	If $i_Error Then Return SetError($i_Error, 0, 0)
	Return 1
EndFunc   ;==>_TraySetIconProgressLight

Func _GDIPlus_CreateBitmapFromScan0($i_Width, $i_Height, $i_Stride = 0, $i_PixelFormat = 0x0026200A, $p_Scan0 = 0)

	Local $a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $i_Width, 'int', $i_Height, 'int', $i_Stride, 'int', $i_PixelFormat, 'ptr', $p_Scan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

;From GDIP.au3
Func _GDIPlus_LineBrushCreateFromRect($t_RectF, $i_ARGBClr1, $i_ARGBClr2, $i_GradientMode = 0, $i_WrapMode = 0)
	Local $p_RectF, $a_Ret

	$p_RectF = DllStructGetPtr($t_RectF)
	$a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateLineBrushFromRect', 'ptr', $p_RectF, 'uint', $i_ARGBClr1, 'uint', $i_ARGBClr2, 'int', $i_GradientMode, 'int', $i_WrapMode, 'int*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_LineBrushCreateFromRect
2. _TraySetIconProgress() - рамка, направление движения прогресса, эффект размытости или без:
Код:
#include <APIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>


Opt('TrayMenuMode', 1)
Opt('MustDeclareVars', 1)

Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $iCount = -1, $iMax = 333, $iNext = 0

_GDIPlus_Startup()
OnAutoItExitRegister('_Exit')
_WinAPI_EmptyWorkingSet()

MsgBox(64, 'Info', 'Start №' & $iNext + 1 & ' (4)')
_Count()
AdlibRegister('_Count', 100)

While 1
	Sleep(50)
WEnd

Func _Count()
	Local $i_Persent, $aParameters[4][6] = [[0x00FF00, 0xDCDCDC, 'No Border', 0, 1, 0], _
			[0x00FF00, 0xDCDCDC, 0x000000, 1, 0, 1], _
			[0x00FF00, 0xDCDCDC, 0xFFFFFF, 2, 1, 0], _
			[0x00FF00, 0xDCDCDC, Default, 3, 1, 1]]
	$iCount += 1
	$i_Persent = 100 * $iCount / $iMax
	;ConsoleWrite(StringFormat('%.2f%', $i_Persent) & @LF)
	_TraySetIconProgress($i_Persent, $aParameters[$iNext][0], $aParameters[$iNext][1], $aParameters[$iNext][2], $aParameters[$iNext][3], $aParameters[$iNext][4], $aParameters[$iNext][5])
	If @error Then
		ConsoleWrite(@error & @LF)
	EndIf
	If $iCount = $iMax Then
		AdlibUnRegister('_Count')
		$iNext += 1
		If $iNext > 3 Then
			MsgBox(64, 'Info', $i_Persent & '%')
			TraySetIcon()
			TraySetToolTip()
			MsgBox(64, 'Info', 'Exit')
			Exit
		EndIf
		$iCount = -1
		MsgBox(64, 'Info', 'Start №' & $iNext + 1 & ' (4)')
		TraySetToolTip()
		AdlibRegister('_Count', 100)
	EndIf
EndFunc   ;==>_Count

Func _Exit()
	_GDIPlus_Shutdown()
EndFunc   ;==>_Exit

; #FUNCTION# ====================================================================================================
; Name...........: _TraySetIconProgress
; Description....: Отображает прогресс выполнения на иконке в трее в процентах.
; Syntax.........: _TraySetIconProgress($i_Persent, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC, $i_BorderColor = Default, $i_Style = 0, $f_Blur = True, $f_ToolTip = False)
;
; Parameters.....: $i_Persent - процент (от 0 до 100).
;
;                  $i_Color [Optional] - RGB цвет полосы прогресса. По умолчанию зеленый (0x00FF00).
;
;                  $i_BkColor [Optional] - RGB цвет фона. По умолчанию серый (0xDCDCDC).
;
;                  $i_BorderColor [Optional] - RGB цвет рамки (бордюра). Default или любая строка - без рамки (бордюра).
;                       По умолчанию - Default без рамки (бордюра).
;
;                  $i_Style [Optional] - направление прогресса:
;                       0 - слева направо (больше 3 приравнивается к 0);
;                       1 - справа налево;
;                       2 - снизу вверх;
;                       3 - сверху вниз.
;                       По умолчанию 0.
;
;                  $f_Blur [Optional] - эффект размытости. True или <> 0 - да, False или 0 - нет. По умолчанию True.
;
;				   $f_ToolTip [Optional] - True или <> 0 отображать процент с использованием TraySetToolTip в формате ii.ff%;
;                       False или 0 не отображать
;                       По умолчанию False.
;
; Return values..: Success - 1
;                  Failure - 0 и флаг @error не равный 0
;
; Author.........: madmasles
;
; Remarks........: Идеи для реализации взяты здесь:
;                  Yashied   http://autoit-script.ru/index.php?topic=10661.msg70606#msg70606
;                  Yashied, http://autoit-script.ru/index.php?topic=7010.msg48475#msg48475
;                  Используется функция _GDIPlus_LineBrushCreateFromRect() из GDIP.au3
;                  (http://autoit-script.ru/index.php/topic,1384.0.html)
;
; Link...........: http://autoit-script.ru/index.php/topic,8343.0.html
; Example........: Есть
; ===============================================================================================================
Func _TraySetIconProgress($i_Persent, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC, $i_BorderColor = Default, $i_Style = 0, $f_Blur = True, $f_ToolTip = False)

	Static $h__IconProgress = 0
	Static $i__PersentProgress = -1

	Local $t_NID, $ah_Bitmap[2], $h_Icon, $h_Graphic, $h_Image, $t_Data, $t_Rect, $i_Start, $i_End, $i_Error, $i_Element, $i_GradientMode, _
			$i_BlurColor, $i_BlurBcColor

	If $f_ToolTip Then
		TraySetToolTip(StringFormat('%.2f%', $i_Persent))
	EndIf
	$i_Persent = Abs(Int($i_Persent / 6))
	If $i_Persent > 16 Then $i_Persent = 16
	If $i__PersentProgress = $i_Persent Then Return
	$i__PersentProgress = $i_Persent
	If Not $i_Persent Then
		$i_Start = 1
		$i_End = 2
	ElseIf $i_Persent = 16 Then
		$i_Start = 3
		$i_End = 4
	Else
		$i_Start = 1
		$i_End = 4
	EndIf
	$i_Color += 0xFF000000
	$i_BkColor += 0xFF000000
	If $f_Blur Then
		$i_BlurColor = 0x00FFFFFF
		$i_BlurBcColor = 0x00FFFFFF
	Else
		$i_BlurColor = $i_Color
		$i_BlurBcColor = $i_BkColor
	EndIf
	$t_Rect = DllStructCreate($tagGDIPRECTF)
	DllStructSetData($t_Rect, 1, 0)
	DllStructSetData($t_Rect, 2, 0)
	Switch $i_Style
		Case 1
			$i_GradientMode = 1
			DllStructSetData($t_Rect, 4, 8)
			$i_Element = 3
			Local $ah_Brush[5][8] = [[4],[0, 16 - $i_Persent, $i_BlurBcColor, $i_BkColor, 0, 0, 16 - $i_Persent, 8], _
					[0, 16 - $i_Persent, $i_BkColor, $i_BlurBcColor, 0, 8, 16 - $i_Persent, 8], _
					[0, $i_Persent, $i_BlurColor, $i_Color, 16 - $i_Persent, 0, $i_Persent, 8], _
					[0, $i_Persent, $i_Color, $i_BlurColor, 16 - $i_Persent, 8, $i_Persent, 8]]
		Case 2
			$i_GradientMode = 0
			DllStructSetData($t_Rect, 3, 8)
			$i_Element = 4
			Local $ah_Brush[5][8] = [[4],[0, 16 - $i_Persent, $i_BlurBcColor, $i_BkColor, 0, 0, 8, 16 - $i_Persent], _
					[0, 16 - $i_Persent, $i_BkColor, $i_BlurBcColor, 8, 0, 8, 16 - $i_Persent], _
					[0, $i_Persent, $i_BlurColor, $i_Color, 0, 16 - $i_Persent, 8, $i_Persent], _
					[0, $i_Persent, $i_Color, $i_BlurColor, 8, 16 - $i_Persent, 8, $i_Persent]]
		Case 3
			$i_GradientMode = 0
			DllStructSetData($t_Rect, 3, 8)
			$i_Element = 4
			Local $ah_Brush[5][8] = [[4],[0, 16 - $i_Persent, $i_BlurBcColor, $i_BkColor, 0, $i_Persent, 8, 16 - $i_Persent], _
					[0, 16 - $i_Persent, $i_BkColor, $i_BlurBcColor, 8, $i_Persent, 8, 16 - $i_Persent], _
					[0, $i_Persent, $i_BlurColor, $i_Color, 0, 0, 8, $i_Persent], _
					[0, $i_Persent, $i_Color, $i_BlurColor, 8, 0, 8, $i_Persent]]
		Case Else
			$i_GradientMode = 1
			DllStructSetData($t_Rect, 4, 8)
			$i_Element = 3
			Local $ah_Brush[5][8] = [[4],[0, 16 - $i_Persent, $i_BlurBcColor, $i_BkColor, $i_Persent, 0, 16 - $i_Persent, 8], _
					[0, 16 - $i_Persent, $i_BkColor, $i_BlurBcColor, $i_Persent, 8, 16 - $i_Persent, 8], _
					[0, $i_Persent, $i_BlurColor, $i_Color, 0, 0, $i_Persent, 8], _
					[0, $i_Persent, $i_Color, $i_BlurColor, 0, 8, $i_Persent, 8]]
	EndSwitch
	If IsInt($i_BorderColor) Then
		Local $ah_BrushBorder[3][12] = [[2],[0, 1, 16, $i_BorderColor + 0xFF000000, 0, 0, 1, 16, 15, 0, 1, 16], _
				[0, 16, 1, $i_BorderColor + 0xFF000000, 0, 0, 16, 1, 0, 15, 16, 1]]
	EndIf
	For $j = 1 To 1
		For $i = $i_Start To $i_End
			DllStructSetData($t_Rect, $i_Element, $ah_Brush[$i][1])
			$ah_Brush[$i][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_Brush[$i][2], $ah_Brush[$i][3], $i_GradientMode)
			If @error Then ExitLoop 2
		Next
		$h_Image = _GDIPlus_CreateBitmapFromScan0(16, 16)
		If @error Then ExitLoop
		$h_Graphic = _GDIPlus_ImageGetGraphicsContext($h_Image)
		If @error Then ExitLoop
		For $i = $i_Start To $i_End
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_Brush[$i][4], $ah_Brush[$i][5], $ah_Brush[$i][6], $ah_Brush[$i][7], $ah_Brush[$i][0])
			If @error Then ExitLoop 2
		Next
		If IsInt($i_BorderColor) Then
			For $i = 1 To $ah_BrushBorder[0][0]
				DllStructSetData($t_Rect, 3, $ah_BrushBorder[$i][1])
				DllStructSetData($t_Rect, 4, $ah_BrushBorder[$i][2])
				$ah_BrushBorder[$i][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_BrushBorder[$i][3], $ah_BrushBorder[$i][3], 1)
				If @error Then ExitLoop 2
				_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorder[$i][4], $ah_BrushBorder[$i][5], $ah_BrushBorder[$i][6], $ah_BrushBorder[$i][7], $ah_BrushBorder[$i][0])
				If @error Then ExitLoop 2
				_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorder[$i][8], $ah_BrushBorder[$i][9], $ah_BrushBorder[$i][10], $ah_BrushBorder[$i][11], $ah_BrushBorder[$i][0])
				If @error Then ExitLoop 2
			Next
		EndIf
		$ah_Bitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
		If @error Then ExitLoop
		$t_Data = _GDIPlus_BitmapLockBits($h_Image, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
		If @error Then ExitLoop
		_WinAPI_SetBitmapBits($ah_Bitmap[0], 1024, DllStructGetData($t_Data, 'Scan0'))
		If @error Then ExitLoop
		_GDIPlus_BitmapUnlockBits($ah_Bitmap, $t_Data)
		If @error Then ExitLoop
		$ah_Bitmap[1] = _WinAPI_CreateBitmap(16, 16)
		If @error Then ExitLoop
		$h_Icon = _WinAPI_CreateIconIndirect($ah_Bitmap[0], $ah_Bitmap[1])
		If @error Then ExitLoop
		$t_NID = DllStructCreate($tagNOTIFYICONDATA)
		DllStructSetData($t_NID, 'Size', DllStructGetSize($t_NID))
		DllStructSetData($t_NID, 'hWnd', $hAutoIt)
		DllStructSetData($t_NID, 'Flags', $NIF_ICON)
		DllStructSetData($t_NID, 'ID', 1)
		DllStructSetData($t_NID, 'hIcon', $h_Icon)
		_WinAPI_ShellNotifyIcon($NIM_MODIFY, $t_NID)
	Next
	$i_Error = @error
	For $i = $i_Start To $i_End
		_GDIPlus_BrushDispose($ah_Brush[$i][0])
	Next
	If IsInt($i_BorderColor) Then
		For $i = 1 To $ah_BrushBorder[0][0]
			_GDIPlus_BrushDispose($ah_BrushBorder[$i][0])
		Next
	EndIf
	_GDIPlus_GraphicsDispose($h_Graphic)
	_GDIPlus_ImageDispose($h_Image)
	For $i = 0 To 1
		_WinAPI_DeleteObject($ah_Bitmap[$i])
	Next
	If $h__IconProgress Then
		_WinAPI_DestroyIcon($h__IconProgress)
	EndIf
	$h__IconProgress = $h_Icon
	If $i_Error Then Return SetError($i_Error, 0, 0)
	Return 1
EndFunc   ;==>_TraySetIconProgress

Func _GDIPlus_CreateBitmapFromScan0($i_Width, $i_Height, $i_Stride = 0, $i_PixelFormat = 0x0026200A, $p_Scan0 = 0)

	Local $a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $i_Width, 'int', $i_Height, 'int', $i_Stride, 'int', $i_PixelFormat, 'ptr', $p_Scan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

;From GDIP.au3
Func _GDIPlus_LineBrushCreateFromRect($t_RectF, $i_ARGBClr1, $i_ARGBClr2, $i_GradientMode = 0, $i_WrapMode = 0)
	Local $p_RectF, $a_Ret

	$p_RectF = DllStructGetPtr($t_RectF)
	$a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateLineBrushFromRect', 'ptr', $p_RectF, 'uint', $i_ARGBClr1, 'uint', $i_ARGBClr2, 'int', $i_GradientMode, 'int', $i_WrapMode, 'int*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_LineBrushCreateFromRect
3. _TraySetIconProgressEx() - последний (надеюсь :smile: ) вариант, в виде наполняющегося стакана.
Код:
#include <APIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>

Opt('TrayMenuMode', 1)
Opt('MustDeclareVars', 1)

Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
Global $iCount = -1, $iMax = 333

_GDIPlus_Startup()
OnAutoItExitRegister('_Exit')
_WinAPI_EmptyWorkingSet()

MsgBox(64, 'Info', 'Start')
_Percent()
AdlibRegister('_Percent', 100)

While 1
	Sleep(100)
WEnd

Func _Percent()
	Local $i_Percent
	$iCount += 1
	$i_Percent = 100 * $iCount / $iMax
	_TraySetIconProgressEx($i_Percent, True)
	If @error Then
		ConsoleWrite(@error & @LF)
	EndIf
	If $iCount = $iMax Then
		AdlibUnRegister('_Percent')
		MsgBox(64, 'Info', $i_Percent & '%')
		Exit
	EndIf
EndFunc   ;==>_Percent

Func _Exit()
	_GDIPlus_Shutdown()
EndFunc   ;==>_Exit

; #FUNCTION# ====================================================================================================
; Name...........: _TraySetIconProgressEx
; Description....: Отображает прогресс выполнения на иконке в трее в виде наполняющегося стакана.
; Syntax.........: _TraySetIconProgressEx($i_Percent, $f_ToolTip, $i_Color, $i_BkColor)
; Parameters.....: $i_Percent - процент (от 0.00 до 100.00)
;
;				   $f_ToolTip [Optional] - True или <> 0 отображать процент с использованием TraySetToolTip в формате ii.ff%;
;                       False или 0 не отображать
;                       По умолчанию True.
;
;                  $i_Color [Optional] - цвет полосы прогресса. По умолчанию зеленый (0x00FF00).
;                  $i_BkColor [Optional] - цвет фона. По умолчанию серый (0xDCDCDC).
;
; Return values..: Success - 1
;                  Failure - 0 и флаг @error не равный 0
;
; Author.........: madmasles
;
; Remarks........: Идеи для реализации взяты здесь:
;                  Yashied   http://autoit-script.ru/index.php?topic=10661.msg70606#msg70606
;                  Yashied, http://autoit-script.ru/index.php?topic=7010.msg48475#msg48475
;                  Используется функция _GDIPlus_LineBrushCreateFromRect() из GDIP.au3
;                  (http://autoit-script.ru/index.php/topic,1384.0.html)
;
; Link...........: http://autoit-script.ru/index.php/topic,8343.0.html
; Example........: Есть
; ===============================================================================================================
Func _TraySetIconProgressEx($i_Percent, $f_ToolTip = False, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC)
	Static $h__IconProgress = 0
	Static $i__PercentProgress = -1

	Local $t_NID, $ah_Bitmap[2], $h_Icon, $h_Graphic, $h_Image, $t_Data, $t_Rect, $i_Start, $i_End, $i_Error, $i_Element, _
			$i_Blur, $i_ColorBottom, $h_BrushBottom

	$i_Percent = Abs($i_Percent)
	If $i_Percent > 100 Then $i_Percent = 100
	If $f_ToolTip Then
		TraySetToolTip(StringFormat('%.2f%', $i_Percent))
	EndIf
	$i_Percent = Int($i_Percent / 6)
	If $i__PercentProgress = $i_Percent Then Return
	$i__PercentProgress = $i_Percent
	$i_Color += 0xFF000000
	$i_BkColor += 0xFF000000
	$i_Blur = 0x00FFFFFF
	Switch $i_Percent
		Case 0
			$i_ColorBottom = $i_BkColor
			$i_Start = 1
			$i_End = 2
		Case 16
			$i_ColorBottom = $i_Color
			$i_Start = 3
			$i_End = 4
		Case Else
			$i_ColorBottom = $i_Color
			$i_Start = 1
			$i_End = 4
	EndSwitch
	$t_Rect = DllStructCreate($tagGDIPRECTF)
	DllStructSetData($t_Rect, 1, 0)
	DllStructSetData($t_Rect, 2, 0)
	DllStructSetData($t_Rect, 3, 8)
	$i_Element = 4
	Local $ah_Brush[5][8] = [[4],[0, 16 - $i_Percent, $i_Blur, $i_BkColor, 0, 0, 8, 16 - $i_Percent], _
			[0, 16 - $i_Percent, $i_BkColor, $i_Blur, 8, 0, 8, 16 - $i_Percent], _
			[0, $i_Percent, $i_Blur, $i_Color, 0, 16 - $i_Percent, 8, $i_Percent], _
			[0, $i_Percent, $i_Color, $i_Blur, 8, 16 - $i_Percent, 8, $i_Percent]]
	Local $ah_BrushBorderC[1][12] = [[0, 1, $i_Percent, $i_Color, 0, 16 - $i_Percent, 1, $i_Percent, 15, 16 - $i_Percent, 1, $i_Percent]]
	Local $ah_BrushBorderBk[1][12] = [[0, 1, 16 - $i_Percent, $i_BkColor, 0, 0, 1, 16 - $i_Percent, 15, 0, 1, 16 - $i_Percent]]
	For $j = 1 To 1
		For $i = $i_Start To $i_End
			DllStructSetData($t_Rect, 4, $ah_Brush[$i][1])
			$ah_Brush[$i][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_Brush[$i][2], $ah_Brush[$i][3])
			If @error Then ExitLoop 2
		Next
		$h_Image = _GDIPlus_CreateBitmapFromScan0(16, 16)
		If @error Then ExitLoop
		$h_Graphic = _GDIPlus_ImageGetGraphicsContext($h_Image)
		If @error Then ExitLoop
		For $i = $i_Start To $i_End
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_Brush[$i][4], $ah_Brush[$i][5], $ah_Brush[$i][6], $ah_Brush[$i][7], $ah_Brush[$i][0])
			If @error Then ExitLoop 2
		Next
		If $i_Percent Then
			DllStructSetData($t_Rect, 3, $ah_BrushBorderC[0][1])
			DllStructSetData($t_Rect, 4, $ah_BrushBorderC[0][2])
			$ah_BrushBorderC[0][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_BrushBorderC[0][3], $ah_BrushBorderC[0][3])
			If @error Then ExitLoop 2
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorderC[0][4], $ah_BrushBorderC[0][5], $ah_BrushBorderC[0][6], $ah_BrushBorderC[0][7], $ah_BrushBorderC[0][0])
			If @error Then ExitLoop 2
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorderC[0][8], $ah_BrushBorderC[0][9], $ah_BrushBorderC[0][10], $ah_BrushBorderC[0][11], $ah_BrushBorderC[0][0])
			If @error Then ExitLoop 2
		EndIf
		If $i_Percent < 16 Then
			DllStructSetData($t_Rect, 3, $ah_BrushBorderBk[0][1])
			DllStructSetData($t_Rect, 4, $ah_BrushBorderBk[0][2])
			$ah_BrushBorderBk[0][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_BrushBorderBk[0][3], $ah_BrushBorderBk[0][3])
			If @error Then ExitLoop 2
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorderBk[0][4], $ah_BrushBorderBk[0][5], $ah_BrushBorderBk[0][6], $ah_BrushBorderBk[0][7], $ah_BrushBorderBk[0][0])
			If @error Then ExitLoop 2
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_BrushBorderBk[0][8], $ah_BrushBorderBk[0][9], $ah_BrushBorderBk[0][10], $ah_BrushBorderBk[0][11], $ah_BrushBorderBk[0][0])
			If @error Then ExitLoop 2
		EndIf
		DllStructSetData($t_Rect, 3, 16)
		DllStructSetData($t_Rect, 4, 1)
		$h_BrushBottom = _GDIPlus_LineBrushCreateFromRect($t_Rect, $i_ColorBottom, $i_ColorBottom)
		If @error Then ExitLoop
		_GDIPlus_GraphicsFillRect($h_Graphic, 0, 15, 16, 1, $h_BrushBottom)
		If @error Then ExitLoop
		$ah_Bitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
		If @error Then ExitLoop
		$t_Data = _GDIPlus_BitmapLockBits($h_Image, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
		If @error Then ExitLoop
		_WinAPI_SetBitmapBits($ah_Bitmap[0], 1024, DllStructGetData($t_Data, 'Scan0'))
		If @error Then ExitLoop
		_GDIPlus_BitmapUnlockBits($ah_Bitmap, $t_Data)
		If @error Then ExitLoop
		$ah_Bitmap[1] = _WinAPI_CreateBitmap(16, 16)
		If @error Then ExitLoop
		$h_Icon = _WinAPI_CreateIconIndirect($ah_Bitmap[0], $ah_Bitmap[1])
		If @error Then ExitLoop
		$t_NID = DllStructCreate($tagNOTIFYICONDATA)
		DllStructSetData($t_NID, 'Size', DllStructGetSize($t_NID))
		DllStructSetData($t_NID, 'hWnd', $hAutoIt)
		DllStructSetData($t_NID, 'Flags', $NIF_ICON)
		DllStructSetData($t_NID, 'ID', 1)
		DllStructSetData($t_NID, 'hIcon', $h_Icon)
		_WinAPI_ShellNotifyIcon($NIM_MODIFY, $t_NID)
	Next
	$i_Error = @error
	For $i = $i_Start To $i_End
		_GDIPlus_BrushDispose($ah_Brush[$i][0])
	Next
	_GDIPlus_BrushDispose($ah_BrushBorderBk[0][0])
	_GDIPlus_BrushDispose($ah_BrushBorderC[0][0])
	_GDIPlus_BrushDispose($h_BrushBottom)
	_GDIPlus_GraphicsDispose($h_Graphic)
	_GDIPlus_ImageDispose($h_Image)
	For $i = 0 To 1
		_WinAPI_DeleteObject($ah_Bitmap[$i])
	Next
	If $h__IconProgress Then
		_WinAPI_DestroyIcon($h__IconProgress)
	EndIf
	$h__IconProgress = $h_Icon
	If $i_Error Then Return SetError($i_Error, 0, 0)
	Return 1
EndFunc   ;==>_TraySetIconProgressEx

Func _GDIPlus_CreateBitmapFromScan0($i_Width, $i_Height, $i_Stride = 0, $i_PixelFormat = 0x0026200A, $p_Scan0 = 0)
	Local $a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $i_Width, 'int', $i_Height, 'int', $i_Stride, 'int', $i_PixelFormat, 'ptr', $p_Scan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

;From GDIP.au3
Func _GDIPlus_LineBrushCreateFromRect($t_RectF, $i_ARGBClr1, $i_ARGBClr2, $i_GradientMode = 0, $i_WrapMode = 0)
	Local $p_RectF, $a_Ret

	$p_RectF = DllStructGetPtr($t_RectF)
	$a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateLineBrushFromRect', 'ptr', $p_RectF, 'uint', $i_ARGBClr1, 'uint', $i_ARGBClr2, 'int', $i_GradientMode, 'int', $i_WrapMode, 'int*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_LineBrushCreateFromRect
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Замечательно!
Похожа на индикатор заряда батареи)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Неплохо!

Но я бы назвал функцию _TraySetProgressIcon, так ближе к Tray* функциям.

И ещё, неплохо было бы задавать параметрами стиль прогресса.
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
Но я бы назвал функцию _TraySetProgressIcon, так ближе к Tray* функциям.И ещё, неплохо было бы задавать параметрами стиль прогресса.
Переименовал на _TraySetIconProgress(). А насчет стилей, если можно, поясните, где и какие стили можно задать.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles [?]
если можно, поясните, где и какие стили можно задать
Где и как я пока сам не разобрался, надеялся что вам как автору функции это будет проще :smile:.
Я имел в виду стиль типа вертикальный/горизонтальный прогресс, рамка, заполнение с права налево (или сверху вниз соответственно), и т.п.
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
стиль типа вертикальный/горизонтальный прогресс, рамка, заполнение с права налево (или сверху вниз соответственно), и т.п.
Буду экспериментировать. :smile:
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
А чё прогрессбар а не циферки (проценты) ? :smile:
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
ну да, циферки тоже бы не плохо.
я скрутил на скорую руку

Код:
#RequireAdmin
#include <APIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
_WinAPI_EmptyWorkingSet()
Opt('TrayMenuMode', 1 + 2)
TraySetIcon('shell32.dll', 21)
Global $nExit = TrayCreateItem('Exit')
Global $hDownload
Global Const $hAutoIt = WinGetHandle(AutoItWinGetTitle())
TraySetClick(16)
HotKeySet('^{F1}', '_exit')
AdlibRegister('_tray', 50)

_load()

Func _tray()
	Switch TrayGetMsg()
		Case $nExit
			_exit()
	EndSwitch
EndFunc   ;==>_tray

Func _load()
	_GDIPlus_Startup()
	$hDownload = InetGet('http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe', @ScriptDir & '\drweb-cureit.exe', 1, 1)
	Do
		If InetGetInfo($hDownload, 1) Then
			$i_Persent = Round((InetGetInfo($hDownload, 0) / InetGetInfo($hDownload, 1)) * 100)
			_TraySetIconProgress($i_Persent)
		EndIf
		Sleep(500)
	Until InetGetInfo($hDownload, 2)
	InetClose($hDownload)
	_GDIPlus_Shutdown()
	TrayTip('Info', 'загрузка завершена', 5, 1)
	Sleep(5000)
EndFunc   ;==>_load

Func _exit()
	InetClose($hDownload)
	_GDIPlus_Shutdown()
	Exit
EndFunc   ;==>_exit

Func _TraySetIconProgress($i_Persent, $i_Color = 0x00FF00, $i_BkColor = 0xDCDCDC, $f_ToolTip = True)

	Static $hPrev = 0
	Static $iPersentOld = -1

	Local $t_NID, $ah_Bitmap[2], $h_Icon, $h_Graphic, $h_Image, $t_Data, $t_Rect, $i_Start, $i_End, $i_Error

	If $f_ToolTip Then
		TrayTip('Info', StringFormat('%.2f%', $i_Persent) & ' ' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 0)) & ' (' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 1)) & ')', 5, 1)
	EndIf
	$i_Persent = Abs(Int($i_Persent / 6))
	If $i_Persent > 16 Then $i_Persent = 16
	If $iPersentOld = $i_Persent Then Return
	$iPersentOld = $i_Persent
	If Not $i_Persent Then
		$i_Start = 1
		$i_End = 2
	ElseIf $i_Persent = 16 Then
		$i_Start = 3
		$i_End = 4
	Else
		$i_Start = 1
		$i_End = 4
	EndIf
	$i_Color += 0xFF000000
	$i_BkColor += 0xFF000000

	Local $ah_Brush[5][7] = [[4],[0, 16 - $i_Persent, 0x00FFFFFF, $i_BkColor, $i_Persent, 0, 16 - $i_Persent], _
			[0, 16 - $i_Persent, $i_BkColor, 0x00FFFFFF, $i_Persent, 8, 16 - $i_Persent], _
			[0, $i_Persent, 0x00FFFFFF, $i_Color, 0, 0, $i_Persent], _
			[0, $i_Persent, $i_Color, 0x00FFFFFF, 0, 8, $i_Persent]]

	For $j = 1 To 1
		$t_Rect = DllStructCreate($tagGDIPRECTF)
		DllStructSetData($t_Rect, 1, 0)
		DllStructSetData($t_Rect, 2, 0)
		DllStructSetData($t_Rect, 4, 8)
		For $i = $i_Start To $i_End
			DllStructSetData($t_Rect, 3, $ah_Brush[$i][1])
			$ah_Brush[$i][0] = _GDIPlus_LineBrushCreateFromRect($t_Rect, $ah_Brush[$i][2], $ah_Brush[$i][3], 1)
			If @error Then ExitLoop 2
		Next
		$h_Image = _GDIPlus_CreateBitmapFromScan0(16, 16)
		If @error Then ExitLoop
		$h_Graphic = _GDIPlus_ImageGetGraphicsContext($h_Image)
		If @error Then ExitLoop
		For $i = $i_Start To $i_End
			_GDIPlus_GraphicsFillRect($h_Graphic, $ah_Brush[$i][4], $ah_Brush[$i][5], $ah_Brush[$i][6], 8, $ah_Brush[$i][0])
			If @error Then ExitLoop 2
		Next
		$ah_Bitmap[0] = _WinAPI_CreateBitmap(16, 16, 1, 32)
		If @error Then ExitLoop
		$t_Data = _GDIPlus_BitmapLockBits($h_Image, 0, 0, 16, 16, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
		If @error Then ExitLoop
		_WinAPI_SetBitmapBits($ah_Bitmap[0], 1024, DllStructGetData($t_Data, 'Scan0'))
		If @error Then ExitLoop
		_GDIPlus_BitmapUnlockBits($ah_Bitmap, $t_Data)
		If @error Then ExitLoop
		$ah_Bitmap[1] = _WinAPI_CreateBitmap(16, 16)
		If @error Then ExitLoop
		$h_Icon = _WinAPI_CreateIconIndirect($ah_Bitmap[0], $ah_Bitmap[1])
		If @error Then ExitLoop
		$t_NID = DllStructCreate($tagNOTIFYICONDATA)
		DllStructSetData($t_NID, 'Size', DllStructGetSize($t_NID))
		DllStructSetData($t_NID, 'hWnd', $hAutoIt)
		DllStructSetData($t_NID, 'Flags', $NIF_ICON)
		DllStructSetData($t_NID, 'ID', 1)
		DllStructSetData($t_NID, 'hIcon', $h_Icon)
		_WinAPI_ShellNotifyIcon($NIM_MODIFY, $t_NID)
	Next
	$i_Error = @error
	For $i = $i_Start To $i_End
		_GDIPlus_BrushDispose($ah_Brush[$i][0])
	Next
	_GDIPlus_GraphicsDispose($h_Graphic)
	_GDIPlus_ImageDispose($h_Image)
	For $i = 0 To 1
		_WinAPI_DeleteObject($ah_Bitmap[$i])
	Next
	If $hPrev Then
		_WinAPI_DestroyIcon($hPrev)
	EndIf
	$hPrev = $h_Icon
	If $i_Error Then Return SetError($i_Error, 0, 0)
	Return 1
EndFunc   ;==>_TraySetIconProgress

Func _GDIPlus_CreateBitmapFromScan0($i_Width, $i_Height, $i_Stride = 0, $i_PixelFormat = 0x0026200A, $p_Scan0 = 0)

	Local $a_Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromScan0', 'int', $i_Width, 'int', $i_Height, 'int', $i_Stride, 'int', $i_PixelFormat, 'ptr', $p_Scan0, 'ptr*', 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_CreateBitmapFromScan0

;From GDIP.au3
Func _GDIPlus_LineBrushCreateFromRect($t_RectF, $i_ARGBClr1, $i_ARGBClr2, $i_GradientMode = 0, $i_WrapMode = 0)
	Local $p_RectF, $a_Ret

	$p_RectF = DllStructGetPtr($t_RectF)
	$a_Ret = DllCall($ghGDIPDll, "uint", "GdipCreateLineBrushFromRect", "ptr", $p_RectF, "uint", $i_ARGBClr1, "uint", $i_ARGBClr2, "int", $i_GradientMode, "int", $i_WrapMode, "int*", 0)

	If @error Then
		Return SetError(1, 0, 0)
	Else
		If $a_Ret[0] Then
			Return SetError(1, $a_Ret[0], 0)
		EndIf
	EndIf
	Return $a_Ret[6]
EndFunc   ;==>_GDIPlus_LineBrushCreateFromRect
 
Автор
madmasles

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Добавил в первый пост третий вариант, надеюсь, последний, в виде наполняющегося стакана.
 

Ganibal95

GreenBytes
Сообщения
877
Репутация
240
madmasles
не помешало -бы сделать такое:
IMG_ZDJuppbqjA10685174.8943639.png

Т.е используется ст. иконка а поверх нее прозрачный бар...
 
Верх