Page 1 of 1

GIF Animation Control - Suggestions to Implement

Posted: Thu Jun 14, 2007 6:40 pm
by localmotion34
OK, so i have Haqibaba's GIF decoding code implemented to decode all frames of an animated GIF. So far, it has not failed on any GIF i have tested, which includes the GIF TheFool showed me.

Now, for an animation control, it will be a static control, and the idea is to just use STM_setimage when the timer set to the frame's delaytime expires. My current problems are:

1) each frame can have a different delay time. i need to figure a way to set a timer, and then execute the next frame on expiration.

2) multiple GIf animation controls should be able to be used without interfering with each other. so i guess using the window's user data and props are viable. but how do you store the ARRAY of images returned by the LoadGIFFrames(), and then reaccess them for each separate control.

The procedure to load GIF frames i have coded returns the hbitmaps in an array. I am thinking it should now be a structured array like:

Code: Select all

Structure ANGIF
  hBitmap.l
  TransparentColor.l
  delaytime.w
EndStructure

dim GIFarray.ANGIF(200)

LoadGIFFrames(filename.s, GIFarray.ANGIF(1))

GifStaticControl(id.l,x.l,y.l,width.l,height.l,GIFarray.ANGIF(1))
And in the callback procedure:

Code: Select all

Procedure GIFTimerProc(hwnd,msg,wParam,lParam)
  Select msg
    Case #WM_TIMER
      *ptr=GetProp_(hwnd,"gif") ; get the image array pointer
      frame=GetProp_(hwnd,"frame") ; get the frame index
      killtimer_(hwnd,200) ; stop the timer
      hBitmap=PeekL(*ptr+(frame*SizeOf(ANGIF))) ; get the bitmap.  move forward ANGIF size frame # of frames to get the next array element
      delaytime=PeekW(*ptr+(frame*SizeOf(ANGIF))+4) ; get the delaytime
      SendMessage_(hwnd,#STM_SETIMAGE,#IMAGE_BITMAP,hBitmap); set the new bitmap
      setprop_(hwnd,"frame",frame+1) ; increase the frame count
      settimer_(hwnd,200,delaytime*10,0) ; set the new timer
  EndSelect 
  ProcedureReturn CallWindowProc_(GetProp_(hwnd,"oldproc"),hwnd,msg,wParam,lParam)
EndProcedure

Procedure GifStaticControl(id.l,x.l,y.l,width.l,height.l,GIFarray.ANGIF(1))
  StaticCtl=ImageGadget(id,x.l,y.l,width.l,height,GIFarray(1)\hBitmap)
  If id=#PB_Any
    PBreturn=StaticCtl
    hwnd=GadgetID(StaticCtl)
  Else
    PBreturn=GadgetID(id)
    hwnd=GadgetID(id)
  EndIf
  setprop_(hwnd,"gif",@GIFarray.ANGIF()) ; set the pointer to the ARRAY of images
  setprop_(hwnd,"frame",0) ; set the frame index to 0
  settimer_(hwnd,200,GIFarray(1)\delaytime*10,0) ; set the timer with the first frame delay time
  setprop_(hwnd,"oldproc",SetWindowLong_(hwnd,#GWL_WNDPROC,@GIFTimerProc())) ; subclass
EndProcedure
This isnt working out too well. any suggestions or methods to make this work cleanly?

Posted: Thu Jun 14, 2007 6:49 pm
by ts-soft
You can use CreateGadget from PBOSL or the IncludeFile in the Tipps &
Tricks Sektion.

Posted: Thu Jun 14, 2007 6:53 pm
by localmotion34
ts-soft wrote:You can use CreateGadget from PBOSL or the IncludeFile in the Tipps &
Tricks Sektion.
Im talking more about the actual function of the control. Im asking for suggestions as to how i should IMPLEMENT storage of the image array, access of the image array, and the timer procedure.

my first attempt isnt very good. instead of wasting time creating messy code, im asking the people on here who can help CLEANLY configure this control, to set me in a direction that is logical and will work for all users who want to use this control.

Posted: Thu Jun 14, 2007 7:13 pm
by ts-soft
Sorry my bad english,

you should use the objectmanagement by pb. You can register a callback
(timercallback for example) for the control. So no conflicts in many
GifGadgets and easy to use.

That is what i mean with use CreateGadget