使用 midiInOpen 委派实现 midi 功能时出错
Posted
技术标签:
【中文标题】使用 midiInOpen 委派实现 midi 功能时出错【英文标题】:Errors on midi functions implementation with Delegation for midiInOpen 【发布时间】:2021-08-08 11:41:03 【问题描述】:我解决了以下代码的许多错误,但 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:X23", StatusByte, DataByte1, DataByte2, "\n");
(...)
这是针对 WPF 应用程序的。
谢谢
【问题讨论】:
【参考方案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:X23", StatusByte, DataByte1, DataByte2, "\n");
【讨论】:
以上是关于使用 midiInOpen 委派实现 midi 功能时出错的主要内容,如果未能解决你的问题,请参考以下文章