2 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Runtime.InteropServices;
6 using SharpDX.DirectInput;
10 public class CInput管理 : IDisposable
14 public static int n通常音量 = 110;
19 public List<IInputDevice> list入力デバイス
24 public IInputDevice Keyboard
28 if( this._Keyboard != null )
30 return this._Keyboard;
32 foreach( IInputDevice device in this.list入力デバイス )
34 if( device.e入力デバイス種別 == E入力デバイス種別.Keyboard )
36 this._Keyboard = device;
43 public IInputDevice Mouse
47 if( this._Mouse != null )
51 foreach( IInputDevice device in this.list入力デバイス )
53 if( device.e入力デバイス種別 == E入力デバイス種別.Mouse )
65 public CInput管理( IntPtr hWnd )
67 CInput管理初期化( hWnd, true );
69 public CInput管理( IntPtr hWnd, bool bUseMidiIn )
71 CInput管理初期化( hWnd, bUseMidiIn );
74 public void CInput管理初期化( IntPtr hWnd, bool bUseMidiIn )
76 this.directInput = new DirectInput();
77 // this.timer = new CTimer( CTimer.E種別.MultiMedia );
79 this.list入力デバイス = new List<IInputDevice>( 10 );
80 #region [ Enumerate keyboard/mouse: exception is masked if keyboard/mouse is not connected ]
81 CInputKeyboard cinputkeyboard = null;
82 CInputMouse cinputmouse = null;
85 cinputkeyboard = new CInputKeyboard( hWnd, directInput );
86 cinputmouse = new CInputMouse( hWnd, directInput );
91 if (cinputkeyboard != null)
93 this.list入力デバイス.Add( cinputkeyboard );
95 if ( cinputmouse != null )
97 this.list入力デバイス.Add( cinputmouse );
100 #region [ Enumerate joypad ]
101 foreach ( DeviceInstance instance in this.directInput.GetDevices( DeviceClass.GameControl, DeviceEnumerationFlags.AttachedOnly ) )
103 this.list入力デバイス.Add( new CInputJoystick( hWnd, instance, directInput ) );
108 this.proc = new CWin32.MidiInProc( this.MidiInCallback );
109 uint nMidiDevices = CWin32.midiInGetNumDevs();
110 Trace.TraceInformation( "MIDI入力デバイス数: {0}", nMidiDevices );
111 for ( uint i = 0; i < nMidiDevices; i++ )
113 CInputMIDI item = new CInputMIDI( i );
114 CWin32.MIDIINCAPS lpMidiInCaps = new CWin32.MIDIINCAPS();
115 uint num3 = CWin32.midiInGetDevCaps( i, ref lpMidiInCaps, (uint) Marshal.SizeOf( lpMidiInCaps ) );
118 Trace.TraceError( "MIDI In: Device{0}: midiInDevCaps(): {1:X2}: ", i, num3 );
120 else if ( ( CWin32.midiInOpen( ref item.hMidiIn, i, this.proc, 0, 0x30000 ) == 0 ) && ( item.hMidiIn != 0 ) )
122 CWin32.midiInStart( item.hMidiIn );
123 Trace.TraceInformation( "MIDI In: [{0}] \"{1}\" の入力受付を開始しました。", i, lpMidiInCaps.szPname );
127 Trace.TraceError( "MIDI In: [{0}] \"{1}\" の入力受付の開始に失敗しました。", i, lpMidiInCaps.szPname );
129 item.strDeviceName = lpMidiInCaps.szPname;
130 this.list入力デバイス.Add(item);
135 Trace.TraceInformation( "DTXVモードのため、MIDI入力は使用しません。" );
142 public IInputDevice Joystick( int ID )
144 foreach( IInputDevice device in this.list入力デバイス )
146 if( ( device.e入力デバイス種別 == E入力デバイス種別.Joystick ) && ( device.ID == ID ) )
153 public IInputDevice Joystick( string GUID )
155 foreach( IInputDevice device in this.list入力デバイス )
157 if( ( device.e入力デバイス種別 == E入力デバイス種別.Joystick ) && device.GUID.Equals( GUID ) )
164 public IInputDevice MidiIn( int ID )
166 foreach( IInputDevice device in this.list入力デバイス )
168 if( ( device.e入力デバイス種別 == E入力デバイス種別.MidiIn ) && ( device.ID == ID ) )
175 public void tポーリング( bool bWindowがアクティブ中, bool bバッファ入力を使用する )
177 lock( this.objMidiIn排他用 )
179 // foreach( IInputDevice device in this.list入力デバイス )
180 for (int i = this.list入力デバイス.Count - 1; i >= 0; i--) // #24016 2011.1.6 yyagi: change not to use "foreach" to avoid InvalidOperation exception by Remove().
182 IInputDevice device = this.list入力デバイス[i];
185 device.tポーリング(bWindowがアクティブ中, bバッファ入力を使用する);
187 catch (SharpDX.SharpDXException e) // #24016 2011.1.6 yyagi: catch exception for unplugging USB joystick, and remove the device object from the polling items.
189 if( e.ResultCode == ResultCode.OtherApplicationHasPriority )
191 // #xxxxx: 2017.5.9: from: このエラーの時は、何もしない。
195 // #xxxxx: 2017.5.9: from: その他のエラーの場合は、デバイスが外されたと想定してRemoveする。
196 this.list入力デバイス.Remove( device );
198 Trace.TraceError( "tポーリング時に対象deviceが抜かれており例外発生。同deviceをポーリング対象からRemoveしました。" );
205 #region [ IDisposable+α ]
207 public void Dispose()
209 this.Dispose( true );
211 public void Dispose( bool disposeManagedObjects )
213 if( !this.bDisposed済み )
215 if( disposeManagedObjects )
217 foreach( IInputDevice device in this.list入力デバイス )
219 CInputMIDI tmidi = device as CInputMIDI;
222 CWin32.midiInStop( tmidi.hMidiIn );
223 CWin32.midiInReset( tmidi.hMidiIn );
224 CWin32.midiInClose( tmidi.hMidiIn );
225 Trace.TraceInformation( "MIDI In: [{0}] を停止しました。", new object[] { tmidi.ID } );
228 foreach( IInputDevice device2 in this.list入力デバイス )
232 lock( this.objMidiIn排他用 )
234 this.list入力デバイス.Clear();
237 this.directInput.Dispose();
239 //if( this.timer != null )
241 // this.timer.Dispose();
242 // this.timer = null;
245 this.bDisposed済み = true;
250 this.Dispose( false );
251 GC.KeepAlive( this );
261 private DirectInput directInput;
262 private IInputDevice _Keyboard;
263 private IInputDevice _Mouse;
264 private bool bDisposed済み;
265 private List<uint> listHMIDIIN = new List<uint>( 8 );
266 private object objMidiIn排他用 = new object();
267 private CWin32.MidiInProc proc;
268 // private CTimer timer;
270 private void MidiInCallback( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 )
272 int p = dwParam1 & 0xF0;
273 if( wMsg != CWin32.MIM_DATA || ( p != 0x80 && p != 0x90 && p != 0xB0 ) )
276 long time = CSound管理.rc演奏用タイマ.nシステム時刻; // lock前に取得。演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
278 lock( this.objMidiIn排他用 )
280 if( ( this.list入力デバイス != null ) && ( this.list入力デバイス.Count != 0 ) )
282 foreach( IInputDevice device in this.list入力デバイス )
284 CInputMIDI tmidi = device as CInputMIDI;
285 if( ( tmidi != null ) && ( tmidi.hMidiIn == hMidiIn ) )
287 tmidi.tメッセージからMIDI信号のみ受信( wMsg, dwInstance, dwParam1, dwParam2, time );