2 using System.Collections.Generic;
6 public class Keyboard : FDK.入力.IInputDevice, IDisposable
8 public InputDeviceType 入力デバイス種別 => ( InputDeviceType.Keyboard );
10 public Keyboard( IntPtr hWindow )
12 FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
15 this._Window = hWindow;
17 #region " キーの押下状態配列を初期化する。"
19 for( int i = 0; i < 256; i++ )
20 this._現在のキーの押下状態[ i ] = false;
25 var di = new SharpDX.DirectInput.DirectInput();
27 #region " キーボードが接続されていないなら、this.Device = null のままとする。"
29 if( 0 == di.GetDevices( SharpDX.DirectInput.DeviceType.Keyboard, SharpDX.DirectInput.DeviceEnumerationFlags.AttachedOnly ).Count )
31 this._Device = null; // これは、エラーではない。
38 this._Device = new SharpDX.DirectInput.Keyboard( di );
41 this._Device.SetCooperativeLevel(
43 SharpDX.DirectInput.CooperativeLevel.NoWinKey |
44 SharpDX.DirectInput.CooperativeLevel.Foreground |
45 SharpDX.DirectInput.CooperativeLevel.NonExclusive );
47 // デバイスの入力バッファサイズを設定する。
48 this._Device.Properties.BufferSize = Keyboard._デバイスの入力バッファサイズ;
52 FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
58 FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
61 FDK.Utilities.解放する( ref this._Device );
65 FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
71 if( null == this._Device )
74 this._入力イベントリスト.Clear(); // Acquire 前にクリアしておく(Acquire の失敗時にリストが空であるように)。
76 #region " Acquire する。失敗(非アクティブ、ウィンドウ終了時など)したら、何もしない。 "
80 this._Device.Acquire();
84 //Log.WARNING( "キーボードデバイスの Acquire に失敗しました。" );
95 // ポーリング結果から状態配列を更新する。
96 var timeStamp = FDK.カウンタ.QPCTimer.生カウント; // なるべく早くに取得しておく。
97 foreach( var k in this._Device.GetBufferedData() )
107 TimeStamp = timeStamp, // DirectInput の TimeStamp は使わない。
112 this._現在のキーの押下状態[ (int) k.Key ] = true;
116 else if( k.IsReleased )
124 TimeStamp = timeStamp, // DirectInput の TimeStamp は使わない。
129 this._現在のキーの押下状態[ (int) k.Key ] = true;
135 catch( SharpDX.SharpDXException )
137 // たまに DIERR_INPUTLOST が発生するが、再度 Acquire すればいいだけなので無視する。
141 public bool キーが押された( int key )
144 return this.キーが押された( key, out dummy );
147 public bool キーが押された( int key, out InputEvent ev )
151 if( null == this._Device )
152 return false; // 準正常。
155 ev = this._入力イベントリスト.Find( ( item ) => { return ( item.Key == key ) && ( item.押された ); } );
158 return ( null != ev ) ? true : false;
161 public bool キーが押された( SharpDX.DirectInput.Key key )
164 return this.キーが押された( (int) key, out dummy );
167 public bool キーが押された( SharpDX.DirectInput.Key key, out InputEvent ev )
169 return this.キーが押された( (int) key, out ev );
172 public bool キーが押されている( int key )
174 if( null == this._Device ) // 準正常。
177 return this._現在のキーの押下状態[ key ];
180 public bool キーが押されている( SharpDX.DirectInput.Key key )
182 return this.キーが押されている( (int) key );
185 public bool キーが離された( int key )
188 return this.キーが離された( key, out dummy );
191 public bool キーが離された( int key, out InputEvent ev )
195 if( null == this._Device )
196 return false; // 準正常。
199 ev = this._入力イベントリスト.Find( ( item ) => { return ( item.Key == key ) && ( item.離された ); } );
202 return ( null != ev ) ? true : false;
205 public bool キーが離された( SharpDX.DirectInput.Key key )
208 return this.キーが離された( (int) key, out dummy );
211 public bool キーが離された( SharpDX.DirectInput.Key key, out InputEvent ev )
213 return this.キーが離された( (int) key, out ev );
216 public bool キーが離されている( int key )
218 if( null == this._Device ) // 準正常。
221 return !( this._現在のキーの押下状態[ key ] );
224 public bool キーが離されている( SharpDX.DirectInput.Key key )
226 return this.キーが離されている( (int) key );
229 private const int _デバイスの入力バッファサイズ = 32;
230 private SharpDX.DirectInput.Keyboard _Device = null; // キーボードがアタッチされていない場合は null 。
231 private IntPtr _Window = IntPtr.Zero;
233 /// ポーリングごとに累積更新された最終の結果。
235 private readonly bool[] _現在のキーの押下状態 = new bool[ 256 ];
236 private readonly List<InputEvent> _入力イベントリスト = new List<InputEvent>();