163 lines
4.0 KiB
C#
163 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
using System.Diagnostics;
|
|
using DirectShowLib;
|
|
|
|
namespace FDK
|
|
{
|
|
public class CTimer : CTimerBase
|
|
{
|
|
public enum E種別
|
|
{
|
|
Unknown = -1,
|
|
PerformanceCounter = 0,
|
|
MultiMedia = 1,
|
|
GetTickCount = 2,
|
|
}
|
|
public E種別 eタイマ種別
|
|
{
|
|
get;
|
|
protected set;
|
|
}
|
|
|
|
|
|
public override long nシステム時刻ms
|
|
{
|
|
get
|
|
{
|
|
switch( this.eタイマ種別 )
|
|
{
|
|
case E種別.PerformanceCounter:
|
|
{
|
|
double num = 0.0;
|
|
if( this.n現在の周波数 != 0L )
|
|
{
|
|
long x = 0L;
|
|
QueryPerformanceCounter( ref x );
|
|
num = ( (double) x ) / ( ( (double) this.n現在の周波数 ) / 1000.0 );
|
|
}
|
|
return (long) num;
|
|
}
|
|
case E種別.MultiMedia:
|
|
return (long) timeGetTime();
|
|
|
|
case E種別.GetTickCount:
|
|
return (long) Environment.TickCount;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public CTimer( E種別 eタイマ種別 )
|
|
:base()
|
|
{
|
|
this.eタイマ種別 = eタイマ種別;
|
|
|
|
if( n参照カウント[ (int) this.eタイマ種別 ] == 0 )
|
|
{
|
|
switch( this.eタイマ種別 )
|
|
{
|
|
case E種別.PerformanceCounter:
|
|
if( !this.b確認と設定_PerformanceCounter() && !this.b確認と設定_MultiMedia() )
|
|
this.b確認と設定_GetTickCount();
|
|
break;
|
|
|
|
case E種別.MultiMedia:
|
|
if( !this.b確認と設定_MultiMedia() && !this.b確認と設定_PerformanceCounter() )
|
|
this.b確認と設定_GetTickCount();
|
|
break;
|
|
|
|
case E種別.GetTickCount:
|
|
this.b確認と設定_GetTickCount();
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentException( string.Format( "未知のタイマ種別です。[{0}]", this.eタイマ種別 ) );
|
|
}
|
|
}
|
|
|
|
base.tリセット();
|
|
|
|
n参照カウント[ (int) this.eタイマ種別 ]++;
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
if( this.eタイマ種別 == E種別.Unknown )
|
|
return;
|
|
|
|
int type = (int) this.eタイマ種別;
|
|
|
|
n参照カウント[ type ] = Math.Max( n参照カウント[ type ] - 1, 0 );
|
|
|
|
if( n参照カウント[ type ] == 0 )
|
|
{
|
|
if( this.eタイマ種別 == E種別.MultiMedia )
|
|
timeEndPeriod( this.timeCaps.wPeriodMin );
|
|
}
|
|
|
|
this.eタイマ種別 = E種別.Unknown;
|
|
}
|
|
|
|
#region [ protected ]
|
|
//-----------------
|
|
protected long n現在の周波数;
|
|
protected static int[] n参照カウント = new int[ 3 ];
|
|
protected TimeCaps timeCaps;
|
|
|
|
protected bool b確認と設定_GetTickCount()
|
|
{
|
|
this.eタイマ種別 = E種別.GetTickCount;
|
|
return true;
|
|
}
|
|
protected bool b確認と設定_MultiMedia()
|
|
{
|
|
this.timeCaps = new TimeCaps();
|
|
if( ( timeGetDevCaps( out this.timeCaps, (uint) Marshal.SizeOf( typeof( TimeCaps ) ) ) == 0 ) && ( this.timeCaps.wPeriodMin < 10 ) )
|
|
{
|
|
this.eタイマ種別 = E種別.MultiMedia;
|
|
timeBeginPeriod( this.timeCaps.wPeriodMin );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
protected bool b確認と設定_PerformanceCounter()
|
|
{
|
|
if( QueryPerformanceFrequency( ref this.n現在の周波数 ) != 0 )
|
|
{
|
|
this.eタイマ種別 = E種別.PerformanceCounter;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
//-----------------
|
|
#endregion
|
|
|
|
#region [ DllImport ]
|
|
//-----------------
|
|
[DllImport( "kernel32.dll" )]
|
|
protected static extern short QueryPerformanceCounter( ref long x );
|
|
[DllImport( "kernel32.dll" )]
|
|
protected static extern short QueryPerformanceFrequency( ref long x );
|
|
[DllImport( "winmm.dll" )]
|
|
protected static extern void timeBeginPeriod( uint x );
|
|
[DllImport( "winmm.dll" )]
|
|
protected static extern void timeEndPeriod( uint x );
|
|
[DllImport( "winmm.dll" )]
|
|
protected static extern uint timeGetDevCaps( out TimeCaps timeCaps, uint size );
|
|
[DllImport( "winmm.dll" )]
|
|
protected static extern uint timeGetTime();
|
|
|
|
[StructLayout( LayoutKind.Sequential )]
|
|
protected struct TimeCaps
|
|
{
|
|
public uint wPeriodMin;
|
|
public uint wPeriodMax;
|
|
}
|
|
//-----------------
|
|
#endregion
|
|
}
|
|
}
|