C# 读取USB外设消息(MIDI为例)

源代码:运行通过验证的:http://download.csdn.net/detail/tianjun2012/6574171(不需要的直接看下面)


第一步:(本例子,我原代码可是利用Samson carbon49实验的,(从无到有)花了2个星期……无语)

首先我们得了解在windows系统中获取消息的方式,我们不管搞不搞底层编程肯定都知道驱动这个概念(如果不知道百度或者谷歌去)外设的消息首先是发送到发现它的驱动上去,我们利用Windows API从驱动中把消息取出来就可以了,首先肯定我们想到的是去写个驱动,这个很对,但是如果你对通信或者是底层编程没啥基础,还是不要去浪费时间了,万幸的是万恶的微软一般的常用的工种USB的驱动都集成着有,所以不用去太话费时间了,我们只需要利用API读取就行了。

第二步:

我们得对c#中对Windows API的引用“DLLImport”关键字,不知道的MSDN上查具体用法,言归正传,我们调用Windows API,代码例子如下:

  internal static class NativeMethods
        {
            internal const int MMSYSERR_NOERROR = 0;
            internal const int CALLBACK_FUNCTION = 0x00030000;


            internal delegate void MidiInProc(
                IntPtr hMidiIn,
                uint wMsg,
                IntPtr dwInstance,
                UInt32 dwParam1,
                UInt32 dwParam2);


            [DllImport("winmm.dll")]
            internal static extern int midiInGetNumDevs();


            [DllImport("winmm.dll")]
            internal static extern int midiInClose(
                IntPtr hMidiIn);


            [DllImport("winmm.dll")]
            internal static extern int midiInOpen(
                out IntPtr lphMidiIn,
                int uDeviceID,
                MidiInProc dwCallback,
                IntPtr dwCallbackInstance,
                int dwFlags);


            [DllImport("winmm.dll")]
            internal static extern int midiInStart(
                IntPtr hMidiIn);


            [DllImport("winmm.dll")]
            internal static extern int midiInStop(
                IntPtr hMidiIn);
        }

第三步:

对上述API的运用(多话不说,原代码奉上)

 public class InputPort
        {
            private NativeMethods.MidiInProc midiInProc;
            private IntPtr handle;


            public InputPort()
            {
                midiInProc = new NativeMethods.MidiInProc(MidiProc);
                handle = IntPtr.Zero;
            }


            public static int InputCount
            {
                get { return NativeMethods.midiInGetNumDevs(); }
            }


            public bool Close()
            {
                bool result = NativeMethods.midiInClose(handle)
                    == NativeMethods.MMSYSERR_NOERROR;
                handle = IntPtr.Zero;
                return result;
            }


            public bool Open(int id)
            {
                return NativeMethods.midiInOpen(
                    out handle,
                    id,
                    midiInProc,
                    IntPtr.Zero,
                    NativeMethods.CALLBACK_FUNCTION)
                        == NativeMethods.MMSYSERR_NOERROR;
            }


            public bool Start()
            {
                return NativeMethods.midiInStart(handle)
                    == NativeMethods.MMSYSERR_NOERROR;
            }


            public bool Stop()
            {
                return NativeMethods.midiInStop(handle)
                    == NativeMethods.MMSYSERR_NOERROR;
            }


            public IntPtr hmidi = IntPtr.Zero;
            public uint midi_wMsg = 0;
            public IntPtr midi_dwIns = IntPtr.Zero;
            public UInt32 midi_dw1 = 0;
            public UInt32 mide_dw2 = 0;




            public void MidiProc(IntPtr hMidiIn,
                uint wMsg,
                IntPtr dwInstance,
                UInt32 dwParam1,
                UInt32 dwParam2)
            {
                // Receive messages here
                hmidi = hMidiIn;


                if (wMsg == 963)
                {
                    dwParam1 = dwParam1 & 0xFFFF;
                    uint h_dw1 = 0;
                    uint l_dw1 = 0;
                    h_dw1 = dwParam1 & 0xFF;
                    l_dw1 = (dwParam1 >> 8) & 0xFF;


                    Console.WriteLine(Convert.ToString(wMsg, 16));
                    Console.WriteLine(Convert.ToString(h_dw1, 16));
                    Console.WriteLine(Convert.ToString(l_dw1, 16));
                    Console.WriteLine(Convert.ToString(dwParam2, 16));
                    Console.WriteLine("-------------------------------");
                }
                else
                {
                    Console.WriteLine(Convert.ToString(wMsg, 16));
                    Console.WriteLine(Convert.ToString(dwParam1, 16));
                    Console.WriteLine(Convert.ToString(dwParam2, 16));
                    Console.WriteLine("-------------------------------");
                }


            }
        }


第四步:

你在你的主函数中运用就行了,注意啊,那个MidiProc(IntPtr hMidiIn,uint wMsg,IntPtr dwInstance, UInt32 dwParam1,UInt32 dwParam2)系统会自动调用它去获取MIDI消息,不用你在写个函数去循环获取消息了,具体的demo,我会传到上去的,等下我发个链接。

第五步:

得感谢这个老外啊,你们也可以参考下:http://stackoverflow.com/questions/1991159/getting-signals-from-a-midi-port-in-c-sharp/1992014#1992014

MIDI APID的读取,大家参考MSDN:http://msdn.microsoft.com/en-us/library/windows/desktop/dd798495(v=vs.85).aspx

当然这只是最简单的MIDI消息的读取,还有USB的其他设备,我给大家几个链接,

http://www.codeproject.com/Articles/18099/A-USB-HID-Component-for-C

http://www.developerfusion.com/article/84338/making-usb-c-friendly/

(太感谢这些无私的老外们了)




你可能感兴趣的:(C# 读取USB外设消息(MIDI为例))