Jump to content

Func-Afying Gif Animation


BillLuvsU
 Share

Recommended Posts

Ok, so I am starting with some code I got off the Examples forumn using GDI+ funcs to display an animated GIF on a transparent GUI. my goal was to convert this into a function that would fit my needs. I failed. I've been trying to wrap my mind around this for the last five hours and can't figure it out. I've gone through it line by line and can't see any significant difference in the two scripts (except for organization of code) and I'm at my last end. The picture isn't evan showing up in the first place, but the GUI IS there. If someone could have a look at this and tell me where I'm being an idiot it would be highly appreciated.

ORIGINAL SCRIPT

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.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

$hGUI = GUICreate("", 0, 0, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
GUISetState()

GifInit()

; move the window with animated GIF image
;~ AdlibEnable("FlyUfo", 20) 

While 1
    ; If $i = the frame count then reset $i to 0
    If $i = $GFC Then $i = 0

 GifDrawFrame($i)
 
    ; 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
WEnd

Func Quit()
 ;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)
 _GDIPlus_Shutdown()

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

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

 $hScrDC = _WinAPI_GetDC($hGUI)
 $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)

 $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)

 ; 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]
EndFunc    

Func GifDrawFrame($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)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)

    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
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)
 Else
    HotKeySet("{Left}")
    Send("{Left}")
    HotKeySet("{Left}", "Left")
 EndIf
EndFunc

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

Func Pause()
 If WinActive($hGUI) Then
    $Pause = Not $Pause
    If Not $Pause Then Return
     
;~   WinSetTitle($hGUI, '', $Gif & " PAUSED")
    While $Pause
       Sleep(100)
    WEnd
;~   WinSetTitle($hGUI, '', $Gif)
 Else
    HotKeySet("{PAUSE}")
    Send("{PAUSE}")
    HotKeySet("{PAUSE}", "Pause")
 EndIf
EndFuncoÝ÷ ØÆ   M«­¢+Ø¥¹±Õ±ÐíU%
½¹ÍѹÑÍà¹ÔÌÐì(¥¹±Õ±Ðí]¥¹½ÝÍ
½¹ÍѹÑ̹ÔÌÐì(¥¹±Õ±Ðí%A±Õ̹ÔÌÐì(¥¹±Õ±Ðí5¥Í¹ÔÌÐì(¥¹±Õ±Ðí]¥¹A$¹ÔÌÐì((ÀÌØíÕ¼ô¥%¹¥Ð¡MÉ¥ÁѥȵÀìÅÕ½ÐìÀäÈí¥µÉ¸µU
Edited by BillLuvsU

[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Link to comment
Share on other sites

I must say I'm lost... but I guess I got a little bit close.

I added:

Global $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend

at the top and uncommented the line

;GifDrawFrame($i, $ufo)

and the gif shows, but doesn't move. I thought it was because you used "$i=+1" instead of "$i+=1", but no! the gif won't move...

Link to comment
Share on other sites

So wait, those variables have to be global? I tried declaring them locally inside the initiate function and that didn't work. I'M SO CONFUSED. T~T

[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Link to comment
Share on other sites

I can't really understand WHY it doesn't work... some problem with variable types? I don't really understand why they have to be global, they are not used anywhere else in the script. I added that line just so I could add the Quit func.

Link to comment
Share on other sites

Em, now it works:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.au3>
;====Fix========
Global $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend
Global $GFC, $GFDC, $pDimensionIDs, $tDL
;==============
$ufo = GifInit(@ScriptDir & "\gif-Green-UFO.gif")
$i = 0
While 1
    If $i = $ufo[9] Then $i = 0
    GifDrawFrame($i, $ufo)
    Sleep(100)
    $i+=1
WEnd


Func GifInit( $Gif )
   ;local $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY
   ;Local $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend
   ;Local $GFC, $GFDC, $pDimensionIDs, $tDL
    Local $return[10]
   
    $gui_handle = GUICreate("", 0, 0, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetState()
    _GDIPlus_Startup()
   
   ; Load your animated gif
    $hImage = _GDIPlus_ImageLoadFromFile($Gif)
    $ApW = _GDIPlus_ImageGetWidth($hImage)
    $ApH = _GDIPlus_ImageGetHeight($hImage)

    $hScrDC = _WinAPI_GetDC($gui_handle)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)

    $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)

   ; 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]
   
    $return[0] = $gui_handle;the GUI handle for moving etc. later
    $return[1] = $hImage;image handle
    $return[2] = $pDimensionIDs;a pointer to the GUID struct.
    $return[3] = $hMemDC;not sure actually -.-;;;;
    $return[4] = $hScrDC;not sure actually -.-;;;;
    $return[5] = $pSize;not sure actually -.-;;;;
    $return[6] = $pSource;not sure actually -.-;;;;
    $return[7] = $pBlend;alpha I think?
    $return[8] = 0;current frame number
    $return[9] = $GFC;Gif Frame Count, total number of frames
    Return $return
   
EndFunc  ;==>GifInit

Func GifDrawFrame($i, $info)
    $info[8] = $i;current frame number
   
   ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc  ;==>GifDrawFrame

Func GifDrawNextFrame($info)
    $info[8] =+ 1;current frame number
   
   ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "int", $info[8])

   ; 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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc  ;==>GifDrawFrame

Func GifDrawPreviousFrame($info)
    $info[8] =- 1;current frame number
   
   ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "int", $info[8])

   ; 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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc  ;==>GifDrawFrame

But I'm still VERY confused. I demand answers from the experts. No idea why this happens.

Oh, and it's $x+=n not $x=+n so change that. And i think you won't be able to change the values of the elements of $info if you don't either declare that array as global or you use byref in every func.

Link to comment
Share on other sites

Well that completely kills this code. if those variables have to be global, I can't think of any organizational layout that could work.

Edited by BillLuvsU

[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Link to comment
Share on other sites

Wow you must just be too smart for all of us lowly non-experts. The problem you are having is that any time you create a struct and declare it as local, you're losing the structs once you leave the function. You saved the pointer to the struct, but not the actual struct so the pointer is useless. The solution is quite simple. Send your return array by reference to the function.

I haven't messed around enough to know exactly what you need to save in the array, but this works so its a starting point.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.au3>
;====Fix========
Global $arUfo
;==============
GifInit(@ScriptDir & "\gif-Green-UFO.gif", $arUfo)
$i = 0
While 1
    If $i = $arUfo[9] Then $i = 0
    GifDrawFrame($i, $arUfo)
    Sleep(100)
    $i+=1
WEnd


Func GifInit( $Gif, ByRef $return)
    Local $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY
;~   Local $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend
    Local $GFC, $GFDC;, $pDimensionIDs, $tDL
    Dim $return[14]
  
    $return[0] = GUICreate("", 0, 0, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetState()
    _GDIPlus_Startup()
  
  ; Load your animated gif
    $return[1] = _GDIPlus_ImageLoadFromFile($Gif)
    $ApW = _GDIPlus_ImageGetWidth($return[1])
    $ApH = _GDIPlus_ImageGetHeight($return[1])

    $return[4] = _WinAPI_GetDC($return[0])
    $return[3] = _WinAPI_CreateCompatibleDC($return[4])

    $return[10] = DllStructCreate($tagSIZE)
    DllStructSetData($return[10], "X", $ApW)
    DllStructSetData($return[10], "Y", $ApH)
    $return[5] = DllStructGetPtr($return[10])

    $return[11] = DllStructCreate($tagPOINT)
    $return[6] = DllStructGetPtr($return[11])

    $return[12] = DllStructCreate($tagBLENDFUNCTION)
    DllStructSetData($return[12], "Alpha", 255)
    DllStructSetData($return[12], "Format", 1)
    $return[7] = DllStructGetPtr($return[12])

  ; Create a struct to hold the GUID.
    $return[13] = DllStructCreate($tagGUID)

  ; Get a pointer to the GUID struct.
    $return[2] = DllStructGetPtr($return[13])

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

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

  ; Get the FrameCount of the loaded gif by passing the GUID pointer
    $GFC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "int", $return[1], "ptr", $return[2], "int*", 0)
    $return[9] = $GFC[3]
  
;~   $return[0] = $gui_handle;the GUI handle for moving etc. later
;~   $return[1] = $hImage;image handle
;~   $return[2] = $pDimensionIDs;a pointer to the GUID struct.
;~   $return[3] = $hMemDC;not sure actually -.-;;;;
;~   $return[4] = $hScrDC;not sure actually -.-;;;;
;~   $return[5] = $pSize;not sure actually -.-;;;;
;~   $return[6] = $pSource;not sure actually -.-;;;;
;~   $return[7] = $pBlend;alpha I think?
;~   $return[8] = 0;current frame number
;~   $return[9] = $GFC;Gif Frame Count, total number of frames
;~  $return[10] = $tSize
;~  $return[11] = $tSource
;~  $return[12] = $tBlend
;~  $return[13] = $tDL
;~   Return $return
  
EndFunc ;==>GifInit

Func GifDrawFrame($i, $info)
    $info[8] = $i;current frame number
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame

Func GifDrawNextFrame($info)
    $info[8] =+ 1;current frame number
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "int", $info[8])

  ; 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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame

Func GifDrawPreviousFrame($info)
    $info[8] =- 1;current frame number
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $info[1], "ptr", $info[2], "int", $info[8])

  ; 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($info[1])
    $hOld = _WinAPI_SelectObject($info[3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($info[0], $info[4], 0, $info[5], $info[3], $info[6], 0, $info[7], $ULW_ALPHA)
    _WinAPI_SelectObject($info[3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame
Link to comment
Share on other sites

*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

Link to comment
Share on other sites

Thankyou very much for your help Zorphnog.

Anyways here is what I smashed out to serve my needs, it's sloppy and ugly but contained inside itself and allows for good orginazation and performance outside of it's bubble. Just longer loading times I suppose. Of course if anybody has a better way to do this than please be my guest and post it here.

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

Const $GIF_guiHWND = 0
Const $GIF_hwnd = 1
Const $GIF_Num_Of_Frames = 9
Const $GIF_Current_Frame = 8

HotKeySet( "{esc}", "byebye" )

;====Fix========
Global $Data_Gifs[101][14]
$Data_Gifs[0][0] = 0 ;Count of how many Gifs there are in existance currently.
;==============
GifInit(@ScriptDir & "\gif-Green-UFO.gif", 1 )

$i = 0
While 1
    If $i = $Data_Gifs[1][9] Then $i = 0
    GifDrawFrame($i, 1)
    Sleep(100)
    $i+=1
WEnd

Func GifInit( $Gif, $GifValue )
    Dim $temp_GifInitReturn
    GifInit2( $Gif, $temp_GifInitReturn )
    $Data_Gifs[$GifValue][0] = $temp_GifInitReturn[0]
    $Data_Gifs[$GifValue][1] = $temp_GifInitReturn[1]
    $Data_Gifs[$GifValue][2] = $temp_GifInitReturn[2]
    $Data_Gifs[$GifValue][3] = $temp_GifInitReturn[3]
    $Data_Gifs[$GifValue][4] = $temp_GifInitReturn[4]
    $Data_Gifs[$GifValue][5] = $temp_GifInitReturn[5]
    $Data_Gifs[$GifValue][6] = $temp_GifInitReturn[6]
    $Data_Gifs[$GifValue][7] = $temp_GifInitReturn[7]
    $Data_Gifs[$GifValue][8] = $temp_GifInitReturn[8]
    $Data_Gifs[$GifValue][9] = $temp_GifInitReturn[9]
    $Data_Gifs[$GifValue][10] = $temp_GifInitReturn[10]
    $Data_Gifs[$GifValue][11] = $temp_GifInitReturn[11]
    $Data_Gifs[$GifValue][12] = $temp_GifInitReturn[12]
    $Data_Gifs[$GifValue][13] = $temp_GifInitReturn[13]
    $Data_Gifs[0][0] += 1
EndFunc

Func GifInit2( $Gif, ByRef $return)
    Local $i = 0, $ApX, $ApY, $ApW, $ApH, $eX, $eY
;~     Local $hImage, $hBitmap, $hScrDC, $hMemDC, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend
    Local $GFC, $GFDC;, $pDimensionIDs, $tDL
    Dim $return[14]
  
    $return[0] = GUICreate("", 0, 0, -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetState()
    _GDIPlus_Startup()
  
  ; Load your animated gif
    $return[1] = _GDIPlus_ImageLoadFromFile($Gif)
    $ApW = _GDIPlus_ImageGetWidth($return[1])
    $ApH = _GDIPlus_ImageGetHeight($return[1])

    $return[4] = _WinAPI_GetDC($return[0])
    $return[3] = _WinAPI_CreateCompatibleDC($return[4])

    $return[10] = DllStructCreate($tagSIZE)
    DllStructSetData($return[10], "X", $ApW)
    DllStructSetData($return[10], "Y", $ApH)
    $return[5] = DllStructGetPtr($return[10])

    $return[11] = DllStructCreate($tagPOINT)
    $return[6] = DllStructGetPtr($return[11])

    $return[12] = DllStructCreate($tagBLENDFUNCTION)
    DllStructSetData($return[12], "Alpha", 255)
    DllStructSetData($return[12], "Format", 1)
    $return[7] = DllStructGetPtr($return[12])

  ; Create a struct to hold the GUID.
    $return[13] = DllStructCreate($tagGUID)

  ; Get a pointer to the GUID struct.
    $return[2] = DllStructGetPtr($return[13])

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

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

  ; Get the FrameCount of the loaded gif by passing the GUID pointer
    $GFC = DllCall($ghGDIPDll, "int", "GdipImageGetFrameCount", "int", $return[1], "ptr", $return[2], "int*", 0)
    $return[9] = $GFC[3]
  
;~     $return[0] = $gui_handle;the GUI handle for moving etc. later
;~     $return[1] = $hImage;image handle
;~     $return[2] = $pDimensionIDs;a pointer to the GUID struct.
;~     $return[3] = $hMemDC;not sure actually -.-;;;;
;~     $return[4] = $hScrDC;not sure actually -.-;;;;
;~     $return[5] = $pSize;not sure actually -.-;;;;
;~     $return[6] = $pSource;not sure actually -.-;;;;
;~     $return[7] = $pBlend;alpha I think?
;~     $return[8] = 0;current frame number
;~     $return[9] = $GFC;Gif Frame Count, total number of frames
;~     $return[10] = $tSize
;~     $return[11] = $tSource
;~     $return[12] = $tBlend
;~     $return[13] = $tDL
;~     Return $return
  
EndFunc ;==>GifInit

Func GifDrawFrame($i, $info)
    $Data_Gifs[$info][$GIF_Current_Frame] = $i;current frame number
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $Data_Gifs[$info][1], "ptr", $Data_Gifs[$info][2], "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($Data_Gifs[$info][1])
    $hOld = _WinAPI_SelectObject($Data_Gifs[$info][3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($Data_Gifs[$info][0], $Data_Gifs[$info][4], 0, $Data_Gifs[$info][5], $Data_Gifs[$info][3], $Data_Gifs[$info][6], 0, $Data_Gifs[$info][7], $ULW_ALPHA)
    _WinAPI_SelectObject($Data_Gifs[$info][3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame

Func GifDrawNextFrame($info)
    $Data_Gifs[$info][8] += 1; $Data_Gifs[$info][8] + 1;current frame number
    If $Data_Gifs[$info][8] > $Data_Gifs[$info][9] Then $Data_Gifs[$info][8] = 0
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $Data_Gifs[$info][1], "ptr", $Data_Gifs[$info][2], "int", $Data_Gifs[$info][8])

  ; 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($Data_Gifs[$info][1])
    $hOld = _WinAPI_SelectObject($Data_Gifs[$info][3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($Data_Gifs[$info][0], $Data_Gifs[$info][4], 0, $Data_Gifs[$info][5], $Data_Gifs[$info][3], $Data_Gifs[$info][6], 0, $Data_Gifs[$info][7], $ULW_ALPHA)
    _WinAPI_SelectObject($Data_Gifs[$info][3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame

Func GifDrawPreviousFrame($info)
    $Data_Gifs[$info][8] -= 1;current frame number
  
  ; Select the ActiveFrame in the loaded gif by telling it. The frame starts @ 0 ($i)
    DllCall($ghGDIPDll, "int", "GdipImageSelectActiveFrame", "ptr", $Data_Gifs[$info][1], "ptr", $Data_Gifs[$info][2], "int", $Data_Gifs[$info][8])

  ; 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($Data_Gifs[$info][1])
    $hOld = _WinAPI_SelectObject($Data_Gifs[$info][3], $hBitmap)

    _WinAPI_UpdateLayeredWindow($Data_Gifs[$info][0], $Data_Gifs[$info][4], 0, $Data_Gifs[$info][5], $Data_Gifs[$info][3], $Data_Gifs[$info][6], 0, $Data_Gifs[$info][7], $ULW_ALPHA)
    _WinAPI_SelectObject($Data_Gifs[$info][3], $hOld)
    _WinAPI_DeleteObject($hBitmap); Needs to be deleted after each creation, not just in the end once
EndFunc ;==>GifDrawFrame

Func byebye( )
    Exit 
EndFunc

[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Link to comment
Share on other sites

  • 7 months later...

sorry for bringing up an old thread but I have a question about animated gifs and this topic is as close to what I want to achieve but I have a knowledge gap. I have looked at ProgAndy `s animated gif UDF which allows the script to create a gif onto a gui. I have also looked at this thread with the final code edited by BillLuvsU

I want to use BillLuvsU`s code Code instead of ProgAndy `s UDF as this allows me to have a transparant gif on the screen that I can adjust the speed of the gif but the only thing i am having issues with is getting this animated gif to sit onto a precreated Gui i have already created. I am just starting out with GUI so apologies for my stupidity.....

I am guessing the reason I cannot get Nahuel`s GUI to nest in my GUI is downto the fact that they are both seperate GUIs in their own right.

Here is an example of the gui I am building - All I want to do is to beable to place the Gif somewhewre on the GUI

#include <GUIConstants.au3>

#include <WindowsConstants.au3>

#Include <GuiListView.au3>

#include <GUIConstantsEx.au3>

GUICreate("listview items", 500,500, 100, 200, -1, $WS_EX_ACCEPTFILES )

GUISetBkColor (0x00E0FFFF) ; will change background color

Global $listview = GuiCtrlCreateListView ("ID | Application Name | Progress ",10,10,400,300);,$LVS_SORTDESCENDING)

GuiCtrlCreateListViewItem("1|2|3", $listview)

GuiSetState()

Sleep(5000)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...