--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+using SharpDX;
+using SharpDX.DirectInput;
+
+using SlimDXKey = SlimDX.DirectInput.Key;
+using SharpDXKey = SharpDX.DirectInput.Key;
+
+namespace FDK
+{
+ public class CInputKeyboard : IInputDevice, IDisposable
+ {
+ // コンストラクタ
+
+ public CInputKeyboard( IntPtr hWnd, DirectInput directInput )
+ {
+ this.e入力デバイス種別 = E入力デバイス種別.Keyboard;
+ this.GUID = "";
+ this.ID = 0;
+ try
+ {
+ this.devKeyboard = new Keyboard( directInput );
+ this.devKeyboard.SetCooperativeLevel( hWnd, CooperativeLevel.NoWinKey | CooperativeLevel.Foreground | CooperativeLevel.NonExclusive );
+ this.devKeyboard.Properties.BufferSize = 32;
+ Trace.TraceInformation( this.devKeyboard.Information.ProductName + " を生成しました。" );
+ }
+ catch
+ {
+ if( this.devKeyboard != null )
+ {
+ this.devKeyboard.Dispose();
+ this.devKeyboard = null;
+ }
+ Trace.TraceWarning( "Keyboard デバイスの生成に失敗しました。" );
+ throw;
+ }
+ try
+ {
+ this.devKeyboard.Acquire();
+ }
+ catch
+ {
+ }
+
+ for( int i = 0; i < this.bKeyState.Length; i++ )
+ this.bKeyState[ i ] = false;
+
+ //this.timer = new CTimer( CTimer.E種別.MultiMedia );
+ this.list入力イベント = new List<STInputEvent>( 32 );
+ // this.ct = new CTimer( CTimer.E種別.PerformanceCounter );
+ }
+
+
+ // メソッド
+
+ #region [ IInputDevice 実装 ]
+ //-----------------
+ public E入力デバイス種別 e入力デバイス種別 { get; private set; }
+ public string GUID { get; private set; }
+ public int ID { get; private set; }
+ public List<STInputEvent> list入力イベント { get; private set; }
+
+ public void tポーリング( bool bWindowがアクティブ中, bool bバッファ入力を使用する )
+ {
+ for ( int i = 0; i < 256; i++ )
+ {
+ this.bKeyPushDown[ i ] = false;
+ this.bKeyPullUp[ i ] = false;
+ }
+
+ if ( bWindowがアクティブ中 && ( this.devKeyboard != null ) )
+ {
+ this.devKeyboard.Acquire();
+ this.devKeyboard.Poll();
+
+ //this.list入力イベント = new List<STInputEvent>( 32 );
+ this.list入力イベント.Clear(); // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();
+ int posEnter = -1;
+ //string d = DateTime.Now.ToString( "yyyy/MM/dd HH:mm:ss.ffff" );
+
+ if ( bバッファ入力を使用する )
+ {
+ #region [ a.バッファ入力 ]
+ //-----------------------------
+ var bufferedData = this.devKeyboard.GetBufferedData();
+ //if ( Result.Last.IsSuccess && bufferedData != null )
+ {
+ foreach( KeyboardUpdate data in bufferedData )
+ {
+ // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
+ var key = DeviceConstantConverter.DIKtoKey( data.Key );
+ if( SlimDXKey.Unknown == key )
+ continue; // 未対応キーは無視。
+
+ //foreach ( Key key in data.PressedKeys )
+ if( data.IsPressed )
+ {
+ // #23708 2016.3.19 yyagi; Even if we remove ALT+ENTER key input by SuppressKeyPress = true in Form,
+ // it doesn't affect to DirectInput (ALT+ENTER does not remove)
+ // So we ignore ENTER input in ALT+ENTER combination here.
+ // Note: ENTER will be alived if you keyup ALT after ALT+ENTER.
+ if( key != SlimDXKey.Return || ( bKeyState[ (int) SlimDXKey.LeftAlt ] == false && bKeyState[ (int) SlimDXKey.RightAlt ] == false ) )
+ {
+ STInputEvent item = new STInputEvent() {
+ nKey = (int) key,
+ b押された = true,
+ b離された = false,
+ nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),
+ nVelocity = CInput管理.n通常音量
+ };
+ this.list入力イベント.Add( item );
+
+ this.bKeyState[ (int) key ] = true;
+ this.bKeyPushDown[ (int) key ] = true;
+ }
+ //if ( item.nKey == (int) SlimDXKey.Space )
+ //{
+ // Trace.TraceInformation( "FDK(buffered): SPACE key registered. " + ct.nシステム時刻 );
+ //}
+ }
+ //foreach ( Key key in data.ReleasedKeys )
+ if( data.IsReleased )
+ {
+ STInputEvent item = new STInputEvent() {
+ nKey = (int) key,
+ b押された = false,
+ b離された = true,
+ nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),
+ nVelocity = CInput管理.n通常音量
+ };
+ this.list入力イベント.Add( item );
+
+ this.bKeyState[ (int) key ] = false;
+ this.bKeyPullUp[ (int) key ] = true;
+ }
+ }
+ }
+ //-----------------------------
+ #endregion
+ }
+ else
+ {
+ #region [ b.状態入力 ]
+ //-----------------------------
+ KeyboardState currentState = this.devKeyboard.GetCurrentState();
+ //if ( Result.Last.IsSuccess && currentState != null )
+ {
+ foreach( SharpDXKey dik in currentState.PressedKeys )
+ {
+ // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
+ var key = DeviceConstantConverter.DIKtoKey( dik );
+ if( SlimDXKey.Unknown == key )
+ continue; // 未対応キーは無視。
+
+ if( this.bKeyState[ (int) key ] == false )
+ {
+ if( key != SlimDXKey.Return || ( bKeyState[ (int) SlimDXKey.LeftAlt ] == false && bKeyState[ (int) SlimDXKey.RightAlt ] == false ) ) // #23708 2016.3.19 yyagi
+ {
+ var ev = new STInputEvent() {
+ nKey = (int) key,
+ b押された = true,
+ b離された = false,
+ nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
+ nVelocity = CInput管理.n通常音量,
+ };
+ this.list入力イベント.Add( ev );
+
+ this.bKeyState[ (int) key ] = true;
+ this.bKeyPushDown[ (int) key ] = true;
+ }
+
+ //if ( (int) key == (int) SlimDXKey.Space )
+ //{
+ // Trace.TraceInformation( "FDK(direct): SPACE key registered. " + ct.nシステム時刻 );
+ //}
+ }
+ }
+ //foreach ( Key key in currentState.ReleasedKeys )
+ foreach( SharpDXKey dik in currentState.AllKeys )
+ {
+ // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
+ var key = DeviceConstantConverter.DIKtoKey( dik );
+ if( SlimDXKey.Unknown == key )
+ continue; // 未対応キーは無視。
+
+ if( this.bKeyState[ (int) key ] == true && !currentState.IsPressed( dik ) ) // 前回は押されているのに今回は押されていない → 離された
+ {
+ var ev = new STInputEvent() {
+ nKey = (int) key,
+ b押された = false,
+ b離された = true,
+ nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
+ nVelocity = CInput管理.n通常音量,
+ };
+ this.list入力イベント.Add( ev );
+
+ this.bKeyState[ (int) key ] = false;
+ this.bKeyPullUp[ (int) key ] = true;
+ }
+ }
+ }
+ //-----------------------------
+ #endregion
+ }
+ #region [#23708 2011.4.8 yyagi Altが押されているときは、Enter押下情報を削除する -> 副作用が見つかり削除]
+ //if ( this.bKeyState[ (int) SlimDXKey.RightAlt ] ||
+ // this.bKeyState[ (int) SlimDXKey.LeftAlt ] )
+ //{
+ // int cr = (int) SlimDXKey.Return;
+ // this.bKeyPushDown[ cr ] = false;
+ // this.bKeyPullUp[ cr ] = false;
+ // this.bKeyState[ cr ] = false;
+ //}
+ #endregion
+ }
+ }
+
+ /// <param name="nKey">
+ /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
+ /// </param>
+ public bool bキーが押された( int nKey )
+ {
+ return this.bKeyPushDown[ nKey ];
+ }
+
+ /// <param name="nKey">
+ /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
+ /// </param>
+ public bool bキーが押されている( int nKey )
+ {
+ return this.bKeyState[ nKey ];
+ }
+
+ /// <param name="nKey">
+ /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
+ /// </param>
+ public bool bキーが離された( int nKey )
+ {
+ return this.bKeyPullUp[ nKey ];
+ }
+
+ /// <param name="nKey">
+ /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
+ /// </param>
+ public bool bキーが離されている( int nKey )
+ {
+ return !this.bKeyState[ nKey ];
+ }
+ //-----------------
+ #endregion
+
+ #region [ IDisposable 実装 ]
+ //-----------------
+ public void Dispose()
+ {
+ if( !this.bDispose完了済み )
+ {
+ if( this.devKeyboard != null )
+ {
+ this.devKeyboard.Dispose();
+ this.devKeyboard = null;
+ }
+ //if( this.timer != null )
+ //{
+ // this.timer.Dispose();
+ // this.timer = null;
+ //}
+ if ( this.list入力イベント != null )
+ {
+ this.list入力イベント = null;
+ }
+ this.bDispose完了済み = true;
+ }
+ }
+ //-----------------
+ #endregion
+
+
+ // その他
+
+ #region [ private ]
+ //-----------------
+ private bool bDispose完了済み;
+ private bool[] bKeyPullUp = new bool[ 256 ];
+ private bool[] bKeyPushDown = new bool[ 256 ];
+ private bool[] bKeyState = new bool[ 256 ];
+ private Keyboard devKeyboard;
+ //private CTimer timer;
+ //private CTimer ct;
+ //-----------------
+ #endregion
+ }
+}