You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.9 KiB
135 lines
3.9 KiB
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace DataService
|
|
{
|
|
public class MediaTimer : IDisposable
|
|
{
|
|
//Lib API declarations
|
|
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
|
|
static extern uint timeSetEvent(uint uDelay, uint uResolution, TimerCallback lpTimeProc, UIntPtr dwUser,uint fuEvent);
|
|
|
|
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
|
|
static extern uint timeKillEvent(uint uTimerID);
|
|
|
|
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
|
|
static extern uint timeGetTime();
|
|
|
|
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
|
|
static extern uint timeBeginPeriod(uint uPeriod);
|
|
|
|
[DllImport("Winmm.dll", CharSet = CharSet.Auto)]
|
|
static extern uint timeEndPeriod(uint uPeriod);
|
|
|
|
//Timer type definitions
|
|
[Flags]
|
|
public enum fuEvent : uint
|
|
{
|
|
TIME_ONESHOT = 0, //Event occurs once, after uDelay milliseconds.
|
|
TIME_PERIODIC = 1,
|
|
TIME_CALLBACK_FUNCTION = 0x0000, /* callback is function */
|
|
TIME_CALLBACK_EVENT_SET = 0x0010, /* callback is event - use SetEvent */
|
|
TIME_CALLBACK_EVENT_PULSE = 0x0020 /* callback is event - use PulseEvent */
|
|
}
|
|
|
|
//Delegate definition for the API callback
|
|
delegate void TimerCallback(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2);
|
|
|
|
//IDisposable code
|
|
private bool disposed = false;
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private void Dispose(bool disposing)
|
|
{
|
|
if (!this.disposed)
|
|
{
|
|
if (disposing)
|
|
{
|
|
Stop();
|
|
}
|
|
}
|
|
disposed = true;
|
|
}
|
|
|
|
~MediaTimer()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The current timer instance ID
|
|
/// </summary>
|
|
uint id = 0;
|
|
|
|
/// <summary>
|
|
/// The callback used by the the API
|
|
/// </summary>
|
|
TimerCallback thisCallBack;
|
|
|
|
/// <summary>
|
|
/// The timer elapsed event
|
|
/// </summary>
|
|
public event EventHandler Timer;
|
|
|
|
public MediaTimer()
|
|
{
|
|
//Initialize the API callback
|
|
thisCallBack = CallBackFunc;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop the current timer instance (if any)
|
|
/// </summary>
|
|
public void Stop()
|
|
{
|
|
lock (this)
|
|
{
|
|
if (id != 0)
|
|
{
|
|
timeKillEvent(id);
|
|
//Debug.WriteLine("MMTimer " + id.ToString() + " stopped");
|
|
id = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start a timer instance
|
|
/// </summary>
|
|
/// <param name="ms">Timer interval in milliseconds</param>
|
|
/// <param name="repeat">If true sets a repetitive event, otherwise sets a one-shot</param>
|
|
public void Start(uint ms, bool repeat)
|
|
{
|
|
//Kill any existing timer
|
|
Stop();
|
|
|
|
//Set the timer type flags
|
|
fuEvent f = fuEvent.TIME_CALLBACK_FUNCTION | (repeat ? fuEvent.TIME_PERIODIC : fuEvent.TIME_ONESHOT);
|
|
|
|
lock (this)
|
|
{
|
|
id = timeSetEvent(ms, 0, thisCallBack, UIntPtr.Zero, (uint)f);
|
|
if (id == 0)
|
|
{
|
|
throw new Exception("timeSetEvent error");
|
|
}
|
|
//Debug.WriteLine("MMTimer " + id.ToString() + " started");
|
|
}
|
|
}
|
|
|
|
void CallBackFunc(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2)
|
|
{
|
|
//Callback from the MMTimer API that fires the Timer event. Note we are in a different thread here
|
|
if (Timer != null)
|
|
{
|
|
Timer(this, new EventArgs());
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|