-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathclass_gif.ahk
117 lines (94 loc) · 3.32 KB
/
class_gif.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
; Title: Using an animated Gif on a gui Topic is solved @
; Link: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=83358
; Author:
; Date:
; for: AHK_L
/*
#SingleInstance Force
SetBatchLines -1
;#include Gdip.ahk
pToken := Gdip_Startup()
OnExit, Exit
Gui, Add, Picture, hwndhwndGif1 w80 h80
Gui, Add, Button, x+10 w80 h80 gPlayPause hwndhwndPlayPause, Play
Gui, Show,, Animated gif
gif1 := new Gif("mario_running.gif", hwndGif1)
return
;######################################################
PlayPause:
isPlaying := gif1.isPlaying
GuiControl,, % hwndPlayPause, % (isPlaying) ? "Play" : "Pause"
if (!isPlaying) {
gif1.Play()
} else {
gif1.Pause()
}
return
;######################################################
Exit:
Gdip_ShutDown(pToken)
ExitApp
return
;######################################################
*/
class Gif {
__New(file, hwnd, cycle := true) {
this.file := file
this.hwnd := hwnd
this.cycle := cycle
this.pBitmap := Gdip_CreateBitmapFromFile(this.file)
Gdip_GetImageDimensions(this.pBitmap, width, height)
this.width := width, this.height := height
this.isPlaying := false
DllCall("Gdiplus\GdipImageGetFrameDimensionsCount", "ptr", this.pBitmap, "uptr*", frameDimensions)
this.SetCapacity("dimensionIDs", 16*frameDimensions)
DllCall("Gdiplus\GdipImageGetFrameDimensionsList", "ptr", this.pBitmap, "uptr", this.GetAddress("dimensionIDs"), "int", frameDimensions)
DllCall("Gdiplus\GdipImageGetFrameCount", "ptr", this.pBitmap, "uptr", this.GetAddress("dimensionIDs"), "int*", count)
this.frameCount := count
this.frameCurrent := -1
this.frameDelay := this.GetFrameDelay(this.pBitmap)
this._Play("")
}
; Return a zero-based array, containing the frames delay (in milliseconds)
GetFrameDelay(pImage) {
static PropertyTagFrameDelay := 0x5100
DllCall("Gdiplus\GdipGetPropertyItemSize", "Ptr", pImage, "UInt", PropertyTagFrameDelay, "UInt*", ItemSize)
VarSetCapacity(Item, ItemSize, 0)
DllCall("Gdiplus\GdipGetPropertyItem" , "Ptr", pImage, "UInt", PropertyTagFrameDelay, "UInt", ItemSize, "Ptr", &Item)
PropLen := NumGet(Item, 4, "UInt")
PropVal := NumGet(Item, 8 + A_PtrSize, "UPtr")
outArray := []
Loop, % PropLen//4 {
if !n := NumGet(PropVal+0, (A_Index-1)*4, "UInt")
n := 10
outArray[A_Index-1] := n * 10
}
return outArray
}
Play() {
this.isPlaying := true
fn := this._Play.Bind(this)
this._fn := fn
SetTimer, % fn, -1
}
Pause() {
this.isPlaying := false
fn := this._fn
SetTimer, % fn, Delete
}
_Play(mode := "set") {
this.frameCurrent := mod(++this.frameCurrent, this.frameCount)
DllCall("Gdiplus\GdipImageSelectActiveFrame", "ptr", this.pBitmap, "uptr", this.GetAddress("dimensionIDs"), "int", this.frameCurrent)
hBitmap := Gdip_CreateHBITMAPFromBitmap(this.pBitmap)
SetImage(this.hwnd, hBitmap)
DeleteObject(hBitmap)
if (mode = "set" && this.frameCurrent < (this.cycle ? 0xFFFFFFFF : this.frameCount - 1)) {
fn := this._fn
SetTimer, % fn, % -1 * this.frameDelay[this.frameCurrent]
}
}
__Delete() {
Gdip_DisposeImage(this.pBitmap)
Object.Delete("dimensionIDs")
}
}