AnimGIFGadget (windows only)
Posted: Fri Mar 09, 2012 4:27 am
This is a small code to show animgifs.
Functions:
gdiplus_Init(); you have to call this before all other functions in this lib.
- Returns nonzero if successfully and zero if not
gdiplus_End(); you have to call this at the end of your program.
AnimGIFGadget(id, x, y, file.s, backcolor = #White, pause = #PB_Any); creates the animgifgadget.
Parameters:
- id = id like all other gadgets, #PB_Any is supported!
- x, y = position of your gadget
- file.s = Filename with path to your gif.
- backcolor = set the backcolor of gadget.
- pause = delay in ms between the frames.
- Returns the same as other gadgets.
AnimGIFGadgetMem(id, x, y, *mem, memsize, backcolor = #White, pause = #PB_Any)); creates the animgifgadget from Mem/DataSection
Parameters:
- id = id like all other gadgets, #PB_Any is supported!
- x, y = position of your gadget
- *mem = MemPointer.
- memsize = Size of Memory.
- backcolor = set the backcolor of gadget.
- pause = delay in ms between the frames.
- Returns the same as other gadgets.
FreeAnimGIFGadget(id = #PB_Any); Free and remove the gadget from the display. It's very important to free your Gadgets!
Parameters:
- id = #Gadget, Specifies the gadget to free.
a value of #PB_Any or -1 frees all AnimGIFGadgets.
[AnimGIFGadget.pbi]
[example.pb]
Have Fun 
Functions:
gdiplus_Init(); you have to call this before all other functions in this lib.
- Returns nonzero if successfully and zero if not
gdiplus_End(); you have to call this at the end of your program.
AnimGIFGadget(id, x, y, file.s, backcolor = #White, pause = #PB_Any); creates the animgifgadget.
Parameters:
- id = id like all other gadgets, #PB_Any is supported!
- x, y = position of your gadget
- file.s = Filename with path to your gif.
- backcolor = set the backcolor of gadget.
- pause = delay in ms between the frames.
- Returns the same as other gadgets.
AnimGIFGadgetMem(id, x, y, *mem, memsize, backcolor = #White, pause = #PB_Any)); creates the animgifgadget from Mem/DataSection
Parameters:
- id = id like all other gadgets, #PB_Any is supported!
- x, y = position of your gadget
- *mem = MemPointer.
- memsize = Size of Memory.
- backcolor = set the backcolor of gadget.
- pause = delay in ms between the frames.
- Returns the same as other gadgets.
FreeAnimGIFGadget(id = #PB_Any); Free and remove the gadget from the display. It's very important to free your Gadgets!
Parameters:
- id = #Gadget, Specifies the gadget to free.
a value of #PB_Any or -1 frees all AnimGIFGadgets.
[AnimGIFGadget.pbi]
Code: Select all
; Copyright (c) 2012 Thomas <ts-soft> Schulz
; Permission is hereby granted, free of charge, to any person obtaining a copy of this
; software and associated documentation files (the "Software"), to deal in the Software
; without restriction, including without limitation the rights to use, copy, modify, merge,
; publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to
; whom the Software is furnished to do so, subject to the following conditions:
; The above copyright notice and this permission notice shall be included in all copies or
; substantial portions of the Software.
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;==================================================================
;
; Library: AnimGIFGadget
; Author: Thomas <ts-soft> Schulz
; Date: Mrz 09, 2012
; Version: 1.4.2
; Target OS: Windows 2000 and higher
; Target Compiler: PureBasic 4.60 and later
; Requires: gdiplus.dll
;==================================================================
; History:
; 1.4.2, Mrz 13, 2012
; changed default backcolor for AnimGIFButton and AnimGIFButtonMem to #PB_Any
; AnimGIFButton and AnimGIFButtonMem supports Transparency, if you use #PB_Any as backcolor
; 1.4.1, Mrz 10, 2012
; + removed redundant code
; 1.4, Mrz 10, 2012
; added AnimGIFButton
; added AnimGIFButtonMem
; 1.3, Mrz 10, 2012
; changed from ImageGadget to CanvasGadget
; drawing-routines changed for better support of some gifs
; removed erase flag, no more required!
; added flag for background-color
; ATTENTION - this version requires Threadsafe Compileroption!
; 1.2.1, Mrz 10, 2012
; bugfix for incompatible to x64 with delaytime
; 1.2, Mrz 09, 2012
; + changed syntax for AnimGIFGadget
; + pause is optional, #PB_Any use the delaytime safed in gif!
; + added new Function: AnimGIFGadgetMem(id, x, y, *mem, memsize, pause = #PB_Any, erase = #False) to catch gif!
; 1.1, Mrz 09, 2012
; + correct structure GdiplusStartupInput
; + changed name of prototypes to solve compatible issues with other libs
; + added erase flag for AnimGIFGadget() as workaround for some gifs.
CompilerIf #PB_Compiler_Thread = 0
Debug "you have to enable threadsafe in compileroptions!"
CompilerEndIf
#PropertyTagFrameDelay = $5100
CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0
Structure GdiplusStartupInput
GdiPlusVersion.l
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64 ; ALIGN next pointer to 8
PB_Alignment.b[4]
CompilerEndIf
*DebugEventCallback.DebugEventProc
SuppressBackgroundThread.i
SuppressExternalCodecs.i
EndStructure
CompilerEndIf
Structure AnimGif_para
ID.i
bitmap.i
pause.i
semaphore.i
backcolor.i
type.i
EndStructure
Structure AnimGif_list
id.i
thread.i
semaphore.i
EndStructure
;{ Prototypes
Prototype __GdipCreateBitmapFromFile(filename.p-unicode, *bitmap)
Prototype __GdipCreateFromHDC(hdc, *graphics)
Prototype __GdipDeleteGraphics(*graphics)
Prototype __GdipDisposeImage(*image)
Prototype __GdipDrawImageI(*graphics, *image, x.l, y.l)
Prototype __GdipGetImageWidth(*image, *width)
Prototype __GdipGetImageHeight(*image, *height)
Prototype __GdipImageGetFrameCount(*image, *dimensionID.GUID, *count)
Prototype __GdipImageGetFrameDimensionsList(*image, *dimensionID.GUID, count.l)
Prototype __GdipImageSelectActiveFrame(*image, *dimensionID.GUID, frameIndex.l)
Prototype __GdipLoadImageFromStream(*stream, *bitmap)
Prototype __GdipGetPropertyItemSize(*image, propId.l, *size)
Prototype __GdipGetPropertyItem(*image, propId.l, propSize.l, *buffer)
Prototype __GdiplusShutdown(token)
Prototype __GdiplusStartup(*token, *input.GdiplusStartupInput, *output) ;}
;{ Globals
Global __GdipCreateBitmapFromFile.__GdipCreateBitmapFromFile
Global __GdipCreateFromHDC.__GdipCreateFromHDC
Global __GdipDeleteGraphics.__GdipDeleteGraphics
Global __GdipDisposeImage.__GdipDisposeImage
Global __GdipDrawImageI.__GdipDrawImageI
Global __GdipGetImageWidth.__GdipGetImageWidth
Global __GdipGetImageHeight.__GdipGetImageHeight
Global __GdipImageGetFrameCount.__GdipImageGetFrameCount
Global __GdipImageGetFrameDimensionsList.__GdipImageGetFrameDimensionsList
Global __GdipImageSelectActiveFrame.__GdipImageSelectActiveFrame
Global __GdipLoadImageFromStream.__GdipLoadImageFromStream
Global __GdipGetPropertyItemSize.__GdipGetPropertyItemSize
Global __GdipGetPropertyItem.__GdipGetPropertyItem
Global __GdiplusShutdown.__GdiplusShutdown
Global __GdiplusStartup.__GdiplusStartup
;}
Define __gdipToken__
Define __gdiphDLL__
Global NewList AnimGIFThreads.AnimGif_list()
Procedure.i gdiplus_Init()
Shared __gdipToken__, __gdiphDLL__
Protected gdpsi.GdiplusStartupInput
__gdiphDLL__ = OpenLibrary(#PB_Any, "gdiplus.dll")
If __gdiphDLL__ <> 0
__GdipCreateBitmapFromFile = GetFunction(__gdiphDLL__, "GdipCreateBitmapFromFile")
__GdipCreateFromHDC = GetFunction(__gdiphDLL__, "GdipCreateFromHDC")
__GdipDeleteGraphics = GetFunction(__gdiphDLL__, "GdipDeleteGraphics")
__GdipDisposeImage = GetFunction(__gdiphDLL__, "GdipDisposeImage")
__GdipDrawImageI = GetFunction(__gdiphDLL__, "GdipDrawImageI")
__GdipGetImageWidth = GetFunction(__gdiphDLL__, "GdipGetImageWidth")
__GdipGetImageHeight = GetFunction(__gdiphDLL__, "GdipGetImageHeight")
__GdipImageGetFrameCount = GetFunction(__gdiphDLL__, "GdipImageGetFrameCount")
__GdipImageGetFrameDimensionsList = GetFunction(__gdiphDLL__, "GdipImageGetFrameDimensionsList")
__GdipImageSelectActiveFrame = GetFunction(__gdiphDLL__, "GdipImageSelectActiveFrame")
__GdipLoadImageFromStream = GetFunction(__gdiphDLL__, "GdipLoadImageFromStream")
__GdipGetPropertyItemSize = GetFunction(__gdiphDLL__, "GdipGetPropertyItemSize")
__GdipGetPropertyItem = GetFunction(__gdiphDLL__, "GdipGetPropertyItem")
__GdiplusShutdown = GetFunction(__gdiphDLL__, "GdiplusShutdown")
__GdiplusStartup = GetFunction(__gdiphDLL__, "GdiplusStartup")
gdpsi\GdiPlusVersion = 1
__GdiplusStartup(@__gdipToken__, gdpsi, 0)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure gdiplus_End()
Shared __gdipToken__, __gdiphDLL__
__GdiplusShutdown(__gdipToken__)
CloseLibrary(__gdiphDLL__)
EndProcedure
Procedure __CreateStreamFromMem(Addr.i, Size.l)
Protected *mem = GlobalAlloc_(#GMEM_MOVEABLE, Size)
Protected *ptr
Protected Stream.IStream
If *mem
*ptr = GlobalLock_(*mem)
If *ptr
CopyMemory(Addr, *ptr, Size)
CreateStreamOnHGlobal_(*mem, #True, @Stream)
GlobalUnlock_(*mem)
EndIf
If Stream = 0: GlobalFree_(*mem) : EndIf
EndIf
ProcedureReturn Stream
EndProcedure
Procedure __AnimGifThread(*p.AnimGif_para)
Protected id, file.s, bitmap, graphics, guid.GUID, count, pause, semaphore, i, backcolor
Protected size, *mem, pos, hdc, type, image
id = *p\id
bitmap = *p\bitmap
pause = *p\pause
semaphore = *p\semaphore
backcolor = *p\backcolor
type = *p\type
FreeMemory(*p)
If bitmap
__GdipImageGetFrameDimensionsList(bitmap, @guid, 1)
__GdipImageGetFrameCount(bitmap, @guid, @count)
__GdipGetPropertyItemSize(bitmap, #PropertyTagFrameDelay, @size)
If size
If pause = #PB_Default
*mem = AllocateMemory(size)
If *mem
__GdipGetPropertyItem(bitmap, #PropertyTagFrameDelay, size, *mem)
Pos = PeekI(*mem + 8 + SizeOf(Integer))
EndIf
EndIf
EndIf
If count > 0
While TrySemaphore(semaphore) = 0
For i = 0 To count - 1
If TrySemaphore(semaphore) = 0
__GdipImageSelectActiveFrame(bitmap, @guid, i)
Select GadgetType(id)
Case #PB_GadgetType_Canvas
hdc = StartDrawing(CanvasOutput(id))
Box(0, 0, GadgetWidth(id), GadgetHeight(id), backcolor)
__GdipCreateFromHDC(hdc, @graphics)
DrawingMode(#PB_2DDrawing_AlphaBlend)
__GdipDrawImageI(graphics, bitmap, 0, 0)
StopDrawing()
Case #PB_GadgetType_ButtonImage
image = CreateImage(#PB_Any, GadgetWidth(id), GadgetHeight(id), 32)
hdc = StartDrawing(ImageOutput(image))
If backcolor = -1
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, GadgetWidth(id), GadgetHeight(id), 0)
Else
Box(0, 0, GadgetWidth(id), GadgetHeight(id), backcolor)
EndIf
__GdipCreateFromHDC(hdc, @graphics)
DrawingMode(#PB_2DDrawing_AlphaBlend)
__GdipDrawImageI(graphics, bitmap, 2, 2)
StopDrawing()
SetGadgetAttribute(id, #PB_Button_Image, ImageID(image))
FreeImage(image)
EndSelect
__GdipDeleteGraphics(graphics)
If pause = #PB_Default And pos <> 0
Delay(PeekA(pos + (i * SizeOf(Long))) * 10)
Else
Delay(pause)
EndIf
Else
Break 2
EndIf
Next
Wend
EndIf
__GdipDisposeImage(bitmap)
If *mem : FreeMemory(*mem) : EndIf
EndIf
EndProcedure
Procedure __AnimGIFCreate(id, x, y, file.s, *mem, memsize, type, backcolor, pause)
Protected bitmap, result, count, semaphore
Protected *para.AnimGif_para = AllocateMemory(SizeOf(AnimGif_para))
Protected w.l, h.l, thread, stream.IStream
If *para
If file <> ""
__GdipCreateBitmapFromFile(file, @bitmap)
ElseIf *mem <> 0
stream = __CreateStreamFromMem(*mem, memsize)
If stream
__GdipLoadImageFromStream(stream, @bitmap)
stream\Release()
EndIf
EndIf
If bitmap
__GdipGetImageWidth(bitmap, @w)
__GdipGetImageHeight(bitmap, @h)
Select type
Case #PB_GadgetType_Canvas
result = CanvasGadget(id, x, y, w, h)
Case #PB_GadgetType_ButtonImage
result = ButtonImageGadget(id, x, y, w + 4, h + 4, 0)
EndSelect
If id = #PB_Any
id = result
EndIf
semaphore = CreateSemaphore()
*para\id = id
*para\bitmap = bitmap
*para\pause = pause
*para\semaphore = semaphore
*para\backcolor = backcolor
*para\type = type
thread = CreateThread(@__AnimGifThread(), *para)
AddElement(AnimGIFThreads())
AnimGIFThreads()\id = id
AnimGIFThreads()\thread = thread
AnimGIFThreads()\semaphore = semaphore
ProcedureReturn result
EndIf
EndIf
EndProcedure
Macro AnimGIFGadget(id, x, y, file, backcolor = #White, pause = #PB_Default)
__AnimGIFCreate(id, x, y, file, 0, 0, #PB_GadgetType_Canvas, backcolor, pause)
EndMacro
Macro AnimGIFGadgetMem(id, x, y, mem, memsize, backcolor = #White, pause = #PB_Default)
__AnimGIFCreate(id, x, y, "", mem, memsize, #PB_GadgetType_Canvas, backcolor, pause)
EndMacro
Macro AnimGIFButton(id, x, y, file, backcolor = #PB_Any, pause = #PB_Default)
__AnimGIFCreate(id, x, y, file, 0, 0, #PB_GadgetType_ButtonImage, backcolor, pause)
EndMacro
Macro AnimGIFButtonMem(id, x, y, mem, memsize, backcolor = #PB_Any, pause = #PB_Default)
__AnimGIFCreate(id, x, y, "", mem, memsize, #PB_GadgetType_ButtonImage, backcolor, pause)
EndMacro
Procedure FreeAnimGIFGadget(id = #PB_Any)
ForEach AnimGIFThreads()
If id = #PB_Any
SignalSemaphore(AnimGIFThreads()\semaphore)
WaitThread(AnimGIFThreads()\thread, 5000)
FreeSemaphore(AnimGIFThreads()\semaphore)
FreeGadget(AnimGIFThreads()\id)
DeleteElement(AnimGIFThreads())
ElseIf AnimGIFThreads()\id = id
SignalSemaphore(AnimGIFThreads()\semaphore)
WaitThread(AnimGIFThreads()\thread, 5000)
FreeSemaphore(AnimGIFThreads()\semaphore)
FreeGadget(id)
DeleteElement(AnimGIFThreads())
Break
EndIf
Next
EndProcedure
Code: Select all
XIncludeFile "AnimGIFGadget.pbi"
InitNetwork()
Define GIF1.s = GetTemporaryDirectory() + "loading_circle.gif"
Define GIF2.s = GetTemporaryDirectory() + "ts-soft.gif"
If FileSize(GIF1) <= 0
ReceiveHTTPFile("http://dl.dropbox.com/u/3086026/loading_circle.gif", GIF1)
EndIf
If FileSize(GIF2) <= 0
ReceiveHTTPFile("http://dl.dropbox.com/u/3086026/ts-soft.gif", GIF2)
EndIf
Define AniGadget
If gdiplus_Init()
OpenWindow(0, #PB_Ignore, #PB_Ignore, 150, 230, "GIF example")
SetWindowColor(0, #White)
AnimGIFGadget(1, 25, 15, GIF1)
AniGadget = AnimGIFGadget(#PB_Any, 35, 130, GIF2)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
HideWindow(0, #True)
FreeAnimGIFGadget()
gdiplus_End()
Break
EndSelect
ForEver
EndIf
