Page 1 of 1

Multimedia timer

Posted: Wed Jun 08, 2011 4:48 pm
by Psychophanta
Since time to time some threads go to limb, i have been in need to repost this code, which might help this guy "pb-user"( http://www.purebasic.fr/english/viewtop ... 13&t=46563 ):

Code: Select all

;***** Windows Multimedia Timer *****
;***** by Psychophanta April 2006 *****
;***************************************
Global m_hWnd.l,m_timerId.l,m_timerRes.l
Procedure.l minUnsigned(a.l,b.l)
  If a<0
    If b>=0 Or a>b:ProcedureReturn b:EndIf
  ElseIf b>=0 And a>b:ProcedureReturn b
  EndIf
  ProcedureReturn a
EndProcedure
Procedure.l maxUnsigned(a.l,b.l)
  If a<0
    If b>=0 Or a>b:ProcedureReturn a:EndIf
  ElseIf b>=0 And a>b:ProcedureReturn a
  EndIf
  ProcedureReturn b
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// mmTimer CALLBACK handler
;// From the trace Data, I think mmTimer Callback is driven by Semaphore With counting.
;// And it won't overrun. In other words, the Callback function won't be re-entried.
;/////////////////////////////////////////////////////////////////////////////////////////////
Global myDD.IDirectDraw ; Create a DirectDraw object
Global ScanLine.l
DirectDrawCreate_(0,@myDD,0) 
Procedure CALLBACK_mmTimerProc(id.l,msg.l,dwUser.l,dw1.l,dw2.l)
  Protected message.l=myDD\GetScanLine(@ScanLine)
;   If Scanline<100:Beep_(300,2):EndIf
  Beep_(300,5)
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// start mmTimer
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b StartTimer(period.l,oneShot.b=0,resolution.l=0)
  Protected tc.TIMECAPS
  If timeGetDevCaps_(@tc,SizeOf(TIMECAPS))=#TIMERR_NOERROR
    m_timerRes.l=minUnsigned(maxUnsigned(tc\wPeriodMin,resolution),tc\wPeriodMax)
    If timeBeginPeriod_(m_timerRes)<>#TIMERR_NOERROR:ProcedureReturn 0:EndIf
  Else 
    ProcedureReturn 0
  EndIf
  If oneShot:oneShot=#TIME_ONESHOT:Else:oneShot=#TIME_PERIODIC:EndIf
  result.l=timeSetEvent_(period,m_timerRes,@CALLBACK_mmTimerProc(),0,oneShot);CALLBACK_EVENT_SET
  If result.l
    m_timerId=result.l
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// stop mmTimer
;// could be modified in XP with TIME_KILL_SYNCHRONOUS
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b StopTimer(bEndTime.b=0)
  result.l=timeKillEvent_(m_timerId)
  If result.l=#TIMERR_NOERROR
    m_timerId=0
    If bEndTime
      For i.b=0 To 9
        Sleep_(10);                          //TIME_KILL_SYNCHRONOUS
      Next
    EndIf
  EndIf
  If m_timerRes
    timeEndPeriod_(m_timerRes)
    m_timerRes=0
  EndIf
  If result.l=#TIMERR_NOERROR:ProcedureReturn 1:EndIf
  ProcedureReturn 0
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// Resume mmTimer
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b SafeStartTimer(period.l=2,oneShot.b=0,resolution.l=0)
  If StartTimer(period,oneShot,resolution)=0
   ; PostMessage_(m_hWnd,#WM_CLOSE,0,0)
    ProcedureReturn 0
  EndIf
  ProcedureReturn 1
EndProcedure
;-MAIN:
Enumeration
#window0=0
#Button_Start=0
#OneShot
#PeriodText
#PeriodBar
EndEnumeration
Procedure.l Open_window0()
  res.l=OpenWindow(#window0,0,0,155,100,"MM timer test",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
  ButtonGadget(#Button_Start,5,5,145,50,"Start timer",#PB_Button_Toggle)
  CheckBoxGadget(#OneShot,5,60,150,15,"One shot")
  TrackBarGadget(#PeriodBar,60,76,100,30,0,1000):SetGadgetState(#PeriodBar,20)
  TextGadget(#PeriodText,2,80,58,15,"Period "+Str(GetGadgetState(#PeriodBar)))
  ProcedureReturn res
EndProcedure
Macro Interact
  Select EventID.l
  Case #PB_Event_Gadget
    Select EventGadget()
    Case #Button_Start
      If GetGadgetText(#Button_Start)="Start timer"
        If SafeStartTimer(GetGadgetState(#PeriodBar),GetGadgetState(#OneShot))
          SetGadgetText(#Button_Start,"Stop timer")
        Else
          SetGadgetState(#Button_Start,0):SetGadgetText(#Button_Start,"Start timer")
        EndIf
      Else
        SetGadgetText(#Button_Start,"Start timer")
        StopTimer()
      EndIf
    Case #PeriodBar
      period.l=GetGadgetState(#PeriodBar)
      SetGadgetText(#PeriodText,"Period "+Str(period))
      If GetGadgetText(#Button_Start)="Stop timer"
        StopTimer():Delay(1)
        If SafeStartTimer(period,GetGadgetState(#OneShot))=0
          SetGadgetState(#Button_Start,0):SetGadgetText(#Button_Start,"Start timer")
        EndIf
      EndIf
    Case #OneShot
      If GetGadgetText(#Button_Start)="Stop timer"
        StopTimer():Delay(1)
        If SafeStartTimer(period,GetGadgetState(#OneShot))=0
          SetGadgetState(#Button_Start,0):SetGadgetText(#Button_Start,"Start timer")
        EndIf
      EndIf
    EndSelect
  EndSelect
EndMacro
m_hWnd=Open_window0()
If m_hWnd=0:End:EndIf
Repeat
  EventID.l=WaitWindowEvent()
  Interact
  Delay(1)
Until EventID=#PB_Event_CloseWindow
StopTimer()
End