using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using SharpDX; using SharpDX.DirectInput; using SlimDXKey = SlimDXKeys.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.Trim(new char[] { '\0' }) + " を生成しました。"); // なぜか0x00のゴミが出るので削除 this.strDeviceName = this.devKeyboard.Information.ProductName.Trim(new char[] { '\0' }); } 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(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 list入力イベント { get; private set; } public string strDeviceName { get; 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( 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 } } /// /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。) /// public bool bキーが押された(int nKey) { return this.bKeyPushDown[nKey]; } /// /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。) /// public bool bキーが押されている(int nKey) { return this.bKeyState[ nKey ]; } /// /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。) /// public bool bキーが離された(int nKey) { return this.bKeyPullUp[nKey]; } /// /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。) /// 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[] bKeyPullUp = new bool[256]; private bool[] bKeyPushDown = new bool[256]; private bool[] bKeyState = new bool[256]; private bool bDispose完了済み; private Keyboard devKeyboard; //private CTimer timer; //private CTimer ct; //----------------- #endregion } }