[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
public struct MIXERLINECONTROLS
{
private UInt32 cbStruct; /* size in bytes of MIXERLINECONTROLS */
private UInt32 dwLineID; /* line id (from MIXERLINE.dwLineID) */
private UInt32 dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */
// private UInt32 dwControlType; //UNIONED with dwControlID /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
private UInt32 cControls; /* count of controls pmxctrl points to */
private UInt32 cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */
private IntPtr pamxctrl; /* pointer to first MIXERCONTROL array */
#region Properties
/// <summary>size in bytes of MIXERLINECONTROLS</summary>
public UInt32 StructSize
{
get { return this.cbStruct; }
set { this.cbStruct = value; }
}
/// <summary>line id (from MIXERLINE.dwLineID)</summary>
public UInt32 LineID
{
get { return this.dwLineID; }
set { this.dwLineID = value; }
}
/// <summary>MIXER_GETLINECONTROLSF_ONEBYID</summary>
public UInt32 ControlID
{
get { return this.dwControlID; }
set { this.dwControlID = value; }
}
/// <summary>MIXER_GETLINECONTROLSF_ONEBYTYPE</summary>
public MIXERCONTROL_CONTROLTYPE ControlType
{
get { return (MIXERCONTROL_CONTROLTYPE)this.dwControlID; }
set { this.dwControlID = (uint)value; }
}
/// <summary>count of controls pmxctrl points to</summary>
public UInt32 Controls
{
get { return this.cControls; }
set { this.cControls = value; }
}
/// <summary>size in bytes of _one_ MIXERCONTROL</summary>
public UInt32 MixerControlItemSize
{
get { return this.cbmxctrl; }
set { this.cbmxctrl = value; }
}
/// <summary>pointer to first MIXERCONTROL array</summary>
public IntPtr MixerControlArray
{
get { return this.pamxctrl; }
set { this.pamxctrl = value; }
}
#endregion
}
THIS IS MY CONVERSION FROM THE C# ABOVE. I have used an UInt32 instead of the MIXERCONTROL_CONTROLTYPE enum as I didn't bother converting it. Also I set dwLineID as an Integer as I was getting a negative number come back from the APIs.
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=4)> _
Public Structure MIXERLINECONTROLS
Private cbStruct As UInt32 '/* size in bytes of MIXERLINECONTROLS */
Private dwLineID As Integer '/* line id (from MIXERLINE.dwLineID) */
Private dwControlID As UInt32 '/* MIXER_GETLINECONTROLSF_ONEBYID */
'private UInt32 dwControlType; //UNIONED with dwControlID /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
Private cControls As UInt32 '/* count of controls pmxctrl points to */
Private cbmxctrl As UInt32 '/* size in bytes of _one_ MIXERCONTROL */
Private pamxctrl As IntPtr '/* pointer to first MIXERCONTROL array */
'/// <summary>size in bytes of MIXERLINECONTROLS</summary>
Public Property StructSize As UInt32
Get
Return cbStruct
End Get
Set(ByVal value As UInt32)
cbStruct = value
End Set
End Property
'/// <summary>line id (from MIXERLINE.dwLineID)</summary>
Public Property LineID As Integer
Get
Return dwLineID
End Get
Set(ByVal value As Integer)
dwLineID = value
End Set
End Property
'/// <summary>MIXER_GETLINECONTROLSF_ONEBYID</summary>
Public Property ControlID As UInt32
Get
Return dwControlID
End Get
Set(ByVal value As UInt32)
dwControlID = value
End Set
End Property
'/// <summary>MIXER_GETLINECONTROLSF_ONEBYTYPE</summary>
Public Property ControlType As UInt32
Get
Return dwControlID
End Get
Set(ByVal value As UInt32)
dwControlID = value
End Set
End Property
'/// <summary>count of controls pmxctrl points to</summary>
Public Property Controls As UInt32
Get
Return cControls
End Get
Set(ByVal value As UInt32)
cControls = value
End Set
End Property
'/// <summary>size in bytes of _one_ MIXERCONTROL</summary>
Public Property MixerControlItemSize As UInt32
Get
Return cbmxctrl
End Get
Set(ByVal value As UInt32)
cbmxctrl = value
End Set
End Property
'/// <summary>pointer to first MIXERCONTROL array</summary>
Public Property MixerControlArray As IntPtr
Get
Return pamxctrl
End Get
Set(ByVal value As IntPtr)
pamxctrl = value
End Set
End Property
End Structure
None.
The winmm dll may not execute properly on 64-bit systems. Consequently, the StructLayout must be Sequential, with CharSet = Ansi, and Pack = 4. This particular type has some special layout considerations (the c union keyword) which typically means developers would use the explicit layout. However, the explicit layout breaks down on 64-bit systems for any type with an IntPtr in the type. Consequently, the C# types have been redesigned to use Sequential layout so that they will automatically adjust to 64-bit systems. This means private fields with public properties which perform the gunky work of making it look like there is a union.
There is more code that is necessary to use the C# types listed above.
private const uint MIXERCONTROL_CT_CLASS_MASK = 0xF0000000u;
private const uint MIXERCONTROL_CT_CLASS_CUSTOM = 0x00000000u;
private const uint MIXERCONTROL_CT_CLASS_METER = 0x10000000u;
private const uint MIXERCONTROL_CT_CLASS_SWITCH = 0x20000000u;
private const uint MIXERCONTROL_CT_CLASS_NUMBER = 0x30000000u;
private const uint MIXERCONTROL_CT_CLASS_SLIDER = 0x40000000u;
private const uint MIXERCONTROL_CT_CLASS_FADER = 0x50000000u;
private const uint MIXERCONTROL_CT_CLASS_TIME = 0x60000000u;
private const uint MIXERCONTROL_CT_CLASS_LIST = 0x70000000u;
private const uint MIXERCONTROL_CT_SUBCLASS_MASK = 0x0F000000u;
private const uint MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = 0x00000000u;
private const uint MIXERCONTROL_CT_SC_SWITCH_BUTTON = 0x01000000u;
private const uint MIXERCONTROL_CT_SC_METER_POLLED = 0x00000000u;
private const uint MIXERCONTROL_CT_SC_TIME_MICROSECS = 0x00000000u;
private const uint MIXERCONTROL_CT_SC_TIME_MILLISECS = 0x01000000u;
private const uint MIXERCONTROL_CT_SC_LIST_SINGLE = 0x00000000u;
private const uint MIXERCONTROL_CT_SC_LIST_MULTIPLE = 0x01000000u;
private const uint MIXERCONTROL_CT_UNITS_MASK = 0x00FF0000u;
private const uint MIXERCONTROL_CT_UNITS_CUSTOM = 0x00000000u;
private const uint MIXERCONTROL_CT_UNITS_BOOLEAN = 0x00010000u;
private const uint MIXERCONTROL_CT_UNITS_SIGNED = 0x00020000u;
private const uint MIXERCONTROL_CT_UNITS_UNSIGNED = 0x00030000u;
private const uint MIXERCONTROL_CT_UNITS_DECIBELS = 0x00040000u; /* in 10ths */
private const uint MIXERCONTROL_CT_UNITS_PERCENT = 0x00050000u; /* in 10ths */
/// <summary>Commonly used control types for specifying MIXERCONTROL.dwControlType</summary>
public enum MIXERCONTROL_CONTROLTYPE : uint
{
CUSTOM =(MIXERCONTROL_CT_CLASS_CUSTOM | MIXERCONTROL_CT_UNITS_CUSTOM),
BOOLEANMETER =(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_BOOLEAN),
SIGNEDMETER =(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_SIGNED),
PEAKMETER =(SIGNEDMETER + 1),
UNSIGNEDMETER =(MIXERCONTROL_CT_CLASS_METER | MIXERCONTROL_CT_SC_METER_POLLED | MIXERCONTROL_CT_UNITS_UNSIGNED),
BOOLEAN =(MIXERCONTROL_CT_CLASS_SWITCH | MIXERCONTROL_CT_SC_SWITCH_BOOLEAN | MIXERCONTROL_CT_UNITS_BOOLEAN),
ONOFF =(BOOLEAN + 1),
MUTE =(BOOLEAN + 2),
MONO =(BOOLEAN + 3),
LOUDNESS =(BOOLEAN + 4),
STEREOENH =(BOOLEAN + 5),
BASS_BOOST =(BOOLEAN + 0x00002277),
BUTTON =(MIXERCONTROL_CT_CLASS_SWITCH | MIXERCONTROL_CT_SC_SWITCH_BUTTON | MIXERCONTROL_CT_UNITS_BOOLEAN),
DECIBELS =(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_DECIBELS),
SIGNED =(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_SIGNED),
UNSIGNED =(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_UNSIGNED),
PERCENT =(MIXERCONTROL_CT_CLASS_NUMBER | MIXERCONTROL_CT_UNITS_PERCENT),
SLIDER =(MIXERCONTROL_CT_CLASS_SLIDER | MIXERCONTROL_CT_UNITS_SIGNED),
PAN =(SLIDER + 1),
QSOUNDPAN =(SLIDER + 2),
FADER =(MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED),
VOLUME =(FADER + 1),
BASS =(FADER + 2),
TREBLE =(FADER + 3),
EQUALIZER =(FADER + 4),
SINGLESELECT =(MIXERCONTROL_CT_CLASS_LIST | MIXERCONTROL_CT_SC_LIST_SINGLE | MIXERCONTROL_CT_UNITS_BOOLEAN),
MUX =(SINGLESELECT + 1),
MULTIPLESELECT =(MIXERCONTROL_CT_CLASS_LIST | MIXERCONTROL_CT_SC_LIST_MULTIPLE | MIXERCONTROL_CT_UNITS_BOOLEAN),
MIXER =(MULTIPLESELECT + 1),
MICROTIME =(MIXERCONTROL_CT_CLASS_TIME | MIXERCONTROL_CT_SC_TIME_MICROSECS | MIXERCONTROL_CT_UNITS_UNSIGNED),
MILLITIME =(MIXERCONTROL_CT_CLASS_TIME | MIXERCONTROL_CT_SC_TIME_MILLISECS | MIXERCONTROL_CT_UNITS_UNSIGNED),
}