VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsVolume"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Ext_KEY = "SavedWithClassBuilder" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
Option ExplicitPrivate hmem As LongConst MMSYSERR_NOERROR = 0
Const MAXPNAMELEN = 32
Const MIXER_LONG_NAME_CHARS = 64
Const MIXER_SHORT_NAME_CHARS = 16
Const MIXER_GETLINEINFOF_COMPONENTTYPE = &H3&
Const MIXER_GETCONTROLDETAILSF_VALUE = &H0&
Const MIXER_SETCONTROLDETAILSF_VALUE = &H0&
Const MIXER_GETLINECONTROLSF_ONEBYTYPE = &H2&
Const MIXERLINE_COMPONENTTYPE_DST_FIRST = &H0&
Const MIXERLINE_COMPONENTTYPE_SRC_FIRST = &H1000&
Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = _
               (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)
Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = _
               (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)
Const MIXERLINE_COMPONENTTYPE_SRC_LINE = _
               (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)
Const MIXERCONTROL_CT_CLASS_FADER = &H50000000
Const MIXERCONTROL_CT_UNITS_UNSIGNED = &H30000
Const MIXERCONTROL_CONTROLTYPE_FADER = _
               (MIXERCONTROL_CT_CLASS_FADER Or _
               MIXERCONTROL_CT_UNITS_UNSIGNED)
Const MIXERCONTROL_CONTROLTYPE_VOLUME = _
               (MIXERCONTROL_CONTROLTYPE_FADER + 1)Private Type MIXERCONTROLDETAILS
    cbStruct    As Long
    dwControlID As Long
    cChannels   As Long
    item        As Long
    cbDetails   As Long
    paDetails   As Long
End TypePrivate Type MIXERCONTROLDETAILS_UNSIGNED
    dwValue As Long
End TypePrivate Type MIXERCONTROL
    cbStruct       As Long
    dwControlID    As Long
    dwControlType  As Long
    fdwControl     As Long
    cMultipleItems As Long
    szShortName    As String * MIXER_SHORT_NAME_CHARS
    szName         As String * MIXER_LONG_NAME_CHARS
    lMinimum       As Long
    lMaximum       As Long
    reserved(10)   As Long
End TypePrivate Type MIXERLINECONTROLS
    cbStruct  As Long
    dwLineID  As Long
    dwControl As Long
    cControls As Long
    cbmxctrl  As Long
    pamxctrl  As Long
End TypePrivate Type MIXERLINE
    cbStruct        As Long
    dwDestination   As Long
    dwSource        As Long
    dwLineID        As Long
    fdwLine         As Long
    dwUser          As Long
    dwComponentType As Long
    cChannels       As Long
    cConnections    As Long
    cControls       As Long
    szShortName     As String * MIXER_SHORT_NAME_CHARS
    szName          As String * MIXER_LONG_NAME_CHARS
    dwType          As Long
    dwDeviceID      As Long
    wMid            As Integer
    wPid            As Integer
    vDriverVersion  As Long
    szPname         As String * MAXPNAMELEN
End Type
'
'Allocates the specified number of bytes from the heap.
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, _
    ByVal dwBytes As Long) As Long
'
'Locks a global memory object and returns a pointer to the
' first byte of the object's memory block.  The memory block
' associated with a locked object cannot be moved or discarded.
Private Declare Function GlobalLock Lib "kernel32" (ByVal hmem As Long) As Long
'
'Frees the specified global memory object and invalidates its handle.
Private Declare Function GlobalFree Lib "kernel32" (ByVal hmem As Long) As Long
'
Private Declare Sub CopyPtrFromStruct Lib "kernel32" Alias "RtlMoveMemory" _
    (ByVal ptr As Long, struct As Any, ByVal cb As Long)Private Declare Sub CopyStructFromPtr Lib "kernel32" Alias "RtlMoveMemory" _
    (struct As Any, ByVal ptr As Long, ByVal cb As Long)
'
'Opens a specified mixer device and ensures that the device
' will not be removed until the application closes the handle.
Private Declare Function mixerOpen Lib "winmm.dll" _
    (phmx As Long, ByVal uMxId As Long, ByVal dwCallback As Long, _
    ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
'
'Sets properties of a single control associated with an audio line.
Private Declare Function mixerSetControlDetails Lib "winmm.dll" _
    (ByVal hmxobj As Long, pmxcd As MIXERCONTROLDETAILS, _
    ByVal fdwDetails As Long) As Long
'
'Retrieves information about a specific line of a mixer device.
Private Declare Function mixerGetLineInfo Lib "winmm.dll" _
    Alias "mixerGetLineInfoA" (ByVal hmxobj As Long, _
    pmxl As MIXERLINE, ByVal fdwInfo As Long) As Long
'
'Retrieves one or more controls associated with an audio line.
Private Declare Function mixerGetLineControls Lib "winmm.dll" _
    Alias "mixerGetLineControlsA" (ByVal hmxobj As Long, _
    pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Long) As LongPrivate hmixer  As Long
Private volCtrl As MIXERCONTROL ' Waveout volume control.
Private micCtrl As MIXERCONTROL ' Microphone volume control.
'
'Local variable to save properties
Private mvarprMicVolume As Long 'Local copy
Private mvarprMicMaxVolume As Long 'Local copy
Private mvarprMicMinVolume As Long 'Local copy
Private mvarprSpeakerVolume As Long 'Local copy
Private mvarprSpeakerMaxVolume As Long 'Local copy
Private mvarprSpeakerMinVolume As Long 'Local copy
Private mvarprMixerErr As Long 'Local copyPrivate Function fGetVolumeControl(ByVal hmixer As Long, _
        ByVal componentType As Long, ByVal ctrlType As Long, _
        ByRef mxc As MIXERCONTROL) As Boolean
'
' This function attempts to obtain a mixer control.
'
Dim mxlc As MIXERLINECONTROLS
Dim mxl  As MIXERLINE
Dim hmem As Long
Dim rc   As Longmxl.cbStruct = Len(mxl)
mxl.dwComponentType = componentType
'
' Get a line corresponding to the component type.
'
rc = mixerGetLineInfo(hmixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)
If MMSYSERR_NOERROR = rc Then
    With mxlc
        .cbStruct = Len(mxlc)
        .dwLineID = mxl.dwLineID
        .dwControl = ctrlType
        .cControls = 1
        .cbmxctrl = Len(mxc)
    End With
    '
    ' Allocate a buffer for the control.
    '
    hmem = GlobalAlloc(&H40, Len(mxc))
    mxlc.pamxctrl = GlobalLock(hmem)
    mxc.cbStruct = Len(mxc)
    '
    ' Get the control.
    '
    rc = mixerGetLineControls(hmixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)
    If MMSYSERR_NOERROR = rc Then
        fGetVolumeControl = True
        '
        ' Copy the control into the destination structure.
        '
        Call CopyStructFromPtr(mxc, mxlc.pamxctrl, Len(mxc))
    Else
        fGetVolumeControl = False
    End If
    Call GlobalFree(hmem)
    Exit Function
End If
fGetVolumeControl = False
End FunctionPrivate Function fSetVolumeControl(ByVal hmixer As Long, _
    mxc As MIXERCONTROL, ByVal volume As Long) As Boolean
'
' This function sets the value for a volume control.
'
Dim rc   As Long
Dim mxcd As MIXERCONTROLDETAILS
Dim vol  As MIXERCONTROLDETAILS_UNSIGNEDWith mxcd
    .item = 0
    .dwControlID = mxc.dwControlID
    .cbStruct = Len(mxcd)
    .cbDetails = Len(vol)
End With
'
' Allocate a buffer for the control value buffer.
'
hmem = GlobalAlloc(&H40, Len(vol))
mxcd.paDetails = GlobalLock(hmem)
mxcd.cChannels = 1
vol.dwValue = volume
'
' Copy the data into the control value buffer.
'
Call CopyPtrFromStruct(mxcd.paDetails, vol, Len(vol))
'
' Set the control value.
'
rc = mixerSetControlDetails(hmixer, mxcd, MIXER_SETCONTROLDETAILSF_VALUE)
Call GlobalFree(hmem)If MMSYSERR_NOERROR = rc Then
    fSetVolumeControl = True
Else
    fSetVolumeControl = False
End If
End FunctionPublic Function meOpenMixer() As Long
Dim rc  As Long
Dim bOK As Boolean
'
' Open the mixer with deviceID 0.
'
rc = mixerOpen(hmixer, 0, 0, 0, 0)
mvarprMixerErr = rc
If MMSYSERR_NOERROR <> rc Then
    MsgBox "Could not open the mixer.", vbCritical, "Volume Control"
    Exit Function
End If
'
' Get the waveout volume control.
'
bOK = fGetVolumeControl(hmixer, _
        MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, _
        MIXERCONTROL_CONTROLTYPE_VOLUME, volCtrl)
'
' If the function successfully gets the volume control,
' the maximum and minimum values are specified by
' lMaximum and lMinimum.
'
If bOK Then
        mvarprSpeakerMaxVolume = volCtrl.lMaximum
        mvarprSpeakerMinVolume = volCtrl.lMinimum
End If
'
' Get the microphone volume control.
'
bOK = fGetVolumeControl(hmixer, _
        MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, _
        MIXERCONTROL_CONTROLTYPE_VOLUME, micCtrl)If bOK Then
        mvarprMicMaxVolume = micCtrl.lMaximum
        mvarprMicMinVolume = micCtrl.lMinimum
End If
End FunctionPublic Property Get prMixerErr() As Long
    prMixerErr = mvarprMixerErr
End PropertyPublic Property Get prSpeakerMinVolume() As Long
    prSpeakerMinVolume = mvarprSpeakerMinVolume
End PropertyPublic Property Get prSpeakerMaxVolume() As Long
    prSpeakerMaxVolume = mvarprSpeakerMaxVolume
End PropertyPublic Property Let prSpeakerVolume(ByVal vData As Long)
    mvarprSpeakerVolume = vData
    Call fSetVolumeControl(hmixer, volCtrl, vData)
End PropertyPublic Property Get prSpeakerVolume() As Long
    prSpeakerVolume = mvarprSpeakerVolume
End PropertyPublic Property Get prMicMinVolume() As Long
    prMicMinVolume = mvarprMicMinVolume
End PropertyPublic Property Get prMicMaxVolume() As Long
    prMicMaxVolume = mvarprMicMaxVolume
End PropertyPublic Property Let prMicVolume(ByVal vData As Long)
    mvarprMicVolume = vData
    Call fSetVolumeControl(hmixer, micCtrl, vData)
End PropertyPublic Property Get prMicVolume() As Long
    prMicVolume = mvarprMicVolume
End Property