Jump to content
Sign in to follow this  
smashly

Animated Gif using GDI+

Recommended Posts

ProgAndy

Why in Resources.au3 ? This should be an UDF of it's own :P


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
smashly

Why in Resources.au3 ? This should be an UDF of it's own :P

Agreed, but I think instead of a whole new udf the functions should be added to the existing GDIPlus udf since they are mostly standard gdiplus calls.

Hope someone will standardize the needed functions and submit them to be added to GDIPlus udf.

*hint*hint .. Anyone ....

Cheers

Share this post


Link to post
Share on other sites
smartee

ive been trying to do this for a long time thumbs up

Edited by smartee

Share this post


Link to post
Share on other sites
Zedna

So with a bit more work we'll hopefully soon get to see animated gif support in Zedna's Resources.au3

YaY :P

Edit: Also forgot to mention with minimal code change you can use the same routine to display multi page tif files

I thought abouut that too.

But I think this is not resource related. You can very easily change these (animated GIFs) examples to use GIF from resources

by using

$hImage = _ResourceGetAsImage($ResName, $ResType)

instead of

$hImage = _GDIPlus_ImageLoadFromFile($Gif)

The rest of code will be the same.

Share this post


Link to post
Share on other sites
smartee

ive been trying to do something like this for ages... great work

Share this post


Link to post
Share on other sites
Zedna

I think it would be good to create UDF like this:

_GuiCtrlCreateGifAnimated(filename, command, left, top [, width [, height[, style [, exStyle]]] )

default command = play

internally will be created label with provided style/exstyle and GIF applied on it by _SetBitmapToCtrl($CtrlId, $hBitmap)

and then some helper functions for change GIF image and/or Pause/Play/Rewind/Forward, something like

_GuiCtrlSetGifAnimated( controlID, filename[, command])

if filename = -1 or Default then just command is performed

command: play/pause/prev/next

And finally other functions for extracting of GIF frames like this:

_GifAnimatedGetFrameCount(filename)

_GifAnimatedGetFrame(filename, frame) returns hImage

_GifAnimatedSaveFrame(filename, framefilename)

...

Maybe instead of filename parameter could be controlID here?

Note: The concept for _GuiCtrlCreateGifAnimated() will be similar to _GuiCtrlCreateFlash()

http://www.autoitscript.com/forum/index.ph...st&p=545382

It's just quick idea.

Edited by Zedna

Share this post


Link to post
Share on other sites
TehWhale

I think it would be good to create UDF like this:

_GuiCtrlCreateGifAnimated(filename, command, left, top [, width [, height[, style [, exStyle]]] )

default command = play

internally will be created label with provided style/exstyle and GIF applied on it by _SetBitmapToCtrl($CtrlId, $hBitmap)

and then some helper functions for change GIF image and/or Pause/Play/Rewind/Forward, something like

_GuiCtrlSetGifAnimated( controlID, filename[, command])

if filename = -1 or Default then just command is performed

command: play/pause/prev/next

And finally other functions for extracting of GIF frames like this:

_GifAnimatedGetFrameCount(filename)

_GifAnimatedGetFrame(filename, frame) returns hImage

_GifAnimatedSaveFrame(filename, framefilename)

...

Note: The concept for _GuiCtrlCreateGifAnimated() will be similar to _GuiCtrlCreateFlash()

http://www.autoitscript.com/forum/index.ph...st&p=545382

It's just quick idea.

Sweet! Make this a sweet UDF and add it to the AutoIt InstallSet! I can't wait Zedna!

Share this post


Link to post
Share on other sites
Zedna

As about using animated GIF images this way from resources:

In my resources UDF (see my signature) there must be commented 1 line at end in _ResourceGetAsImage() --> _MemGlobalFree($hData)

Then all works fine (must be compiled from Scite4AutoIt3 and must be run only in compiled form):

#AutoIt3Wrapper_useupx=n
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, gif-Green-UFO.gif, rcdata, TEST_GIF_1, 0
#AutoIt3Wrapper_run_after=upx.exe --best --compress-resources=0 "%out%"

#include "resources.au3"

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.au3>
#include <Timers.au3>

HotKeySet("{Esc}", "Quit")
HotKeySet("{Left}", "Left")
HotKeySet("{Right}", "Right")
HotKeySet("{Pause}", "Pause")

;~ Global $Gif = @ScriptDir & "\gif-Green-UFO.gif"
Global $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY
Global $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend
Global $GFC, $GFDC, $pDimensionIDs, $tDL
Global $Pause

Global $MadeLoops, $LoopCount
Global $FrameDelays
Global $GIF_TimerID = -1

Global Const $tagPropertyItem = "long id; long length; int Type; ptr value"
Global Const $PropertyTagFrameDelay = 0x5100
Global Const $PropertyTagLoopCount = 0x5101

Global Const $PropertyTagTypeByte = 1
Global Const $PropertyTagTypeASCII = 2
Global Const $PropertyTagTypeShort = 3
Global Const $PropertyTagTypeLong = 4
Global Const $PropertyTagTypeRational = 5
Global Const $PropertyTagTypeUndefined = 7
Global Const $PropertyTagTypeSLong = 9
Global Const $PropertyTagTypeSRational = 10

;~ $hGUI = GUICreate("", 0, 0, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
$hGUI = GUICreate("GIF Animation",300,300)
GUICtrlCreateLabel("text behind GIF",5,15,100,25)
Global $IMG_Ctrl= GUICtrlCreateLabel("",10,10,10,10) ; For Drawing 
GUICtrlSetBkColor(-1,$GUI_BKCOLOR_TRANSPARENT) ; Transparency's working 

GUISetState()

GifInit()

; move the window with animated GIF image
;~ AdlibEnable("FlyUfo", 20)
$GIF_TimerID = _Timer_SetTimer($hGUI, 100, "_Draw_Timer") ; Start Animation
While 1
    If GUIGetMsg() = -3 Then Quit()
WEnd

Func _Draw_Timer($hWnd, $Msg, $iIDTimer, $dwTime)
    If $LoopCount = 0 Or ($LoopCount > $MadeLoops) Then
        ; If $i = the frame count then reset $i to 0
        If $GIF_TimerID = 0 Then $GIF_TimerID = -1
        If $i = $GFC Then $i = 0
        If UBound($FrameDelays) > $i And $FrameDelays[$i] > 0 Then
            _Timer_SetTimer($hWnd, $FrameDelays[$i], "_Draw_Timer", $iIDTimer)
        Else
            _Timer_SetTimer($hWnd, 100, "_Draw_Timer", $iIDTimer)
            ConsoleWrite("Fallback, no time found " & @CRLF)
        EndIf
;~   GifDrawFrame($i)
        GifDrawFrame_Ctrl($i)
        $i += 1
    Else
        _Timer_KillTimer($hWnd, $iIDTimer)
    EndIf
EndFunc   ;==>_Draw_Timer
Func Quit()
    _Timer_KillAllTimers($hGUI)
    ;Tidy Up at end of each frame, otherwise memory use gets excessive in a short time.
    _GDIPlus_ImageDispose($hImage)

    _GDIPlus_Shutdown()

    HotKeySet("{Esc}")
    HotKeySet("{Left}")
    HotKeySet("{Right}")
    HotKeySet("{Pause}")

    Exit
EndFunc   ;==>Quit

Func GifInit()
    _GDIPlus_Startup()
    ; Load your animated gif
;~     $hImage = _GDIPlus_ImageLoadFromFile($Gif)
;~     If @error Then _WinAPI_FatalAppExit("Image " & $Gif & " not found!" & _GDIPlus_Shutdown())
    $hImage = _ResourceGetAsImage("TEST_GIF_1")
    If @error Then _WinAPI_FatalAppExit("Image resource TEST_GIF_1 not found!" & _GDIPlus_Shutdown())
 
    $ApW = _GDIPlus_ImageGetWidth($hImage)
    $ApH = _GDIPlus_ImageGetHeight($hImage)

    GUICtrlSetPos($IMG_Ctrl,Default,Default,$ApW,$ApH) ;Set Size of the Control 

    ; Create a struct to hold the GUID.
    $tDL = DllStructCreate($tagGUID)

    ; Get a pointer to the GUID struct.
    $pDimensionIDs = DllStructGetPtr($tDL)

    ; Get the FrameDimensionsCount of the loaded gif
    $GFDC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "ptr", $hImage, "int*", 0)

    ; Get the FrameDimensionsList , which fills the GUID struct by passing the GUID pointer and the FrameDimensionsCount.
    DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsList", "ptr", $hImage, "ptr", $pDimensionIDs, "int", $GFDC[2])

    ; Get the FrameCount of the loaded gif by passing the GUID pointer
    $GFC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "int", $hImage, "ptr", $pDimensionIDs, "int*", 0)
    $GFC = $GFC[3]
    $FrameDelays = _GetFrameDelays($hImage, $GFC)
    $LoopCount = _GetGifLoopCount($hImage)
EndFunc   ;==>GifInit

Func GifDrawFrame_Ctrl($i)
    ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $hImage, "ptr", $pDimensionIDs, "int", $i)

    ; The rest is just a copy and paste on updating a layered window with the loaded gif.
    ; I tried using _GDIPlus_GraphicsDrawImage() but no matter what I did memory was getting chewed up. leak maybe?
    ; But using the Update layered window and memory use seems to level out and sit pretty idle
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _SetBitmapToCtrl($IMG_Ctrl,$hBitmap)
    _WinAPI_DeleteObject($hBitmap)
EndFunc   ;==>GifDrawFrame

; internal helper function, out of reources UDf from Zedna
;~ Func _SetBitmapToCtrl($CtrlId, $hBitmap)
;~     Local Const $STM_SETIMAGE = 0x0172
;~     Local Const $IMAGE_BITMAP = 0
;~     Local Const $SS_BITMAP = 0xE
;~     Local Const $GWL_STYLE = -16
;~     Local Const $SS_REALSIZEIMAGE = 0x800

;~     Local $hWnd = GUICtrlGetHandle($CtrlId)
;~     If $hWnd = 0 Then Return SetError(1, 0, 0)
;~         ; set SS_BITMAP style to control
;~     Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE)
;~     If @error Then Return SetError(2, 0, 0)
;~     DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP,$SS_REALSIZEIMAGE))
;~     If @error Then Return SetError(3, 0, 0)
;~         Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
;~     If @error Then Return SetError(4, 0, 0)
;~     If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0])
;~     Return 1
;~ EndFunc

; move the window with animated GIF image
Func FlyUfo()
    Local $Speed = 0
    Do
        If $ApX >= (@DesktopWidth - $ApW) Then
            $eX = "$ApX - 1"
        ElseIf $ApX <= 0 Then
            $eX = "$ApX + 1"
        EndIf
        If $ApY >= (@DesktopHeight - $ApH) Then
            $eY = "$ApY - 1"
        ElseIf $ApY <= 0 Then
            $eY = "$ApY + 1"
        EndIf
        $ApX = Execute($eX)
        $ApY = Execute($eY)
        WinMove($hGUI, "", $ApX, $ApY)
        $Speed += 1
    Until $Speed = 5
EndFunc   ;==>FlyUfo

Func Left()
    If WinActive($hGUI) Then
        If Not $Pause Then Return
        $i -= 1
        If $i = -1 Then $i = $GFC - 1
;~   GifDrawFrame($i)
        GifDrawFrame_Ctrl($i)
    Else
        HotKeySet("{Left}")
        Send("{Left}")
        HotKeySet("{Left}", "Left")
    EndIf
EndFunc   ;==>Left

Func Right()
    If WinActive($hGUI) Then
        If Not $Pause Then Return
        $i += 1
        If $i = $GFC Then $i = 0
;~   GifDrawFrame($i)
        GifDrawFrame_Ctrl($i)
    Else
        HotKeySet("{Right}")
        Send("{Right}")
        HotKeySet("{Right}", "Right")
    EndIf
EndFunc   ;==>Right

Func Pause()
    If WinActive($hGUI) Then
        $Pause = Not $Pause
        if $Pause Then
            _Timer_KillTimer($hGUI,$GIF_TimerID)
        Else
            $GIF_TimerID = _Timer_SetTimer($hGUI, 100, "_Draw_Timer") ; Start Animation
        EndIf

    Else
        HotKeySet("{PAUSE}")
        Send("{PAUSE}")
        HotKeySet("{PAUSE}", "Pause")
    EndIf
EndFunc   ;==>Pause

; Author: Prog@ndy (converted from VB  )
; VB-Source: http://www.activevb.de/tipps/vb6tipps/tipp0675.html
Func _GetFrameDelays(ByRef $hImage, $FrameCount)
    
    Local $lOutFrameDelay[$FrameCount]
    

;~  Dim lProp() As Byte
;~  Dim lPropCount As Long
    Local $lSize ;As Long
;~  Dim lPropSize As Long
;~  Dim tPropItem As PropertyItem
    Local $PropID = $PropertyTagFrameDelay
    If Not _CheckForProperty($hImage, $PropID) Then Return SetError(1, 0, 0)
    Local $PropertySize = DllCall($ghGDIPDll, "int", "GdipGetPropertyItemSize", "ptr", $hImage, "dword", $PropID, "uint*", 0)

;~     ' Datengröße vom EXIF-Tag
;~     ' "PropertyTagFrameDelay" ermitteln
    If $PropertySize[0] = 0 Then
        $tPropItem = DllStructCreate($tagPropertyItem & ";byte[" & $PropertySize[3] & "]"); Create Property-ItemStruct and save enough memory for its data
        Local $PropertyItem = DllCall($ghGDIPDll, "int", "GdipGetPropertyItem", "ptr", $hImage, "dword", $PropID, "dword", $PropertySize[3], "ptr", DllStructGetPtr($tPropItem))
        If $PropertyItem[0] <> 0 Then Return SetError(1, 0, 0)
        $lSize = DllStructGetData($tPropItem, "length")
;~    ' PropertyTyp ermitteln
        Switch DllStructGetData($tPropItem, "Type")
            Case $PropertyTagTypeByte
                $lProp = DllStructCreate("byte[" & $lSize & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "byte"
                ConsoleWrite("byte" & @CRLF)
            Case $PropertyTagTypeShort
                $lProp = DllStructCreate("short[" & Ceiling($lSize / 2) & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "ushort"
                ConsoleWrite("short" & @CRLF)

            Case $PropertyTagTypeLong
                $lProp = DllStructCreate("long[" & Ceiling($lSize / 4) & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "long"
                ConsoleWrite("long" & @CRLF)
        EndSwitch

;~      ' Pausenzeiten der einzelnen
;~      ' Bilder aus Bytearray kopieren
        For $lPropCount = 0 To $FrameCount - 1
            $lOutFrameDelay[$lPropCount] = DllStructGetData($lProp, 1, $lPropCount + 1) * 10


        Next
    EndIf
;~  _MemGlobalFree(DllStructGetData($tPropItem,"value"))
;~  _MemVirtualFree(DllStructGetData($tPropItem,"value"),$lSize,$MEM_RELEASE)
    Return $lOutFrameDelay
EndFunc   ;==>_GetFrameDelays

; Author: Prog@ndy (converted from VB  )
; VB-Source: http://www.activevb.de/tipps/vb6tipps/tipp0675.html
;~ '------------------------------------------------------
;~ ' Funktion     : GetGifLoopCount
;~ ' Beschreibung : Auslesen der Wiederholungen
;~ ' Übergabewert : lInBitmap = GDI+ Bitmapobjekt
;~ '                lOutLoopCount = Anzahl der Wiederholungen
;~ '------------------------------------------------------
Func _GetGifLoopCount(ByRef $hImage)

    Local $tPropItem
    Local $lProp
    Local $lSize

;~     ' ist der EXIF-Tag
;~     ' "PropertyTagLoopCount" vorhanden
    If _CheckForProperty($hImage, _
            $PropertyTagLoopCount) = True Then

;~     ' Datengröße vom EXIF-Tag
;~     ' "PropertyTagLoopCount" ermitteln
        Local $PropertySize = DllCall($ghGDIPDll, "int", "GdipGetPropertyItemSize", "ptr", $hImage, "dword", $PropertyTagLoopCount, "uint*", 0)
        If $PropertySize[0] = 0 Then

;~             ' Daten auslesen
            
            $tPropItem = DllStructCreate($tagPropertyItem & ";byte[" & $PropertySize[3] & "]"); Create Property-ItemStruct and save enough memory for its data
            Local $PropertyItem = DllCall($ghGDIPDll, "int", "GdipGetPropertyItem", "ptr", $hImage, "dword", $PropertyTagLoopCount, "dword", $PropertySize[3], "ptr", DllStructGetPtr($tPropItem))
            If $PropertyItem[0] <> 0 Then Return SetError(1, 0, 0)


            $lSize = DllStructGetData($tPropItem, "length")
;~    ' PropertyTyp ermitteln
            Switch DllStructGetData($tPropItem, "Type")
                Case $PropertyTagTypeByte
                    $lProp = DllStructCreate("byte[" & $lSize & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "byte"
                    ConsoleWrite("byte" & @CRLF)
                Case $PropertyTagTypeShort
                    $lProp = DllStructCreate("short[" & Ceiling($lSize / 2) & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "ushort"
                    ConsoleWrite("short" & @CRLF)

                Case $PropertyTagTypeLong
                    $lProp = DllStructCreate("long[" & Ceiling($lSize / 4) & "]", DllStructGetData($tPropItem, "value"))
;~      $lSize = "long"
                    ConsoleWrite("long" & @CRLF)
            EndSwitch
            Return DllStructGetData($lProp, 1, 1)

        EndIf

    Else
;~   ' wenn der EXIF-Tag
;~   ' "PropertyTagLoopCount" fehlt
        Return 0
    EndIf
EndFunc   ;==>_GetGifLoopCount


; Author: Prog@ndy (converted from VB  )
; VB-Source: http://www.activevb.de/tipps/vb6tipps/tipp0675.html
;~ '------------------------------------------------------
;~ ' Funktion     : CheckLoopCount
;~ ' Beschreibung : Überprüft, ob der EXIF-Tag LoopCount
;~ '                vorhanden sind
;~ ' Übergabewert : lInBitmap = GDI+ Bitmapobjekt
;~ ' Rückgabewert : True = LoopCount vorhanden
;~ '                False = LoopCount nicht vorhanden
;~ '------------------------------------------------------
Func _CheckForProperty( _
        ByRef $hImage, _
        $PropertyID)

    Local $lPropItem
    Local $lPropList


    Local $bRet = False

;~     ' Anzahl der EXIF-Metatags ermitteln
    Local $PropertyCount = DllCall($ghGDIPDll, "int", "GdipGetPropertyCount", "ptr", $hImage, "long*", 0)
    If $PropertyCount[0] = 0 Then


;~         ' sind EXIF-Metatags vorhanden
        If ($PropertyCount[2] > 0) Then

;~             ' Array zur Aufnahme der
;~             ' EXIF-Metatags dimensionieren
            Local $lPropList = DllStructCreate("dword[" & $PropertyCount[2] & "]")

;~             ' Liste der EXIF-Metatags auslesen -> lPropList()
            Local $PropertyList = DllCall($ghGDIPDll, "int", "GdipGetPropertyIdList", "ptr", $hImage, "long", $PropertyCount[2], "ptr", DllStructGetPtr($lPropList))
            If $PropertyList[0] = 0 Then

;~     ' Liste der EXIF-Metatags durchlaufen
                For $lPropItem = 1 To $PropertyCount[2]

;~                     ' ist in der Liste der EXIF-Metatag
;~                     ' PropertyID vorhanden

                    If DllStructGetData($lPropList, $lPropItem) = $PropertyID Then

;~                         ' wenn ja, dann Rückgabewert setzen und
;~                         ' Schleife verlassen
                        $bRet = True
                        ExitLoop
                    EndIf

                Next

            EndIf
        EndIf
    EndIf

;~     ' Rückgabewert ausgeben
    Return $bRet
EndFunc   ;==>_CheckForProperty

Share this post


Link to post
Share on other sites
ProgAndy

Your'e right :) Now it works. I have made an UDF out of it now, but I think it needs more tesing :)

[autoit]#include<GDIPlus.au3>

#include<Resources.au3>

#include<Timers.au3>

#include<WinAPI.au3>

#include<GUIConstantsEx.au3>

#include<WindowsConstants.au3>

#include<Constants.au3>

#include<Memory.au3>

#include<MemoryConstants.au3>

#include<StaticConstants.au3>

#include<StructureConstants.au3>

Global Const $GIF_CTRL_ARRAY_ENTRYS = 12

Global $GIF_CTRL_ARRAY[1][$GIF_CTRL_ARRAY_ENTRYS]

Global Const $GIF_TIMER_INIT_VALUE = 1000

Global Const $tagPropertyItem = "long id; long length; int Type; ptr value"

Global Const $PropertyTagFrameDelay = 0x5100

Global Const $PropertyTagLoopCount = 0x5101

Global Const $PropertyTagTypeByte = 1

Global Const $PropertyTagTypeASCII = 2

Global Const $PropertyTagTypeShort = 3

Global Const $PropertyTagTypeLong = 4

Global Const $PropertyTagTypeRational = 5

Global Const $PropertyTagTypeUndefined = 7

Global Const $PropertyTagTypeSLong = 9

Global Const $PropertyTagTypeSRational = 10

Global Const $GIFopt_AUTOPLAY = 1

Global Const $GIFopt_PROPOPRTIONAL = 2

Global Const $GIFopt_DONTRESIZESMALLER = 4

;#######For_Resource_Images##############################################################

#Region For_Resource_Images

#cs

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_SetImageResource()

; Description:: Sets an image out of a resource to a GIF-Control

; Parameter(s): $iCtrl -> ID of GIF-Control

; $ResName -> Name of GIF-Resource

; $ResType -> [optional] Type of the resource. (Default RcData = 10)

; $ResType -> [optional] Hanlde or filename of DLL to load resource from

; $Options -> Options for the GIF:

; 1 - Start the GIF automatically

; 2 - Size it proportional to given sizes

; 4 - Don't resize GIF, if it is smaller than the given values

; $width -> [optional] The width of the control,

; if not given, The size of the image is used

; $height -> [optional] The height of the control,

; if not given, The size of the image is used

; then, the other parameter is computed by the given one

; Requirement(s): GDIplus, Timers

; Return Value(s): ID of the Control

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_SetImageResource($iCtrl, $ResName, $ResType = 10, $ResDLL = -1, $Options = 1, $width = Default, $height = Default)

; Load your animated gif

ConsoleWrite('@@ (' & @ScriptLineNumber &') :(' & @MIN & ':' & @SEC & '):: hallo' & @CR);### DEBUGLINE

Local $hImage = _ResourceGetAsImage($ResName, $ResType, $ResDLL)

If @error Then Return SetError(2, @error, 0)

_GuiCtrlGifAnimated_SetGDIpImage($iCtrl, $hImage, $Options, $width, $height)

If @error Then

_GDIPlus_ImageDispose($hImage)

Return SetError(1, 0, 0)

EndIf

Return 1

EndFunc ;==>_GuiCtrlGifAnimated_SetImageResource

#ce

#EndRegion For_Resource_Images

;########################################################################################

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Create()

; Description:: Creates an animated GIF in you GUI

; Parameter(s): $filename -> Name of GIF, can be "" -> empty Control created

; $left -> The left side of the control. If -1 is used then

; left will be computed according to GUICoordMode.

; $top -> The top of the control. If -1 is used then top

; will be computed according to GUICoordMode.

; $width -> [optional] The width of the control,

; if not given, The size of the image is used

; $height -> [optional] The height of the control,

; if not given, The size of the image is used

; then, the other parameter is computed by the given one

; $Options -> Options for the GIF:

; 1 - Start the GIF automatically

; 2 - Size it proportional to given sizes

; 4 - Don't resize GIF, if it is smaller than the given values

; $style -> [optional] Defines the style of the control.

; $exStyle -> [optional] Defines the extended style of the control.

; Requirement(s): GDIplus, Timers

; Return Value(s): ID of the Control

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

; Remarks: MUST BE DELETED WITH _GuiCtrlGifAnimated_Delete

; or _GuiCtrlGifAnimated_DeleteAll

;===============================================================================

;

Func _GuiCtrlGifAnimated_Create($filename, $left, $top, $width = Default, $height = Default, $Options = 1, $style = -1, $exStyle = -1)

Local $iIndex = $GIF_CTRL_ARRAY[0][0] + 1

ReDim $GIF_CTRL_ARRAY[$iIndex + 1][$GIF_CTRL_ARRAY_ENTRYS]

$GIF_CTRL_ARRAY[0][0] = $iIndex

Local $iCtrl = GUICtrlCreateLabel("", $left, $top, $width, $height, $style, $exStyle) ; For Drawing :)

GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; Transparency's working :)

$GIF_CTRL_ARRAY[$iIndex][0] = $iCtrl ; Control for Display

If $filename <> "" Then

_GuiCtrlGifAnimated_SetImage($iCtrl, $filename, $Options, $width, $height)

If @error Then

Local $error = @error

GUICtrlDelete($iCtrl)

ReDim $GIF_CTRL_ARRAY[$iIndex][$GIF_CTRL_ARRAY_ENTRYS]

$GIF_CTRL_ARRAY[0][0] -= 1

Return SetError($error, 0, 0)

EndIf

EndIf

Return $iCtrl

EndFunc ;==>_GuiCtrlGifAnimated_Create

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_GetProperty()

; Description:: Gets properties of a GIF-Control

; Parameter(s): $iCtrl -> ID of GIF-Control

; $Property -> The Property to read. Possible Values:

; playing - paused or animating

; totalframes - Amount of frames

; frame - current frame

; totalloops - how often should it be repeated? 0=infinite

; loops - The amount of completed loops

; framedelays - The delays for all frames

; framedelay;0 - an extended property:

; framedelay -> the property name

; ; -> separator

; 0 -> the number of the frame to get the delay for

; Requirement(s): This UDf

; Return Value(s): ID of the Control

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_GetProperty($iCtrl, $Property = "playing")

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

Switch StringLower($Property)

Case "playing"

Return $GIF_CTRL_ARRAY[$iIndex][9] > 0

Case "totalframes"

Return $GIF_CTRL_ARRAY[$iIndex][3]

Case "frame"

Return $GIF_CTRL_ARRAY[$iIndex][2]

Case "totalloops"

Return $GIF_CTRL_ARRAY[$iIndex][5]

Case "loops"

Return $GIF_CTRL_ARRAY[$iIndex][6]

Case "framedelays"

Return $GIF_CTRL_ARRAY[$iIndex][4]

Case Else

If StringLeft($Property, 11) = "framedelay;" Then

Local $Frame = Number(StringTrimLeft($Property, 11)), $FrameDelays = $GIF_CTRL_ARRAY[$iIndex][4]

If UBound($FrameDelays) < $Frame And $Frame > 0 Then Return $FrameDelays[$Frame]

Return SetError(3, 0, -1)

EndIf

EndSwitch

Return SetError(2, 0, "")

EndFunc ;==>_GuiCtrlGifAnimated_GetProperty

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_SetImage()

; Description:: Sets the image of a GIF-Control

; Parameter(s): $iCtrl -> ID of GIF-Control

; $filename -> Name of GIF

; $Options -> Options for the GIF:

; 1 - Start the GIF automatically

; 2 - Size it proportional to given sizes

; 4 - Don't resize GIF, if it is smaller than the given values

; $width -> [optional] The width of the control,

; if not given, The size of the image is used

; $height -> [optional] The height of the control,

; if not given, The size of the image is used

; then, the other parameter is computed by the given one

; Requirement(s): GDIplus, Timers

; Return Value(s): ID of the Control

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_SetImage($iCtrl, $filename, $Options = 1, $width = Default, $height = Default)

; Load your animated gif

Local $hImage = _GDIPlus_ImageLoadFromFile($filename)

If @error Then Return SetError(2, 0, 0)

_GuiCtrlGifAnimated_SetGDIpImage($iCtrl, $hImage, $Options, $width, $height)

If @error Then

_GDIPlus_ImageDispose($hImage)

Return SetError(1, 0, 0)

EndIf

Return 1

EndFunc ;==>_GuiCtrlGifAnimated_SetImage

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Delete()

; Description:: deletes a GIF-Control

; Parameter(s): $iCtrl -> ID of GIF-Control

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Delete($iCtrl)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

If $GIF_CTRL_ARRAY[$iIndex][9] Then _Timer_KillTimer(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), $GIF_CTRL_ARRAY[$iIndex][7])

_GDIPlus_ImageDispose($GIF_CTRL_ARRAY[$iIndex][1])

GUICtrlDelete($iCtrl)

For $i = $iIndex To UBound($GIF_CTRL_ARRAY) - 2

For $j = 0 To $GIF_CTRL_ARRAY_ENTRYS - 1

$GIF_CTRL_ARRAY[$i][$j] = $GIF_CTRL_ARRAY[$i + 1][$j]

Next

Next

ReDim $GIF_CTRL_ARRAY[$GIF_CTRL_ARRAY[0][0]][$GIF_CTRL_ARRAY_ENTRYS]

$GIF_CTRL_ARRAY[0][0] -= 1

EndFunc ;==>_GuiCtrlGifAnimated_Delete

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Stop()

; Description:: Stops animation of a GIF-Control (sets loopcounter to 0)

; Parameter(s): $iCtrl -> ID of GIF-Control

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; if already stopped: True with @error = -1

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Stop($iCtrl)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

Local $iOK = _GuiCtrlGifAnimated_Pause($iCtrl)

Local $error = @error

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], 0)

$GIF_CTRL_ARRAY[$iIndex][2] = 0

$GIF_CTRL_ARRAY[$iIndex][6] = 0

Return SetError($error, 0, $iOK)

EndFunc ;==>_GuiCtrlGifAnimated_Stop

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Next()

; Description:: Steps to the next frame

; Parameter(s): $iCtrl -> ID of GIF-Control

; $JumpToStart -> [optional] If the Animation is at the end,

; go to start again ( default: false )

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; if jumped to start: True with @error = -1

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Next($iCtrl, $JumpToStart = False)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

If $GIF_CTRL_ARRAY[$iIndex][2] + 1 < $GIF_CTRL_ARRAY[$iIndex][3] Then

$GIF_CTRL_ARRAY[$iIndex][2] += 1

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], $GIF_CTRL_ARRAY[$iIndex][2])

Return 1

ElseIf $JumpToStart Then

$GIF_CTRL_ARRAY[$iIndex][2] = 0

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], $GIF_CTRL_ARRAY[$iIndex][2])

Return SetError(-1, 0, 1)

EndIf

Return SetError(2, 0, 0)

EndFunc ;==>_GuiCtrlGifAnimated_Next

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Prev()

; Description:: Steps to the previous frame

; Parameter(s): $iCtrl -> ID of GIF-Control

; $JumpToStart -> [optional] If the Animation is at the beginning,

; go to end ( default: false )

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; if jumped to end: True with @error = -1

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Prev($iCtrl, $JumpToEnd = False)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

If $GIF_CTRL_ARRAY[$iIndex][2] - 1 >= 0 Then

$GIF_CTRL_ARRAY[$iIndex][2] -= 1

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], $GIF_CTRL_ARRAY[$iIndex][2])

Return 1

ElseIf $JumpToEnd Then

$GIF_CTRL_ARRAY[$iIndex][2] = $GIF_CTRL_ARRAY[$iIndex][3] - 1

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], $GIF_CTRL_ARRAY[$iIndex][2])

Return SetError(-1, 0, 1)

EndIf

Return SetError(2, 0, 0)

EndFunc ;==>_GuiCtrlGifAnimated_Prev

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_pause()

; Description:: Pauses the animation ( saves frame + loopcount)

; Parameter(s): $iCtrl -> ID of GIF-Control

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Pause($iCtrl)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

If $GIF_CTRL_ARRAY[$iIndex][9] = 0 Then Return SetError(-1, 0, 1)

Local $iOK = _Timer_KillTimer(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), $GIF_CTRL_ARRAY[$iIndex][7])

If $iOK Then $GIF_CTRL_ARRAY[$iIndex][9] = 0

Return SetError($iOK = 0, 0, $iOK)

EndFunc ;==>_GuiCtrlGifAnimated_Pause

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Resume()

; Description:: Same as _GuiCtrlGifAnimated_Play

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Resume($iCtrl)

Local $iOK = _GuiCtrlGifAnimated_Play($iCtrl)

Return SetError(@error, 0, $iOK)

EndFunc ;==>_GuiCtrlGifAnimated_Resume

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_Play()

; Description:: Continues animation after Pause or Stop

; Parameter(s): $iCtrl -> ID of GIF-Control

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; @error = 1 if Control does not exist

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_Play($iCtrl)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

If $GIF_CTRL_ARRAY[$iIndex][9] > 0 Then Return SetError(-1, 0, 1)

$GIF_CTRL_ARRAY[$iIndex][9] = _Timer_SetTimerEx(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), 100, "_GIFAni_Draw_TimerFunc", $GIF_CTRL_ARRAY[$iIndex][7]); Start Animation

Return $GIF_CTRL_ARRAY[$iIndex][9] > 0

EndFunc ;==>_GuiCtrlGifAnimated_Play

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_DeleteAll()

; Description:: Deletes all GIF-Controls, use e.g. when termainating Script.

; Parameter(s): none

; Requirement(s): GDIPlus, Timers

; Return Value(s): Success: true, otherwise false

; Author(s): Prog@ndy

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_DeleteAll()

Local $iIndex

For $iIndex = 1 To $GIF_CTRL_ARRAY[0][0]

If $GIF_CTRL_ARRAY[$iIndex][9] Then _Timer_KillTimer(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), $GIF_CTRL_ARRAY[$iIndex][7])

_GDIPlus_ImageDispose($GIF_CTRL_ARRAY[$iIndex][1])

GUICtrlDelete($GIF_CTRL_ARRAY[$iIndex][0])

Next

Global $GIF_CTRL_ARRAY[1][$GIF_CTRL_ARRAY_ENTRYS] = [[0]]

EndFunc ;==>_GuiCtrlGifAnimated_DeleteAll

;===============================================================================

;

; Function Name: _GuiCtrlGifAnimated_SetGDIpImage()

; Description:: Sets the image of a GIF-Control

; Parameter(s): $iCtrl -> ID of GIF-Control

; $$hImage -> handle of GDIplus_Image

; $Options -> Options for the GIF:

; 1 - Start the GIF automatically

; 2 - Size it proportional to given sizes

; 4 - Don't resize GIF, if it is smaller than the given values

; $width -> [optional] The width of the control,

; if not given, The size of the image is used

; $height -> [optional] The height of the control,

; if not given, The size of the image is used

; then, the other parameter is computed by the given one

; Requirement(s): GDIplus, Timers

; Return Value(s): ID of the Control

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

; INTERNAL USE ONLY

;

;===============================================================================

;

Func _GuiCtrlGifAnimated_SetGDIpImage($iCtrl, ByRef $hImage, $Options = 1, $width = Default, $height = Default)

Local $iIndex = __GuiCtrlGifAnimated_GetIndexbyGUICtrl($iCtrl)

If @error Then Return SetError(1, 0, 0)

Local $ApW = _GDIPlus_ImageGetWidth($hImage) * 1

Local $ApH = _GDIPlus_ImageGetHeight($hImage) * 1

If BitAND($Options, $GIFopt_DONTRESIZESMALLER) = $GIFopt_DONTRESIZESMALLER And _

$width > $ApW And $height > $ApH Then

$width = Default

$height = Default

EndIf

If $width = Default Or $width < 1 Then $width = $ApW

If $height = Default Or $height < 1 Then $height = $ApH

;Size Proportional

If BitAND($Options, $GIFopt_PROPOPRTIONAL) = $GIFopt_PROPOPRTIONAL Then

Local $PROPwidth = Int($ApW * $height / $ApH)

Local $PROPheight = Int($ApH * $width / $ApW)

Switch ($PROPwidth > $width)

Case True

$height = $PROPheight

Case False

$width = $PROPwidth

EndSwitch

EndIf

; Get the FrameDimensionsCount of the loaded gif

Local $GFDC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "ptr", $hImage, "int*", 0)

If $GFDC[2] = 0 Then Return SetError(2, 0, 0)

; Create a struct to hold the GUID.

Local $tagGUIDArr

For $i = 1 To $GFDC[2]

$tagGUIDArr &= $tagGUID & ";"

Next

Local $tDL = DllStructCreate($tagGUIDArr)

; Get a pointer to the GUID struct.

Local $pDimensionIDs = DllStructGetPtr($tDL)

; Get the FrameDimensionsList , which fills the GUID struct by passing the GUID pointer and the FrameDimensionsCount.

DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsList", "ptr", $hImage, "ptr", $pDimensionIDs, "int", $GFDC[2])

; Get the FrameCount of the loaded gif by passing the GUID pointer

Local $GFC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "int", $hImage, "ptr", $pDimensionIDs, "int*", 0)

$GFC = $GFC[3]

If $GFC = 0 Then Return SetError(3, 0, 0)

Local $FrameDelays = _GDIplus_GetFrameDelays($hImage, $GFC)

Local $LoopCount = _GDIplus_GetGifLoopCount($hImage)

GUICtrlSetPos($iCtrl, Default, Default, $width, $height) ;Set Size of the Control :D

If $GIF_CTRL_ARRAY[$iIndex][9] Then _Timer_KillTimer(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), $GIF_CTRL_ARRAY[$iIndex][7])

If $GIF_CTRL_ARRAY[$iIndex][1] > 0 Then _GDIPlus_ImageDispose($GIF_CTRL_ARRAY[$iIndex][1])

Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)

_GIFAni_SetBitmapToCtrl($iCtrl, $hBitmap, 1, 1)

_WinAPI_DeleteObject($hBitmap)

$GIF_CTRL_ARRAY[$iIndex][0] = $iCtrl ; Control for Display

$GIF_CTRL_ARRAY[$iIndex][1] = $hImage ; GIF-Image

$GIF_CTRL_ARRAY[$iIndex][2] = 0 ; Frame to Display

$GIF_CTRL_ARRAY[$iIndex][3] = $GFC ; Frame Count

$GIF_CTRL_ARRAY[$iIndex][4] = $FrameDelays

$GIF_CTRL_ARRAY[$iIndex][5] = $LoopCount

$GIF_CTRL_ARRAY[$iIndex][6] = 0 ; -> Completed Loops

$GIF_CTRL_ARRAY[$iIndex][7] = $GIF_TIMER_INIT_VALUE + $iCtrl ; -> TimerID: StartValue + CtrlID :)

$GIF_CTRL_ARRAY[$iIndex][8] = GUICtrlGetHandle($iCtrl) ; -> Control Handle

$GIF_CTRL_ARRAY[$iIndex][10] = $tDL

$GIF_CTRL_ARRAY[$iIndex][11] = $pDimensionIDs

If BitAND($Options, 1) = 1 Then $GIF_CTRL_ARRAY[$iIndex][9] = _Timer_SetTimerEx(_WinAPI_GetParent($GIF_CTRL_ARRAY[$iIndex][8]), 100, "_GIFAni_Draw_TimerFunc", $GIF_CTRL_ARRAY[$iIndex][7]); Start Animation

Return 1

EndFunc ;==>_GuiCtrlGifAnimated_SetGDIpImage

;===============================================================================

;

; Function Name: _GIFAni_Draw_TimerFunc

; Author(s): Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)

;

; INTERNAL USE ONLY

;

;===============================================================================

;

Func _GIFAni_Draw_TimerFunc($hWnd, $Msg, $iIDTimer, $dwTime)

Local $iIndex, $LoopCount, $MadeLoops, $FrameCount, $Frame, $FrameDelays

Local $iCtrl

For $i = 1 To $GIF_CTRL_ARRAY[0][0]

If $GIF_CTRL_ARRAY[$i][9] = $iIDTimer Then

$iCtrl = $GIF_CTRL_ARRAY[$i][0]

$iIndex = $i

ExitLoop

EndIf

Next

If $iIndex = 0 Then Return

$LoopCount = $GIF_CTRL_ARRAY[$iIndex][5]

$MadeLoops = $GIF_CTRL_ARRAY[$iIndex][6]

$FrameCount = $GIF_CTRL_ARRAY[$iIndex][3]

$FrameDelays = $GIF_CTRL_ARRAY[$iIndex][4]

If $LoopCount = 0 Or ($LoopCount > $MadeLoops) Then

$Frame = $GIF_CTRL_ARRAY[$iIndex][2] + 1

; If $i = the frame count then reset $i to 0

If $Frame = $FrameCount Then $Frame = 0

$GIF_CTRL_ARRAY[$iIndex][2] = $Frame

If UBound($FrameDelays) > $Frame And $FrameDelays[$Frame] > 0 Then

_Timer_SetTimerEx($hWnd, $FrameDelays[$i], "_GIFAni_Draw_TimerFunc", $iIDTimer)

Else

_Timer_SetTimerEx($hWnd, 100, "_GIFAni_Draw_TimerFunc", $iIDTimer)

ConsoleWrite('@@ (' & @ScriptLineNumber & ') :(' & @MIN & ':' & @SEC & '):: Fallback, no time found :)' & @CR);### DEBUGLINE

EndIf

;~ GifDrawFrame($i)

_GIFAni_SetFrameToCtrl($GIF_CTRL_ARRAY[$iIndex][8], $GIF_CTRL_ARRAY[$iIndex][1], $GIF_CTRL_ARRAY[$iIndex][11], $Frame)

If $Frame = ($FrameCount - 1) Then $GIF_CTRL_ARRAY[$iIndex][6] += 1

Else

_Timer_KillTimer($hWnd, $iIDTimer)

EndIf

EndFunc ;==>_GIFAni_Draw_TimerFunc

;===============================================================================

;

; Function Name: _GDIplus_GetFrameDelays

; Author(s): Prog@ndy (converted from VB :) )

; VB-Source: http://www.activevb.de/tipps/vb6tipps/tipp0675.html

; INTERNAL USE ONLY

;

;===============================================================================

;

Func _GDIplus_GetFrameDelays(ByRef $hImage, $FrameCount)

If $FrameCount = 0 Then Return SetError(1, 0, 0)

Local $lOutFrameDelay[$FrameCount]

;~ Dim lProp() As Byte

;~ Dim lPropCount As Long

Local $lSize ;As Long

;~ Dim lPropSize As Long

;~ Dim tPropItem As PropertyItem

Local $PropID = $PropertyTagFrameDelay

If Not _GDIplus_CheckForProperty($hImage, $PropID) Then Return SetError(1, 0, 0)

Local $PropertySize = DllCall($ghGDIPDll, "int", "GdipGetPropertyItemSize", "ptr", $hImage, "dword", $PropID, "uint*", 0)

;~ ' Datengr


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
smashly

That's looking good ProgAndy, nice work :P

I've started trying to get the basic GDI+ image functions for animated images (Gif & Tif) added to the GDIPlus.au3 udf.

If they are accepted or not well that's another story... lol

So far I've submitted:

_GDIPlus_ImageSaveAddImage

_GDIPlus_ImageSaveAdd

_GDIPlus_ImageGetFrameDimensionCount

_GDIPlus_ImageGetFrameDimensionList

_GDIPlus_ImageGetFrameCount

_GDIPlus_ImageSelectActiveFrame

I've still got to submit the ones you've done as of yet.

As for the upload limit per file , I haven't had that issue as of yet.

The limit I'm aware of is the 1MB total limit of attached files.

Cheers

Share this post


Link to post
Share on other sites
ProgAndy

Ahh, i see. There was some very big GIF in my Files ...

And functions, you could submit, are:

GdipGetPropertyItemSize

GdipGetPropertyItem

GdipGetPropertyCount

GdipGetPropertyIdList

and the structures and constants like

CODE
Global Const $tagPropertyItem = "long id; long length; int Type; ptr value"

Global Const $PropertyTagFrameDelay = 0x5100

Global Const $PropertyTagLoopCount = 0x5101

Global Const $PropertyTagTypeByte = 1

Global Const $PropertyTagTypeASCII = 2

Global Const $PropertyTagTypeShort = 3

Global Const $PropertyTagTypeLong = 4

Global Const $PropertyTagTypeRational = 5

Global Const $PropertyTagTypeUndefined = 7

Global Const $PropertyTagTypeSLong = 9

Global Const $PropertyTagTypeSRational = 10


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
matrixnz

Hi there

I'm trying to impliment animated gif within my gui using Zedna's resource.au3 udf while also using ProgAndys GUIGIFAnimated.au3, I noted that the resource section was commented out (see below), was this because the function doesn't work or am I missing something? I tried using the function but wasn't able to get it to work, I have seen Zednas animated gif example which is great but liked the thought of using a udf for future projects. Does anyone know if this function works and if so could they provide an example of how to use it? Any help would be greatly appreciated.

Cheers

;#######For_Resource_Images##############################################################
#Region For_Resource_Images
#cs
    
   ;===============================================================================
   ;
   ; Function Name:   _GuiCtrlGifAnimated_SetImageResource()
   ; Description::  Sets an image out of a resource to a GIF-Control
   ; Parameter(s):  $iCtrl   -> ID of GIF-Control
   ;                  $ResName   -> Name of GIF-Resource
   ;                  $ResType   -> [optional] Type of the resource. (Default RcData = 10)
   ;                  $ResType   -> [optional] Hanlde or filename of DLL to load resource from
   ;                  $Options   -> Options for the GIF:
   ;                                 1 - Start the GIF automatically
   ;                                 2 - Size it proportional to given sizes
   ;                                 4 - Don't resize GIF, if it is smaller than the given values
   ;                  $width     -> [optional] The width of the control,
   ;                                if not given, The size of the image is used
   ;                  $height   -> [optional] The height of the control,
   ;                                if not given, The size of the image is used
   ;                          then, the other parameter is computed by the given one
   ; Requirement(s):  GDIplus, Timers
   ; Return Value(s): ID of the Control
   ; Author(s):    Prog@ndy, with Code from Zedna and smashly (both autoitscript.com)
   ;
   ;===============================================================================
   ;
    Func _GuiCtrlGifAnimated_SetImageResource($iCtrl, $ResName, $ResType = 10, $ResDLL = -1, $Options = 1, $width = Default, $height = Default)
   ; Load your animated gif
    ConsoleWrite('@@ (' & @ScriptLineNumber &') ' & @MIN & ':' & @SEC & '):: hallo' & @CR);### DEBUGLINE
    Local $hImage = _ResourceGetAsImage($ResName, $ResType, $ResDLL)
    If @error Then Return SetError(2, @error, 0)
    _GuiCtrlGifAnimated_SetGDIpImage($iCtrl, $hImage, $Options, $width, $height)
    If @error Then
    _GDIPlus_ImageDispose($hImage)
    Return SetError(1, 0, 0)
    EndIf
    Return 1
    EndFunc  ;==>_GuiCtrlGifAnimated_SetImageResource
#ce
#EndRegion For_Resource_Images
;########################################################################################

Share this post


Link to post
Share on other sites
joseLB

Hi Andy,

do you know a way to CREATE an animated gif in AU3, given a list of .gif simple images? I'm doing a kind of prgram do capture screens (_ScreenCapture_CaptureWnd with mouse) at each 1 second, generating gifs. When it finishes I would like to create just one animated gif that shows the screen actions as in a movie.

THanks

Jose

Share this post


Link to post
Share on other sites
ProgAndy

@joseLB: sorry don't know how to do that.

@matrixnz this should work, but i commented it out since you have to include Resources.au3 when you use it or toherwise there will be errors.

Where did you load the GIF from? If it's an external DLL, it should not be unloaded while using this function.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
electros

Does anyone know how can I create a function show/hide gif for the UDF

Share this post


Link to post
Share on other sites
KaFu

@ProgAndy

Really nice UDF you created :), currently I'm trying to use it in SMF.

Now I stumbled over a problem with _GuiCtrlGifAnimated_SetImage() I can not figure out yet.

If I create a gif and afterwards assign another gif to the control, suddently the position of the control changes, but only on the first change.

Changed your code example a little to demonstrate, Prev and Next now change between 2 gifs.

#include "GUIGIFAnimated.au3"

Global $Gif = @ScriptDir & "\gif1.gif"
Global $Gif2 = @ScriptDir & "\gif2.gif"

_GDIPlus_Startup()
;~ $hGUI = GUICreate("", 0, 0, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
$hGUI = GUICreate("GIF Animation", 300, 300)
$GIF_ICO = GUICtrlCreateLabel("text behind GIF", 5, 15, 100, 25)
GUISetState()
$ANI_GIF = _GuiCtrlGifAnimated_Create($Gif, 50, 20, 90, 90, BitOR($GIFopt_AUTOPLAY, $GIFopt_PROPOPRTIONAL, $GIFopt_DONTRESIZESMALLER))

;~ _GuiCtrlGifAnimated_SetImageResource($ANI_GIF,"GIF1",10,"GIFAnimated.dll")

GUISetFont(12, Default, Default, "Arial")
$btnPrev = GUICtrlCreateButton("<<", 10, 100, 30)

$btnStart = GUICtrlCreateButton(ChrW(0x25BA), 45, 100, 30)
$btnPause = GUICtrlCreateButton(ChrW(0x258C) & ChrW(0x2590), 80, 100, 30)
$btnStop = GUICtrlCreateButton(ChrW(0x2588), 110, 100, 30)

$btnNext = GUICtrlCreateButton(">>", 145, 100, 30)
$lblFrameInfo = GUICtrlCreateLabel("Frame: ", 20, 135, 100, 20)
$tmpLastFrame = -1
While 1
    $nMSG = GUIGetMsg()
    Switch $nMSG
        Case - 3
            Exit
        Case $btnStop
            _GuiCtrlGifAnimated_Stop($ANI_GIF)
        Case $btnPause
            _GuiCtrlGifAnimated_Pause($ANI_GIF)
        Case $btnStart
            _GuiCtrlGifAnimated_Play($ANI_GIF)
        Case $btnNext
            _GuiCtrlGifAnimated_SetImage($ANI_GIF,$Gif2)
         ;_GuiCtrlGifAnimated_Next($ANI_GIF, 1)
        Case $btnPrev
            _GuiCtrlGifAnimated_SetImage($ANI_GIF,$Gif)
         ;_GuiCtrlGifAnimated_Prev($ANI_GIF, 1)
    EndSwitch
    $tmpFrame = _GuiCtrlGifAnimated_GetProperty($ANI_GIF, "frame")
    If $tmpFrame <> $tmpLastFrame Then
        GUICtrlSetData($lblFrameInfo, "Frame: " & $tmpFrame)
        $tmpLastFrame = $tmpFrame
    EndIf
WEnd

Func OnAutoItExit()
    _GuiCtrlGifAnimated_DeleteAll()
    _Timer_KillAllTimers($hGUI)
    _GDIPlus_Shutdown()
    ConsoleWrite('@@ (' & @ScriptLineNumber &') ' & @MIN & ':' & @SEC & '):: Free Resources' & @CR);### DEBUGLINE
    Exit
EndFunc;==>OnAutoItExit
Edited by KaFu

Share this post


Link to post
Share on other sites
KaFu

Found it. For _GuiCtrlGifAnimated_SetImage() to work correct, this

GUICtrlSetPos($iCtrl, Default, Default, $width, $height);Set Size of the Control

needs to be replaced with this

$hCtrl = ControlGetHandle('','',$iCtrl)
if IsHWnd($hCtrl) then
    $GIF_CTRL_POS = ControlGetPos('','',$iCtrl)
GUICtrlSetPos($iCtrl, $GIF_CTRL_POS[0], $GIF_CTRL_POS[1], $width, $height);Set Size of the Control
Else
    GUICtrlSetPos($iCtrl, Default, Default, $width, $height);Set Size of the Control
endif

Share this post


Link to post
Share on other sites
KaFu

The above part has of course to be replaced in the func _GuiCtrlGifAnimated_SetGDIpImage().

Additionally I think there might be an error in _GuiCtrlGifAnimated_SetImage(). While assigning a new image with _GuiCtrlGifAnimated_SetGDIpImage() the old image and it's timer are not destroyed! I guess that's the reason why my program kept crashing on exit. Tried to debug / rewrite it, but was to impatient and switch to non GDI+ display of animated Gif's again :).

Cheers

Edited by KaFu

Share this post


Link to post
Share on other sites
Homes32

nice udf! ;) thanks for spending the time to put it all together.

I have run across an issue with displaying a .gif with quick animation.

using the example provided (with the udf) the image lags considerably while the bat is hitting the copier.

using this other method the gif is played properly.

Global $Gif = @ScriptDir & "\smash-copier.gif"
Global $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY

Func Show_Gif()
Local $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY

    _GDIPlus_Startup()

    ; Load your animated gif
    $hImage = _GDIPlus_ImageLoadFromFile($Gif)
    $ApW = _GDIPlus_ImageGetWidth($hImage)
    $ApH = _GDIPlus_ImageGetHeight($hImage)

    ;Local $aPos = WinGetPos($FRM_Parent)
    Local $aPos = WinGetPos("Program Manager") ; "Program Manager" uses desktop as the parent


    ; Create GUI to hold gif
    $hGUI = GUICreate("", $ApW, $ApH, $aPos[0] + (($aPos[2] - $ApW) / 2), $aPos[1] + (($aPos[3] - $ApH) / 2), $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetState()

    ; get time stamp
    $iBegin = TimerInit()

    Do
        ; Create a struct to hold the GUID.
        $tDL = DllStructCreate($tagGUID)

        ; Get a pointer to the GUID struct.
        $pDimensionIDs = DllStructGetPtr($tDL)

        ; Get the FrameDimensionsCount of the loaded gif
        $GFDC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "ptr", $hImage, "int*", 0)

        ; Get the FrameDimensionsList , which fills the GUID struct by passing the GUID pointer and the FrameDimensionsCount.
        DllCall($ghGDIPDll, "int", "GdipImageGetFrameDimensionsList", "ptr", $hImage, "ptr", $pDimensionIDs, "int", $GFDC[2])

        ; Get the FrameCount of the loaded gif by passing the GUID pointer
        $GFC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "int", $hImage, "ptr", $pDimensionIDs, "int*", 0)

        ; If $i = the frame count then reset $i to 0
        If $i = $GFC[3] Then $i = 0
;~     ConsoleWrite($GFC[3] & @LF)
        ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
        DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $hImage, "ptr", $pDimensionIDs, "int", $i)

        ; At this point you can get the CLSID of an encoder and save the frame to file if you want..
        ; Use any Encoder you like. eg: "GIF", "TIF", "BMP", "JPG"
        ; Transparency won't be saved. (You'd need to play with pallets to have the transparency saved)
;~  $sCLSID = _GDIPlus_EncodersGetCLSID ("PNG")
;~  _GDIPlus_ImageSaveToFileEx ($hImage, @MyDocumentsDir & "\Gif_Frame_" & $i & ".png", $sCLSID)

        ; The rest is just a copy and paste on updating a layered window with the loaded gif.
        ; I tried using _GDIPlus_GraphicsDrawImage() but no matter what I did memory was getting chewed up. leak maybe?
        ; But using the Update layered window and memory use seems to level out and sit pretty idle ;)

        $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
        $hScrDC = _WinAPI_GetDC($hGUI)
        $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
        $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)

        $tSize = DllStructCreate($tagSIZE)
        DllStructSetData($tSize, "X", $ApW)
        DllStructSetData($tSize, "Y", $ApH)
        $pSize = DllStructGetPtr($tSize)

        $tSource = DllStructCreate($tagPOINT)
        $pSource = DllStructGetPtr($tSource)

        $tBlend = DllStructCreate($tagBLENDFUNCTION)
        DllStructSetData($tBlend, "Alpha", 255)
        DllStructSetData($tBlend, "Format", 1)
        $pBlend = DllStructGetPtr($tBlend)

        _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)

        ;Tidy Up at end of each frame, otherwise memory use gets excessive in a short time.
;~  _GDIPlus_ImageDispose($hImage)
        _WinAPI_ReleaseDC(0, $hScrDC)
        _WinAPI_DeleteObject($hBitmap)
        _WinAPI_DeleteDC($hMemDC)

        ; By rights I should be using the const PropertyTagFrameDelay and geting the properties time delay between frames.
        ; I cheated , so shoot me...lol
        Sleep(100)

        $i += 1

    Until TimerDiff($iBegin) > 9500 ; Run for ?? ms secs

    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()

    ; Delete gif GUI
    GUIDelete($hGUI)
EndFunc   ;==>Show_Gif

any ideas on what should be corrected to make this work better with this UDF?

gif file is attached to this post

post-54678-12817161285094_thumb.gif

Share this post


Link to post
Share on other sites
Homes32

if anybody is looking at this who knows what they are doing the issues seems to be in the way the delay between frames is used. the script sample that I posted above uses a hard coded Sleep(100) where as this UDF uses the const PropertyTagFrameDelay from GDI+

thats about all I can figure out with my limited/non-existent knowledge of GDI+. I could be completely wrong and the issues is with the timers...

Edited by Homes32

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
Sign in to follow this  

×