
Un petit exemple pour afficher des GIFs issus d'un fichier, de ressources ou encore inclus dans l'exécutable, dans des ImageGadgets.
Le code peut être compilé en 64 ou 32 bits sans problème
La boucle des événement est un peu lourde, mais ce n'est que pour la gestion des boutons pour l'exemple.
Les fichiers GIF et le fichier de ressources sont récupérable ici: http://www.mediafire.com/?n5ynhfwxuwly546
Code : Tout sélectionner
EnableExplicit
Import "TestGIF.res": EndImport
Structure GDIPLUSSTARTUPINPUT
GdiPlusVersion.l
*DebugEventCallback.DebugEventProc
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
Structure GARBAGE
Stream.IStream
*Memory
hMemGlobal.i
*Bitmap
*RawPropItem
EndStructure
Structure GIFPARAMETERS
Gadget.l; Le numéro du l'ImageGadget dans lequel le GIF doit être affiché
From.l; #FILE, #MEMORY ou #RESOURCE si le GIF est un fichier externe, inclus dans l'exe ou dans les ressources
FileName.s; Le nom du fichier GIF si le GIF est un fichier externe
StartAddress.i; L'adresse de début du GIF s'il est inclus dans l'exe
Length.l; La longueur du GIF s'il est inclus dans l'exe
ResType.l; Le type de la ressource si le GIF est inclus aux ressources
ResName.s; Le nom de la ressource si le GIF est inclus aux ressources
ResLang.l; Le langage de la ressource si le GIF est inclus aux ressources
SeveralFrames.b; (Réservé) #True si le GIF comporte plusieurs frames
Thread.l; (Réservé) Le numéro du Thread affecté
ThreadPaused.b; (Réservé) #True si le GIF est en pause
Garb.GARBAGE; (Réservé) Libération de la mémoire
EndStructure
Enumeration; Type du GIF à afficher
#FILE
#MEMORY
#RESOURCE
EndEnumeration
Enumeration; Fenêtre et gadgets
#Window_0
#Image_1
#Image_4
#Image_2
#Image_3
#Button_1
#Button_2
#Button_3
#Button_4
#Button_5
#Button_6
#Button_7
#Button_8
#Image_Image_1
#Image_Image_2
#Image_Image_3
#Image_Image_4
EndEnumeration
;{- Prototypes
Prototype PFNGdiplusStartup(*token, *input, *output)
Prototype PFNGdiplusShutdown(*token)
Prototype PFNGdipDisposeImage(*image)
Prototype PFNGdipLoadImageFromFile(filename.p-unicode, *image)
Prototype PFNGdipGetImageDimension(*image, *width.f, *height.f)
Prototype PFNGdipImageGetFrameDimensionsCount(*image, count.l)
Prototype PFNGdipImageGetFrameDimensionsList(*image, *dimensionID, count.l)
Prototype PFNGdipImageGetFrameCount(*image, *dimensionID, *count)
Prototype PFNGdipCreateHBITMAPFromBitmap(*image, *hBitmap, iARGB.l)
Prototype PFNGdipCreateBitmapFromStream(*stream, *image)
Prototype PFNGdipImageSelectActiveFrame(*image, *dimensionID, frameIndex.l)
Prototype PFNGdipGetPropertyItemSize(*image, *propId, size.l)
Prototype PFNGdipGetPropertyItem(*image, propId.l, propSize.l, *Buffer)
Prototype PFNGdipBitmapGetPixel(*bitmap, x.l, y.l, *color)
;}
;{- Déclaration Pointeurs de Fonction GDIplus
Global GdiplusStartup.PFNGdiplusStartup
Global GdiplusShutdown.PFNGdiplusShutdown
Global GdipDisposeImage.PFNGdipDisposeImage
Global GdipLoadImageFromFile.PFNGdipLoadImageFromFile
Global GdipGetImageDimension.PFNGdipGetImageDimension
Global GdipImageGetFrameDimensionsCount.PFNGdipImageGetFrameDimensionsCount
Global GdipImageGetFrameDimensionsList.PFNGdipImageGetFrameDimensionsList
Global GdipImageGetFrameCount.PFNGdipImageGetFrameCount
Global GdipCreateHBITMAPFromBitmap.PFNGdipCreateHBITMAPFromBitmap
Global GdipCreateBitmapFromStream.PFNGdipCreateBitmapFromStream
Global GdipImageSelectActiveFrame.PFNGdipImageSelectActiveFrame
Global GdipGetPropertyItemSize.PFNGdipGetPropertyItemSize
Global GdipGetPropertyItem.PFNGdipGetPropertyItem
Global GdipBitmapGetPixel.PFNGdipBitmapGetPixel
;}
#PropertyTagFrameDelay = $5100
Global hGdip_DLL ; Handle de la DLL GDIplus
;{- Récupération des adresses des Fonctions GDIplus
hGdip_DLL = OpenLibrary(#PB_Any, "GDIPLUS.DLL")
If hGdip_DLL
GdiplusStartup = GetFunction(hGdip_DLL, "GdiplusStartup")
GdiplusShutdown = GetFunction(hGdip_DLL, "GdiplusShutdown")
GdipDisposeImage = GetFunction(hGdip_DLL, "GdipDisposeImage")
GdipLoadImageFromFile = GetFunction(hGdip_DLL, "GdipLoadImageFromFile")
GdipGetImageDimension = GetFunction(hGdip_DLL, "GdipGetImageDimension")
GdipImageGetFrameDimensionsCount = GetFunction(hGdip_DLL, "GdipImageGetFrameDimensionsCount")
GdipImageGetFrameDimensionsList = GetFunction(hGdip_DLL, "GdipImageGetFrameDimensionsList")
GdipImageGetFrameCount = GetFunction(hGdip_DLL, "GdipImageGetFrameCount")
GdipCreateHBITMAPFromBitmap = GetFunction(hGdip_DLL, "GdipCreateHBITMAPFromBitmap")
GdipCreateBitmapFromStream = GetFunction(hGdip_DLL, "GdipCreateBitmapFromStream")
GdipImageSelectActiveFrame = GetFunction(hGdip_DLL, "GdipImageSelectActiveFrame")
GdipGetPropertyItemSize = GetFunction(hGdip_DLL, "GdipGetPropertyItemSize")
GdipGetPropertyItem = GetFunction(hGdip_DLL, "GdipGetPropertyItem")
GdipBitmapGetPixel = GetFunction(hGdip_DLL, "GdipBitmapGetPixel")
EndIf
;}
Procedure GIFToImageGadget(*Gif.GIFPARAMETERS)
Protected FrameDimensionsCount.l
Protected Guid.GUID
Protected FrameCount.l
Protected hGIFBitmap.i
Protected ARGB.l = $FF000000
Protected PropertyItemSize.l
Protected CurrentFrame.l
Protected Time.l
Protected TimingTable.i
Protected hModule.i
Protected hResInfo.i
Protected SizeOfResource.l
Protected hResData.i
Protected *Resource
If *Gif\From = #RESOURCE
hModule = GetModuleHandle_(#Null)
hResInfo = FindResourceEx_(hModule, *Gif\ResType, *Gif\ResName, *Gif\ResLang)
SizeOfResource = SizeofResource_(hModule, hResInfo)
hResData = LoadResource_(hModule, hResInfo)
*Resource = LockResource_(hResData)
FreeResource_(hResData)
FreeLibrary_(hModule)
*Gif\Length = SizeOfResource
*Gif\StartAddress = *Resource
EndIf
If *Gif\From = #FILE
GdipLoadImageFromFile(*Gif\FileName, @*Gif\Garb\Bitmap)
Else
*Gif\Garb\hMemGlobal = GlobalAlloc_(#GHND, *Gif\Length)
*Gif\Garb\Memory = GlobalLock_(*Gif\Garb\hMemGlobal)
CopyMemory(*Gif\StartAddress, *Gif\Garb\Memory, *Gif\Length)
CreateStreamOnHGlobal_(*Gif\Garb\Memory, #True, @*Gif\Garb\Stream)
GdipCreateBitmapFromStream(*Gif\Garb\Stream, @*Gif\Garb\Bitmap)
EndIf
; Gets the number of frame dimensions in this Image object.
GdipImageGetFrameDimensionsCount(*Gif\Garb\Bitmap, @FrameDimensionsCount)
; Gets the identifiers for the frame dimensions of this Image object.
GdipImageGetFrameDimensionsList(*Gif\Garb\Bitmap, @Guid, FrameDimensionsCount)
; Gets the number of frames in a specified dimension of this Image object.
GdipImageGetFrameCount(*Gif\Garb\Bitmap, @Guid, @FrameCount)
If FrameCount = 1
*Gif\SeveralFrames = #False
GdipCreateHBITMAPFromBitmap(*Gif\Garb\Bitmap, @hGIFBitmap, ARGB)
SetGadgetState(*Gif\Gadget, hGIFBitmap)
DeleteObject_(hGIFBitmap)
DeleteObject_(*Gif\Garb\Bitmap)
GlobalUnlock_(*Gif\Garb\Memory)
GlobalFree_(*Gif\Garb\hMemGlobal)
ProcedureReturn
Else
*Gif\SeveralFrames = #True
; Get size of PropertyTagFrameDelay
GdipGetPropertyItemSize(*Gif\Garb\Bitmap, #PropertyTagFrameDelay, @PropertyItemSize)
*Gif\Garb\RawPropItem = AllocateMemory(PropertyItemSize)
GdipGetPropertyItem(*Gif\Garb\Bitmap, #PropertyTagFrameDelay, PropertyItemSize, *Gif\Garb\RawPropItem)
GdipCreateHBITMAPFromBitmap(*Gif\Garb\Bitmap, @hGIFBitmap, ARGB)
CurrentFrame = 1
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
TimingTable = *Gif\Garb\RawPropItem + 24
CompilerElse
TimingTable = *Gif\Garb\RawPropItem + 16
CompilerEndIf
Repeat
; Change animation frame
GdipImageSelectActiveFrame(*Gif\Garb\Bitmap, @Guid, CurrentFrame)
Time = PeekL(TimingTable + 4 * (CurrentFrame - 1)) * 10
; Corrections
If Not Time: Time = 130: EndIf ; interpreting 0 as 130 ms
If Time < 50: Time = 50: EndIf ; will slow it down to prevent more extensive cpu usage
GdipCreateHBITMAPFromBitmap(*Gif\Garb\Bitmap, @hGIFBitmap, ARGB)
SetGadgetState(*Gif\Gadget, hGIFBitmap)
Delay(Time)
DeleteObject_(hGIFBitmap)
CurrentFrame = CurrentFrame + 1
If CurrentFrame > FrameCount : CurrentFrame = 1 : EndIf
ForEver
EndIf
EndProcedure
Procedure GIFStart(*Gif.GIFPARAMETERS)
If IsThread(*Gif\Thread) = 0
*Gif\ThreadPaused = #False
*Gif\Thread = CreateThread(@GIFToImageGadget(), *Gif)
EndIf
EndProcedure
Procedure GIFPause(*Gif.GIFPARAMETERS)
If *Gif\SeveralFrames And IsThread(*Gif\Thread) And *Gif\ThreadPaused = #False
*Gif\ThreadPaused = #True
PauseThread(*Gif\Thread)
EndIf
EndProcedure
Procedure GIFResume(*Gif.GIFPARAMETERS)
If *Gif\SeveralFrames And IsThread(*Gif\Thread) And *Gif\ThreadPaused = #True
*Gif\ThreadPaused = #False
ResumeThread(*Gif\Thread)
EndIf
EndProcedure
Procedure GIFStop(*Gif.GIFPARAMETERS)
If *Gif\SeveralFrames And IsThread(*Gif\Thread)
KillThread(*Gif\Thread)
*Gif\ThreadPaused = #False
If *Gif\From = #MEMORY Or *Gif\From = #RESOURCE
*Gif\Garb\Stream\Release()
EndIf
GlobalUnlock_(*Gif\Garb\Memory)
GlobalFree_(*Gif\Garb\hMemGlobal)
DeleteObject_(*Gif\Garb\Bitmap)
FreeMemory(*Gif\Garb\RawPropItem)
*Gif\Thread = 0
SetGadgetState(*Gif\Gadget, 0)
Else
SetGadgetState(*Gif\Gadget, 0)
EndIf
EndProcedure
Define GdiplusStartupInput.GDIPLUSSTARTUPINPUT
Define Token.l
Define Gif1.GIFPARAMETERS
Define Gif2.GIFPARAMETERS
Define Gif3.GIFPARAMETERS
Define Gif4.GIFPARAMETERS
Define Event.l
Define Quit.b
; Initailise GDIplus
GdiplusStartupInput\GdiPlusVersion = 1
GdiplusStartup(@Token, @GdiplusStartupInput, #NUL)
OpenWindow(#Window_0, 505, 196, 381, 370, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
ImageGadget(#Image_1, 20, 20, 170, 160, 0)
ImageGadget(#Image_2, 220, 40, 114, 121, 0)
ImageGadget(#Image_3, 70, 230, 80, 90, 0)
ImageGadget(#Image_4, 230, 220, 100, 105, 0)
ButtonGadget(#Button_1, 30, 190, 70, 20, "Stop")
ButtonGadget(#Button_2, 110, 190, 70, 20, "Pause")
ButtonGadget(#Button_3, 200, 190, 70, 20, "Stop")
ButtonGadget(#Button_4, 280, 190, 70, 20, "Pause")
ButtonGadget(#Button_5, 30, 330, 70, 20, "Stop")
ButtonGadget(#Button_6, 110, 330, 70, 20, "Pause")
ButtonGadget(#Button_7, 210, 330, 70, 20, "Stop")
ButtonGadget(#Button_8, 290, 330, 70, 20, "Pause")
With Gif1
\Gadget = #Image_1
\StartAddress = ?StartGIF
\From = #MEMORY
\Length = ?EndGIF - ?StartGIF
EndWith
GIFStart(Gif1)
With Gif2
\Gadget = #Image_2
\From = #FILE
\FileName = "2.gif"
EndWith
GIFStart(Gif2)
With Gif3
\Gadget = #Image_3
\From = #RESOURCE
\ResType = #RT_RCDATA
\ResName = "RCDATA_0"
\ResLang = 0
EndWith
GIFStart(Gif3)
With Gif4
\Gadget = #Image_4
\From = #FILE
\FileName = "4.gif"
EndWith
GIFStart(Gif4)
;{- Evénements
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #Button_1
If IsThread(Gif1\Thread)
GIFStop(Gif1): SetGadgetText(#Button_1, "Start"): DisableGadget(#Button_2, 1)
Else
GIFStart(Gif1): SetGadgetText(#Button_1, "Stop"): DisableGadget(#Button_2, 0): SetGadgetText(#Button_2, "Pause")
EndIf
Case #Button_2
If IsThread(Gif1\Thread) And Gif1\ThreadPaused = #False
GIFPause(Gif1): SetGadgetText(#Button_2, "Resume")
ElseIf IsThread(Gif1\Thread) And Gif1\ThreadPaused = #True
GIFResume(Gif1): SetGadgetText(#Button_2, "Pause")
EndIf
Case #Button_3
If IsThread(Gif2\Thread)
GIFStop(Gif2): SetGadgetText(#Button_3, "Start"): DisableGadget(#Button_4, 1)
Else
GIFStart(Gif2): SetGadgetText(#Button_3, "Stop"): DisableGadget(#Button_4, 0): SetGadgetText(#Button_4, "Pause")
EndIf
Case #Button_4
If IsThread(Gif2\Thread) And Gif2\ThreadPaused = #False
GIFPause(Gif2): SetGadgetText(#Button_4, "Resume")
ElseIf IsThread(Gif2\Thread) And Gif2\ThreadPaused = #True
GIFResume(Gif2): SetGadgetText(#Button_4, "Pause")
EndIf
Case #Button_5
If IsThread(Gif3\Thread)
GIFStop(Gif3): SetGadgetText(#Button_5, "Start"): DisableGadget(#Button_6, 1)
Else
GIFStart(Gif3): SetGadgetText(#Button_5, "Stop"): DisableGadget(#Button_6, 0): SetGadgetText(#Button_6, "Pause")
EndIf
Case #Button_6
If IsThread(Gif3\Thread) And Gif3\ThreadPaused = #False
GIFPause(Gif3): SetGadgetText(#Button_6, "Resume")
ElseIf IsThread(Gif3\Thread) And Gif3\ThreadPaused = #True
GIFResume(Gif3): SetGadgetText(#Button_6, "Pause")
EndIf
Case #Button_7
If IsThread(Gif4\Thread)
GIFStop(Gif4): SetGadgetText(#Button_7, "Start"): DisableGadget(#Button_8, 1)
Else
GIFStart(Gif4): SetGadgetText(#Button_7, "Stop"): DisableGadget(#Button_8, 0): SetGadgetText(#Button_8, "Pause")
EndIf
Case #Button_8
If IsThread(Gif4\Thread) And Gif4\ThreadPaused = #False
GIFPause(Gif4): SetGadgetText(#Button_8, "Resume")
ElseIf IsThread(Gif4\Thread) And Gif4\ThreadPaused = #True
GIFResume(Gif4): SetGadgetText(#Button_8, "Pause")
EndIf
EndSelect
Case #PB_Event_CloseWindow
GIFStop(Gif1): GIFStop(Gif2): : GIFStop(Gif3): GIFStop(Gif4)
GdiplusShutdown(Token)
CloseLibrary(hGdip_DLL)
Quit = 1
EndSelect
Until Quit = 1
;}
End
DataSection
StartGIF:
IncludeBinary "1.gif"
EndGIF:
EndDataSection