There is already a new version of the class:
Code: Select all
#NoEnv
SetBatchLines, -1
SetWorkingDir, % A_ScriptDir
if !FileExist("abstract.gif")
UrlDownloadToFile, https://i.imgur.com/egxGqKK.gif, abstract.gif
filePath := "abstract.gif"
Menu, Tray, Icon, % "HBITMAP:*" . LoadPicture(filePath, "GDI+ w32 h32")
exStyles := (WS_EX_COMPOSITED := 0x02000000) | (WS_EX_LAYERED := 0x80000)
Gui, New, +E%exStyles% +hwndhGui
Gui, Add, Picture, hwndhPic gOnClick, % "HBITMAP:" . LoadPicture(filePath, "GDI+")
OnMessage(0x20, Func("WM_SETCURSOR").Bind(hPic))
Gui, Add, Button, xp y+10 w75 h24 gOnClick Default, Play
Gui, Add, Button, x+5 yp wp hp gOnClick , Stop
Gui, Add, Button, x+5 yp w35 hp gOnClick , <
Gui, Add, Button, x+5 yp wp hp gOnClick , >
UserFunc := Func("PlayGif").Bind(hGui, hPic, FramesCount := [])
MyGif := new AnimateGif(filePath, UserFunc) ; for every frame UserFunc will be called with two params: currentFrameIdx and hBitmap
; user is responsible for deleting hBitmap
count := FramesCount[1] := MyGif.framesCount
Gui, Show,, % "Frame: " . Format("{:0" . StrLen(count) . "}", 1) . "/" . count
Return
OnClick:
try GuiControl,, Pause, Play
Switch A_GuiControl {
Case "Stop": MyGif.Stop()
Case "<" : MyGif.Prev()
Case ">" : MyGif.Next()
Default:
if MyGif.playing
MyGif.Pause()
else {
GuiControl,, Play, Pause
MyGif.Play()
}
}
Return
GuiClose:
ExitApp
PlayGif(hGui, hPic, FramesCount, currentFrameIdx, hBitmap) {
GuiControl,, % hPic, HBITMAP: %hBitmap%
count := FramesCount[1]
frame := Format("{:0" . StrLen(count) . "}", currentFrameIdx)
Gui, %hGui%: Show, NA, % "Frame: " . frame . "/" . count
}
WM_SETCURSOR(hPic, wp) {
static hCursor, flags := (LR_DEFAULTSIZE := 0x40) | (LR_SHARED := 0x8000)
, params := [ "Ptr", 0, "UInt", OCR_HAND := 32649
, "UInt", IMAGE_CURSOR := 2
, "Int", 0, "Int", 0, "UInt", flags, "Ptr" ]
(!hCursor && hCursor := DllCall("LoadImage", params*))
if (wp = hPic)
Return DllCall("SetCursor", "Ptr", hCursor)
}
class AnimateGif
{
; UserFunc will be called with two params: currentFrameIdx and hBitmap
; user is responsible for deleting hBitmap
__New(gifFile, UserFunc := "", cycle := true) {
this.GDIp := new GDIplus
this.pBitmap := this.GDIp.CreateBitmapFromFile(gifFile)
this.Frames := new this._FramesHandling(this.GDIp, this.pBitmap, UserFunc, cycle)
this.GDIp.GetImageDimensions(this.pBitmap, width, height)
this.width := width
this.height := height
}
Play() {
this.playing := true
this.Frames.PlayFrames()
}
Pause() {
if this.playing {
this.playing := false
timer := this.Frames._PlayTimer
SetTimer, % timer, Delete
}
}
Stop() {
this.Pause()
this.ShowFrame(1)
}
Prev() {
this.ShowFrame("prev")
}
Next() {
this.ShowFrame("next")
}
ShowFrame(which) { ; 'which' can be "prev", "next" or "", or 1-based frame index
this.Pause()
(which = "prev" && this.Frames.currentFrame -= 2)
(which + 0 && this.Frames.currentFrame := which - 1)
this.Frames.PlayFrames()
}
GetFrameByIndex(idx) {
Return hBitmap := this.Frames.GetFrame(idx - 1)
}
playing[] {
get {
Return this.Frames.playing
}
set {
Return this.Frames.playing := value
}
}
framesCount[] {
get {
Return this.Frames.frameCount
}
}
__Delete() {
this.Frames.Clear()
this.GDIp.DisposeImage(this.pBitmap)
this.Delete("Frames")
this.GDIp.Release()
}
class _FramesHandling {
__New(GDIp, pBitmap, userFunc, cycle) {
this.GDIp := GDIp
this.pBitmap := pBitmap
this.userFunc := userFunc
this.cycle := cycle
this.GetFrameCount()
this.GetFrameDelay()
this._PlayTimer := ObjBindMethod(this, "PlayFrames")
this._currentFrame := 1
}
currentFrame[] {
get {
Return this._currentFrame
}
set {
Return this._currentFrame := value < 1 ? this.frameCount + value : value > this.frameCount ? 1 : value
}
}
PlayFrames() {
Critical
frameIdx := ++this.currentFrame - 1
if ( this.playing && this.currentFrame != (this.cycle ? 0xFFFFFFFF : this.frameCount) ) {
timer := this._PlayTimer
SetTimer, % timer, % "-" this.frameDelay[frameIdx]
}
if userFunc := this.userFunc
%userFunc%(this.currentFrame, this.GetFrame(frameIdx))
}
GetFrameCount() {
this.frameCount := this.GDIp.GetFrameCount(this.pBitmap, dimensionIDs, size)
this.SetCapacity("dimensionIDs", size)
this.pDimensionIDs := this.GetAddress("dimensionIDs")
DllCall("RtlMoveMemory", "Ptr", this.pDimensionIDs, "Ptr", &dimensionIDs, "Ptr", size)
VarSetCapacity(dimensionIDs, 0), dimensionIDs := ""
this.currentFrame := 0
}
GetFrameDelay() {
this.GDIp.GetPropertyItem(this.pBitmap, PropertyTagFrameDelay := 0x5100, item)
len := NumGet(item, 4, "UInt")
val := NumGet(item, 8 + A_PtrSize, "UPtr")
this.frameDelay := []
Loop, % len//4 {
i := A_Index - 1
n := NumGet(val + i*4, "UInt") * 10
this.frameDelay[i] := n ? n : 100
}
}
GetFrame(idx) {
this.GDIp.ImageSelectActiveFrame(this.pBitmap, this.pDimensionIDs, idx)
Return this.GDIp.CreateHBITMAPFromBitmap(this.pBitmap)
}
Clear() {
this.playing := false
timer := this._PlayTimer
SetTimer, % timer, Delete
this.Delete("dimensionIDs")
}
}
}
class GDIplus {
__New() {
static Instance := ""
if Instance.references {
++Instance.references
Return Instance
}
this.references := 1
if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
this.token := pToken
Return Instance := this
}
Release() {
if --this.references
Return
DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("FreeLibrary", "Ptr", hModule)
}
CreateBitmapFromFile(sFile) {
DllCall("gdiplus\GdipCreateBitmapFromFile", "WStr", sFile, "PtrP", pBitmap)
Return pBitmap
}
CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff) {
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "Int", Background)
Return hbm
}
GetImageDimensions(pBitmap, ByRef Width, ByRef Height) {
DllCall("gdiplus\GdipGetImageWidth", "Ptr", pBitmap, "UIntP", Width)
DllCall("gdiplus\GdipGetImageHeight", "Ptr", pBitmap, "UIntP", Height)
}
GetFrameCount(pBitmap, ByRef dimensionIDs, ByRef size) {
DllCall("gdiplus\GdipImageGetFrameDimensionsCount", "Ptr", pBitmap, "UIntP", frameDimensions)
VarSetCapacity(dimensionIDs, size := 16*frameDimensions)
DllCall("gdiplus\GdipImageGetFrameDimensionsList", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UInt", frameDimensions)
DllCall("gdiplus\GdipImageGetFrameCount", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UIntP", count)
Return count
}
GetPropertyItem(pBitmap, tag, ByRef item) {
DllCall("gdiplus\GdipGetPropertyItemSize", "Ptr", pBitmap, "UInt", tag, "UIntP", size)
VarSetCapacity(item, size, 0)
DllCall("gdiplus\GdipGetPropertyItem", "Ptr", pBitmap, "UInt", tag, "UInt", size, "Ptr", &item)
Return size
}
ImageSelectActiveFrame(pBitmap, pDimensionIDs, idx) {
Return DllCall("gdiplus\GdipImageSelectActiveFrame", "Ptr", pBitmap, "Ptr", pDimensionIDs, "Int", idx)
}
DisposeImage(pBitmap) {
Return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
}
}
For your gif:
Code: Select all
SetBatchLines, -1
gifFile := "welcome.gif"
exStyles := (WS_EX_COMPOSITED := 0x02000000) | (WS_EX_LAYERED := 0x80000)
Gui, New, +E%exStyles%
gui, color, black
Gui, Add, Picture, w480 y10 hwndhwndGif1, % gifFile
Gui, Add, Button, xp y+10 w80 h24 hwndhPlayPause gOnButtonClick, Play
Gui, Add, Button, xp y+10 w80 h24 gOnButtonClick, Play Once
UserFunc := Func("PlayGif").Bind(hwndGif1, hPlayPause, FramesCount := [], PlayOnce := [false])
MyGif := new AnimateGif(gifFile, UserFunc)
FramesCount[1] := MyGif.framesCount
Gui, Show,, Animated gif
Return
OnButtonClick:
Switch A_GuiControl {
Case "Play":
GuiControl,, Play, Pause
MyGif.Play()
Case "Pause":
GuiControl,, Pause, Play
MyGif.Pause()
Case "Play Once":
PlayOnce[1] := true
if !MyGif.playing {
GuiControl,, Play, Pause
MyGif.Play()
}
}
Return
PlayGif(hPic, hPlayPause, FramesCount, PlayOnce, currentFrameIdx, hBitmap) {
global MyGif
GuiControl,, % hPic, HBITMAP: %hBitmap%
if (PlayOnce[1] && currentFrameIdx = FramesCount[1]) {
MyGif.Stop()
PlayOnce[1] := false
GuiControl,, %hPlayPause%, Play
}
}
GuiClose() {
ExitApp
}
class AnimateGif
{
; UserFunc will be called with two params: currentFrameIdx and hBitmap
; user is responsible for deleting hBitmap
__New(gifFile, UserFunc := "", cycle := true) {
this.GDIp := new GDIplus
this.pBitmap := this.GDIp.CreateBitmapFromFile(gifFile)
this.Frames := new this._FramesHandling(this.GDIp, this.pBitmap, UserFunc, cycle)
this.GDIp.GetImageDimensions(this.pBitmap, width, height)
this.width := width
this.height := height
}
Play() {
this.playing := true
this.Frames.PlayFrames()
}
Pause() {
if this.playing {
this.playing := false
timer := this.Frames._PlayTimer
SetTimer, % timer, Delete
}
}
Stop() {
this.Pause()
this.ShowFrame(1)
}
Prev() {
this.ShowFrame("prev")
}
Next() {
this.ShowFrame("next")
}
ShowFrame(which) { ; 'which' can be "prev", "next" or "", or 1-based frame index
this.Pause()
(which = "prev" && this.Frames.currentFrame -= 2)
(which + 0 && this.Frames.currentFrame := which - 1)
this.Frames.PlayFrames()
}
GetFrameByIndex(idx) {
Return hBitmap := this.Frames.GetFrame(idx - 1)
}
playing[] {
get {
Return this.Frames.playing
}
set {
Return this.Frames.playing := value
}
}
framesCount[] {
get {
Return this.Frames.frameCount
}
}
__Delete() {
this.Frames.Clear()
this.GDIp.DisposeImage(this.pBitmap)
this.Delete("Frames")
this.GDIp.Release()
}
class _FramesHandling {
__New(GDIp, pBitmap, userFunc, cycle) {
this.GDIp := GDIp
this.pBitmap := pBitmap
this.userFunc := userFunc
this.cycle := cycle
this.GetFrameCount()
this.GetFrameDelay()
this._PlayTimer := ObjBindMethod(this, "PlayFrames")
this._currentFrame := 1
}
currentFrame[] {
get {
Return this._currentFrame
}
set {
Return this._currentFrame := value < 1 ? this.frameCount + value : value > this.frameCount ? 1 : value
}
}
PlayFrames() {
Critical
frameIdx := ++this.currentFrame - 1
if ( this.playing && this.currentFrame != (this.cycle ? 0xFFFFFFFF : this.frameCount) ) {
timer := this._PlayTimer
SetTimer, % timer, % "-" this.frameDelay[frameIdx]
}
if userFunc := this.userFunc
%userFunc%(this.currentFrame, this.GetFrame(frameIdx))
}
GetFrameCount() {
this.frameCount := this.GDIp.GetFrameCount(this.pBitmap, dimensionIDs, size)
this.SetCapacity("dimensionIDs", size)
this.pDimensionIDs := this.GetAddress("dimensionIDs")
DllCall("RtlMoveMemory", "Ptr", this.pDimensionIDs, "Ptr", &dimensionIDs, "Ptr", size)
VarSetCapacity(dimensionIDs, 0), dimensionIDs := ""
this.currentFrame := 0
}
GetFrameDelay() {
this.GDIp.GetPropertyItem(this.pBitmap, PropertyTagFrameDelay := 0x5100, item)
len := NumGet(item, 4, "UInt")
val := NumGet(item, 8 + A_PtrSize, "UPtr")
this.frameDelay := []
Loop, % len//4 {
i := A_Index - 1
n := NumGet(val + i*4, "UInt") * 10
this.frameDelay[i] := n ? n : 100
}
}
GetFrame(idx) {
this.GDIp.ImageSelectActiveFrame(this.pBitmap, this.pDimensionIDs, idx)
Return this.GDIp.CreateHBITMAPFromBitmap(this.pBitmap)
}
Clear() {
this.playing := false
timer := this._PlayTimer
SetTimer, % timer, Delete
this.Delete("dimensionIDs")
}
}
}
class GDIplus {
__New() {
static Instance := ""
if Instance.references {
++Instance.references
Return Instance
}
this.references := 1
if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
this.token := pToken
Return Instance := this
}
Release() {
if --this.references
Return
DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("FreeLibrary", "Ptr", hModule)
}
CreateBitmapFromFile(sFile) {
DllCall("gdiplus\GdipCreateBitmapFromFile", "WStr", sFile, "PtrP", pBitmap)
Return pBitmap
}
CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff) {
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "Int", Background)
Return hbm
}
GetImageDimensions(pBitmap, ByRef Width, ByRef Height) {
DllCall("gdiplus\GdipGetImageWidth", "Ptr", pBitmap, "UIntP", Width)
DllCall("gdiplus\GdipGetImageHeight", "Ptr", pBitmap, "UIntP", Height)
}
GetFrameCount(pBitmap, ByRef dimensionIDs, ByRef size) {
DllCall("gdiplus\GdipImageGetFrameDimensionsCount", "Ptr", pBitmap, "UIntP", frameDimensions)
VarSetCapacity(dimensionIDs, size := 16*frameDimensions)
DllCall("gdiplus\GdipImageGetFrameDimensionsList", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UInt", frameDimensions)
DllCall("gdiplus\GdipImageGetFrameCount", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UIntP", count)
Return count
}
GetPropertyItem(pBitmap, tag, ByRef item) {
DllCall("gdiplus\GdipGetPropertyItemSize", "Ptr", pBitmap, "UInt", tag, "UIntP", size)
VarSetCapacity(item, size, 0)
DllCall("gdiplus\GdipGetPropertyItem", "Ptr", pBitmap, "UInt", tag, "UInt", size, "Ptr", &item)
Return size
}
ImageSelectActiveFrame(pBitmap, pDimensionIDs, idx) {
Return DllCall("gdiplus\GdipImageSelectActiveFrame", "Ptr", pBitmap, "Ptr", pDimensionIDs, "Int", idx)
}
DisposeImage(pBitmap) {
Return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
}
}
However, if you always only need to play your gif once, just set the
cycle parameter to
false:
Code: Select all
SetBatchLines, -1
gifFile := "welcome.gif"
exStyles := (WS_EX_COMPOSITED := 0x02000000) | (WS_EX_LAYERED := 0x80000)
Gui, New, +E%exStyles%
gui, color, black
Gui, Add, Picture, w480 y10 hwndhwndGif1, % gifFile
Gui, Add, Button, xp y+10 w80 h24 gPlay, Play Once
UserFunc := Func("PlayGif").Bind(hwndGif1)
MyGif := new AnimateGif(gifFile, UserFunc, false)
Gui, Show,, Animated gif
Return
Play:
MyGif.Play()
Return
PlayGif(hPic, currentFrameIdx, hBitmap) {
GuiControl,, % hPic, HBITMAP: %hBitmap%
}
GuiClose() {
ExitApp
}
class AnimateGif
{
; UserFunc will be called with two params: currentFrameIdx and hBitmap
; user is responsible for deleting hBitmap
__New(gifFile, UserFunc := "", cycle := true) {
this.GDIp := new GDIplus
this.pBitmap := this.GDIp.CreateBitmapFromFile(gifFile)
this.Frames := new this._FramesHandling(this.GDIp, this.pBitmap, UserFunc, cycle)
this.GDIp.GetImageDimensions(this.pBitmap, width, height)
this.width := width
this.height := height
}
Play() {
this.playing := true
this.Frames.PlayFrames()
}
Pause() {
if this.playing {
this.playing := false
timer := this.Frames._PlayTimer
SetTimer, % timer, Delete
}
}
Stop() {
this.Pause()
this.ShowFrame(1)
}
Prev() {
this.ShowFrame("prev")
}
Next() {
this.ShowFrame("next")
}
ShowFrame(which) { ; 'which' can be "prev", "next" or "", or 1-based frame index
this.Pause()
(which = "prev" && this.Frames.currentFrame -= 2)
(which + 0 && this.Frames.currentFrame := which - 1)
this.Frames.PlayFrames()
}
GetFrameByIndex(idx) {
Return hBitmap := this.Frames.GetFrame(idx - 1)
}
playing[] {
get {
Return this.Frames.playing
}
set {
Return this.Frames.playing := value
}
}
framesCount[] {
get {
Return this.Frames.frameCount
}
}
__Delete() {
this.Frames.Clear()
this.GDIp.DisposeImage(this.pBitmap)
this.Delete("Frames")
this.GDIp.Release()
}
class _FramesHandling {
__New(GDIp, pBitmap, userFunc, cycle) {
this.GDIp := GDIp
this.pBitmap := pBitmap
this.userFunc := userFunc
this.cycle := cycle
this.GetFrameCount()
this.GetFrameDelay()
this._PlayTimer := ObjBindMethod(this, "PlayFrames")
this._currentFrame := 1
}
currentFrame[] {
get {
Return this._currentFrame
}
set {
Return this._currentFrame := value < 1 ? this.frameCount + value : value > this.frameCount ? 1 : value
}
}
PlayFrames() {
Critical
frameIdx := ++this.currentFrame - 1
if ( this.playing && this.currentFrame != (this.cycle ? 0xFFFFFFFF : this.frameCount) ) {
timer := this._PlayTimer
SetTimer, % timer, % "-" this.frameDelay[frameIdx]
}
if userFunc := this.userFunc
%userFunc%(this.currentFrame, this.GetFrame(frameIdx))
}
GetFrameCount() {
this.frameCount := this.GDIp.GetFrameCount(this.pBitmap, dimensionIDs, size)
this.SetCapacity("dimensionIDs", size)
this.pDimensionIDs := this.GetAddress("dimensionIDs")
DllCall("RtlMoveMemory", "Ptr", this.pDimensionIDs, "Ptr", &dimensionIDs, "Ptr", size)
VarSetCapacity(dimensionIDs, 0), dimensionIDs := ""
this.currentFrame := 0
}
GetFrameDelay() {
this.GDIp.GetPropertyItem(this.pBitmap, PropertyTagFrameDelay := 0x5100, item)
len := NumGet(item, 4, "UInt")
val := NumGet(item, 8 + A_PtrSize, "UPtr")
this.frameDelay := []
Loop, % len//4 {
i := A_Index - 1
n := NumGet(val + i*4, "UInt") * 10
this.frameDelay[i] := n ? n : 100
}
}
GetFrame(idx) {
this.GDIp.ImageSelectActiveFrame(this.pBitmap, this.pDimensionIDs, idx)
Return this.GDIp.CreateHBITMAPFromBitmap(this.pBitmap)
}
Clear() {
this.playing := false
timer := this._PlayTimer
SetTimer, % timer, Delete
this.Delete("dimensionIDs")
}
}
}
class GDIplus {
__New() {
static Instance := ""
if Instance.references {
++Instance.references
Return Instance
}
this.references := 1
if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
this.token := pToken
Return Instance := this
}
Release() {
if --this.references
Return
DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("FreeLibrary", "Ptr", hModule)
}
CreateBitmapFromFile(sFile) {
DllCall("gdiplus\GdipCreateBitmapFromFile", "WStr", sFile, "PtrP", pBitmap)
Return pBitmap
}
CreateHBITMAPFromBitmap(pBitmap, Background=0xffffffff) {
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "Int", Background)
Return hbm
}
GetImageDimensions(pBitmap, ByRef Width, ByRef Height) {
DllCall("gdiplus\GdipGetImageWidth", "Ptr", pBitmap, "UIntP", Width)
DllCall("gdiplus\GdipGetImageHeight", "Ptr", pBitmap, "UIntP", Height)
}
GetFrameCount(pBitmap, ByRef dimensionIDs, ByRef size) {
DllCall("gdiplus\GdipImageGetFrameDimensionsCount", "Ptr", pBitmap, "UIntP", frameDimensions)
VarSetCapacity(dimensionIDs, size := 16*frameDimensions)
DllCall("gdiplus\GdipImageGetFrameDimensionsList", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UInt", frameDimensions)
DllCall("gdiplus\GdipImageGetFrameCount", "Ptr", pBitmap, "Ptr", &dimensionIDs, "UIntP", count)
Return count
}
GetPropertyItem(pBitmap, tag, ByRef item) {
DllCall("gdiplus\GdipGetPropertyItemSize", "Ptr", pBitmap, "UInt", tag, "UIntP", size)
VarSetCapacity(item, size, 0)
DllCall("gdiplus\GdipGetPropertyItem", "Ptr", pBitmap, "UInt", tag, "UInt", size, "Ptr", &item)
Return size
}
ImageSelectActiveFrame(pBitmap, pDimensionIDs, idx) {
Return DllCall("gdiplus\GdipImageSelectActiveFrame", "Ptr", pBitmap, "Ptr", pDimensionIDs, "Int", idx)
}
DisposeImage(pBitmap) {
Return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
}
}