【问题标题】:Errors on midi functions implementation with Delegation for midiInOpen使用 midiInOpen 委派实现 midi 功能时出错
【发布时间】:2025-12-13 05:35:01
【问题描述】:

我解决了以下代码的许多错误,但 IntelliSense 没有为其中 6 个提供真正的解决方案(3、4、5 和 6 是相同的)。

错误在下面从 1 到 6 进行编号和注释,Visual Studio 给出了相应的错误。

完整的代码是这个:

(...)

// Extra Libraries
using System.Threading;
using System.Runtime.InteropServices;

namespace MidiMonitorC
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        [System.Runtime.InteropServices.DllImport("winmm.dll")]
        public static extern int midiInGetNumDevs();
        [System.Runtime.InteropServices.DllImport("winmm.dll")]
        public static extern int midiInGetDevCaps(int uDeviceID, ref MIDIINCAPS lpCaps, uint uSize);
        [System.Runtime.InteropServices.DllImport("winmm.dll")]
        public static extern int midiInOpen(ref int hMidiIn, int uDeviceID, MidiInCallback dwCallback, int dwInstance, int dwFlags);

        (...)

        public delegate int MidiInCallback(int hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2);
        public MidiInCallback ptrCallback = new MidiInCallback(MidiInProc); // <-- 1. A field initializer cannot reference the non-static field, method or property...
        public const int CALLBACK_FUNCTION = 0x30000;
        public const int MIDI_IO_STATUS = 0x20;

        public delegate void DisplayDataDelegate(object dwParam1);

        public struct MIDIINCAPS
        {
            public Int16 wMid; // Manufacturer ID
            public Int16 wPid; // Product ID
            public int vDriverVersion; // Driver version
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string szPname; // Product Name
            public int dwSupport; // Reserved
        }

        private int hMidiIn;
        private byte StatusByte;
        private byte DataByte1;
        private byte DataByte2;
        private bool MonitorActive = false;
        private bool HideMidiSysMessages = false;

        public int MidiInProc(int hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2) // <-- 2. Not all code paths return a value
        {
            if (MonitorActive)
                TextBox1.Dispatcher.Invoke(new DisplayDataDelegate(DisplayData), new object[] { dwParam1 });
        }

        private void DisplayData(object dwParam1)
        {
            if (HideMidiSysMessages & ((dwParam1 & 0xF0) == 0xF0)) // <-- 3. Operator & cannot be applied to operands of type 'object[]' and int
                return;
            else
            {
                StatusByte = dwParam1 & 0xFF; // <-- 4. Operator & cannot be applied to operands of type 'object[]' and int
                DataByte1 = (dwParam1 & 0xFF00) >> 8; // <-- 5. Operator & cannot be applied to operands of type 'object[]' and int
                DataByte2 = (dwParam1 & 0xFF0000) >> 16; // <-- 6. Operator & cannot be applied to operands of type 'object[]' and int
                TextBox1.Text += string.Format("{0:X2} {1:X2} {2:X2}{3}", StatusByte, DataByte1, DataByte2, "\n");
            }
        }

        (...)

    }
}

这是针对 WPF 应用程序的。

谢谢

【问题讨论】:

    标签: c# wpf visual-studio debugging midi


    【解决方案1】:

    对于问题1,你可以在构造函数或者“window Loaded”事件中初始化你的变量:

    
           public MainWindow()
            {
                InitializeComponent();
    
                ptrCallback = new MidiInCallback(MidiInProc);
            }
    
            //[...]
            public MidiInCallback ptrCallback;
            //[...]      
    
    

    对于问题 2,您必须提供 int 类型的返回值。请查找midiInOpen方法的相应文档:

    
         public int MidiInProc(int hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2) 
            {
                if (MonitorActive)
                    TextBox1.Dispatcher.Invoke(new DisplayDataDelegate(DisplayData), new object[] { dwParam1 });
                
                return 0; //or whatever value should be returned by default. 
                    
            }
    
    

    对于问题 3 到 6,您必须将对象转换为相应的值,可能根据您的代码转换为 int32:

          private void DisplayData(object dwParam1)
          {
          int dwParam1Cast = Convert.ToInt32(dwParam1); 
          if (HideMidiSysMessages & ((dwParam1Cast & 0xF0) == 0xF0)) 
              return;
          else
             {
                 StatusByte = dwParam1Cast & 0xFF; 
                 DataByte1 = (dwParam1Cast & 0xFF00) >> 8; 
                 DataByte2 = (dwParam1Cast & 0xFF0000) >> 16; 
                 TextBox1.Text += string.Format("{0:X2} {1:X2} {2:X2}{3}", StatusByte, DataByte1, DataByte2, "\n");
              }
           }
    

    【讨论】:

      最近更新 更多