Code Swap Request - Master Volume Class for Remote Application Control

  • Thread starter Christopher A. Kelly
  • Start date
C

Christopher A. Kelly

I need to figure out how to control any 3rd party application by
simulating mouse click and key presses. I need to take a partial window
title and get the handle then be able to send the necessary input to the
application, I have been trying for weeks to figure this out and can't.

In trade i am posting a master volume class that i modified and added
functions to.


Imports System
Imports System.Runtime.InteropServices

Public Class class_Audio_Mixer

#Region "Constants"
Private Const MMSYSERR_NOERROR As Integer = 0
Private Const MAXPNAMELEN As Integer = 32
Private Const MIXER_LONG_NAME_CHARS As Integer = 64
Private Const MIXER_SHORT_NAME_CHARS As Integer = 16
Private Const MIXERCONTROL_CT_CLASS_FADER As Integer = &H50000000
Private Const MIXERCONTROL_CT_UNITS_UNSIGNED As Integer = &H30000
Private Const MIXERCONTROL_CT_UNITS_BOOLEAN As Integer = &H10000
Private Const MIXERCONTROL_CT_CLASS_SWITCH As Integer = &H20000000
Private Const MIXERLINE_COMPONENTTYPE_DST_FIRST As Integer = &H0&
Private Const MIXER_GETLINEINFOF_COMPONENTTYPE As Integer = &H3&
Private Const MIXER_GETLINECONTROLSF_ONEBYTYPE As Integer = &H2
Private Const MIXER_GETCONTROLDETAILSF_VALUE As Integer = &H0
Private Const MIXER_SETCONTROLDETAILSF_VALUE As Integer = &H0
Private Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS As Integer =
(MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)
Private Const MIXERCONTROL_CONTROLTYPE_FADER As Integer =
(MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Private Const MIXERCONTROL_CONTROLTYPE_VOLUME As Integer =
(MIXERCONTROL_CONTROLTYPE_FADER + 1)
Private Const MIXERCONTROL_CONTROLTYPE_BASS As Integer =
(MIXERCONTROL_CONTROLTYPE_FADER + 2)
Private Const MIXERCONTROL_CONTROLTYPE_TREBLE As Integer =
(MIXERCONTROL_CONTROLTYPE_FADER + 3)
Private Const MIXERCONTROL_CONTROLTYPE_EQUALIZER As Integer =
(MIXERCONTROL_CONTROLTYPE_FADER + 4)
Private Const MIXERCONTROL_CONTROLTYPE_BOOLEAN As Integer =
(MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Private Const MIXERCONTROL_CONTROLTYPE_MUTE As Integer =
(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
#End Region

#Region "Api Declaration"

Private Declare Function mixerClose Lib "winmm.dll" (ByVal hmx As
Integer) As Integer
Private Declare Function mixerGetControlDetailsA Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal
fdwDetails As Integer) As Integer
Private Declare Function mixerGetDevCapsA Lib "winmm.dll" (ByVal
uMxId As Integer, ByVal pmxcaps As MIXERCAPS, ByVal cbmxcaps As Integer)
As Integer
Private Declare Function mixerGetID Lib "winmm.dll" (ByVal hmxobj
As Integer, ByVal pumxID As Integer, ByVal fdwId As Integer) As Integer
Private Declare Function mixerGetLineControlsA Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxlc As MIXERLINECONTROLS, ByVal
fdwControls As Integer) As Integer
Private Declare Function mixerGetLineInfoA Lib "winmm.dll" (ByVal
hmxobj As Integer, ByRef pmxl As MIXERLINE, ByVal fdwInfo As Integer) As
Integer
Private Declare Function mixerGetNumDevs Lib "winmm.dll" () As Integer
Private Declare Function mixerMessage Lib "winmm.dll" (ByVal hmx As
Integer, ByVal uMsg As Integer, ByVal dwParam1 As Integer, ByVal
dwParam2 As Integer) As Integer
Private Declare Function mixerOpen Lib "winmm.dll" (ByRef phmx As
Integer, ByVal uMxId As Integer, ByVal dwCallback As Integer, ByVal
dwInstance As Integer, ByVal fdwOpen As Integer) As Integer
Private Declare Function mixerSetControlDetails Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDETAILS, ByVal
fdwDetails As Integer) As Integer

#End Region

#Region "Structures"

Private Structure MIXERCAPS
Public wMid As Integer
Public wPid As Integer
Public vDriverVersion As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)>
Public szPname As String
Public fdwSupport As Integer
Public cDestinations As Integer
End Structure 'MIXERCAPS


Private Structure MIXERCONTROL
Public cbStruct As Integer
Public dwControlID As Integer
Public dwControlType As Integer
Public fdwControl As Integer
Public cMultipleItems As Integer
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MIXER_SHORT_NAME_CHARS)> Public szShortName As String
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MIXER_LONG_NAME_CHARS)> Public szName As String
Public lMinimum As Integer
Public lMaximum As Integer
<MarshalAs(UnmanagedType.U4, SizeConst:=10)> Public reserved As
Integer
End Structure 'MIXERCONTROL


Private Structure MIXERCONTROLDETAILS
Public cbStruct As Integer
Public dwControlID As Integer
Public cChannels As Integer
Public item As Integer
Public cbDetails As Integer
Public paDetails As IntPtr
End Structure 'MIXERCONTROLDETAILS


Private Structure MIXERCONTROLDETAILS_UNSIGNED
Public dwValue As Integer
End Structure 'MIXERCONTROLDETAILS_UNSIGNED


Private Structure MIXERLINE
Public cbStruct As Integer
Public dwDestination As Integer
Public dwSource As Integer
Public dwLineID As Integer
Public fdwLine As Integer
Public dwUser As Integer
Public dwComponentType As Integer
Public cChannels As Integer
Public cConnections As Integer
Public cControls As Integer
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MIXER_SHORT_NAME_CHARS)> Public szShortName As String
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MIXER_LONG_NAME_CHARS)> Public szName As String
Public dwType As Integer
Public dwDeviceID As Integer
Public wMid As Integer
Public wPid As Integer
Public vDriverVersion As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)>
Public szPname As String
End Structure 'MIXERLINE


Private Structure MIXERLINECONTROLS
Public cbStruct As Integer
Public dwLineID As Integer

Public dwControl As Integer
Public cControls As Integer
Public cbmxctrl As Integer
Public pamxctrl As IntPtr
End Structure 'MIXERLINECONTROLS
#End Region

#Region "Internal Functions"
Private Shared Function GetVolumeControl(ByVal hmixer As Integer,
ByVal componentType As Integer, _
ByVal ctrlType As Integer, ByRef mxc As MIXERCONTROL, ByRef
vCurrentVol As Integer) As Boolean
' This function attempts to obtain a mixer control.
' Returns True if successful.
Dim mxlc As New MIXERLINECONTROLS
Dim mxl As New MIXERLINE
Dim pmxcd As New MIXERCONTROLDETAILS
Dim du As New MIXERCONTROLDETAILS_UNSIGNED
mxc = New MIXERCONTROL
Dim rc As Integer
Dim retValue As Boolean
vCurrentVol = -1

mxl.cbStruct = Marshal.SizeOf(mxl)
mxl.dwComponentType = componentType

rc = mixerGetLineInfoA(hmixer, mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE)

If MMSYSERR_NOERROR = rc Then
Dim sizeofMIXERCONTROL As Integer = 152
Dim ctrl As Integer = Marshal.SizeOf(GetType(MIXERCONTROL))
mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL)
mxlc.cbStruct = Marshal.SizeOf(mxlc)
mxlc.dwLineID = mxl.dwLineID
mxlc.dwControl = ctrlType
mxlc.cControls = 1
mxlc.cbmxctrl = sizeofMIXERCONTROL

' Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONTROL

' Get the control
rc = mixerGetLineControlsA(hmixer, mxlc,
MIXER_GETLINECONTROLSF_ONEBYTYPE)

If MMSYSERR_NOERROR = rc Then
retValue = True

' Copy the control into the destination structure
mxc = CType(Marshal.PtrToStructure(mxlc.pamxctrl,
GetType(MIXERCONTROL)), MIXERCONTROL)
Else
retValue = False
End If
Dim sizeofMIXERCONTROLDETAILS As Integer =
Marshal.SizeOf(GetType(MIXERCONTROLDETAILS))
Dim sizeofMIXERCONTROLDETAILS_UNSIGNED As Integer =
Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED))
pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS
pmxcd.dwControlID = mxc.dwControlID
pmxcd.paDetails =
Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED)
pmxcd.cChannels = 1
pmxcd.item = 0
pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED

rc = mixerGetControlDetailsA(hmixer, pmxcd,
MIXER_GETCONTROLDETAILSF_VALUE)

du = CType(Marshal.PtrToStructure(pmxcd.paDetails,
GetType(MIXERCONTROLDETAILS_UNSIGNED)),
kcVoiceControl.class_Audio_Mixer.MIXERCONTROLDETAILS_UNSIGNED)

vCurrentVol = du.dwValue

Return retValue
End If

retValue = False
Return retValue
End Function 'GetVolumeControl

Private Shared Function SetVolumeControl(ByVal hmixer As Integer,
ByVal mxc As MIXERCONTROL, ByVal volume As Integer) As Boolean
Try
Dim retValue As Boolean
Dim rc As Integer
Dim mxcd As New MIXERCONTROLDETAILS
Dim vol As New MIXERCONTROLDETAILS_UNSIGNED

mxcd.item = 0
mxcd.dwControlID = mxc.dwControlID
mxcd.cbStruct = Marshal.SizeOf(mxcd)
mxcd.cbDetails = Marshal.SizeOf(vol)

' Allocate a buffer for the control value buffer
mxcd.cChannels = 1
vol.dwValue = volume

' Copy the data into the control value buffer
mxcd.paDetails =
Marshal.AllocCoTaskMem(Marshal.SizeOf(GetType(MIXERCONTROLDETAILS_UNSIGNED)))
Marshal.StructureToPtr(vol, mxcd.paDetails, False)

' Set the control value
rc = mixerSetControlDetails(hmixer, mxcd,
MIXER_SETCONTROLDETAILSF_VALUE)

If MMSYSERR_NOERROR = rc Then
retValue = True
Else
retValue = False
End If
Return retValue
Catch ex As Exception
kcIntFunc.kcHandleError(ex,
System.Reflection.MethodInfo.GetCurrentMethod)
Return False
End Try
End Function 'SetVolumeControl
#End Region

#Region "Exposed Functions"
Public Function GetVolume() As Integer
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer
mixerOpen(mixer, 0, 0, 0, 0)
GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
MIXERCONTROL_CONTROLTYPE_VOLUME, volCtrl, currentVol)
mixerClose(mixer)

Dim kcCurrentPercent As Integer = CInt(((currentVol * 100) /
volCtrl.lMaximum))
Return kcCurrentPercent
End Function

Public Function GetMute() As Boolean
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer
mixerOpen(mixer, 0, 0, 0, 0)
GetVolumeControl(mixer, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
MIXERCONTROL_CONTROLTYPE_MUTE, volCtrl, currentVol)
mixerClose(mixer)

Return CBool(currentVol)
End Function

Public Sub SetVolume(ByVal vVolume As Integer)
Try
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer = GetVolume()
mixerOpen(mixer, 0, 0, 0, 0)
GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, MIXERCONTROL_CONTROLTYPE_VOLUME,
volCtrl, currentVol)

If vVolume > 100 Then
vVolume = 100
Else
If vVolume < 0 Then
vVolume = 0
End If
End If

Dim kcNewVolume As Integer = CInt(((volCtrl.lMaximum *
vVolume) / 100))
SetVolumeControl(mixer, volCtrl, kcNewVolume)
mixerClose(mixer)
Catch ex As Exception
kcIntFunc.kcHandleError(ex,
System.Reflection.MethodInfo.GetCurrentMethod)
End Try
End Sub

Public Sub SetMute(ByVal boolMute As Boolean)
Try
Dim mixer As Integer
Dim volCtrl As New MIXERCONTROL
Dim currentVol As Integer = GetVolume()
Dim lngVolSetting As Integer

' Obtain the hmixer struct
mixerOpen(mixer, 0, 0, 0, 0)

GetVolumeControl(mixer,
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, MIXERCONTROL_CONTROLTYPE_MUTE,
volCtrl, currentVol)

If boolMute = True Then
lngVolSetting = 1
Else
lngVolSetting = 0
End If

SetVolumeControl(mixer, volCtrl, lngVolSetting)
mixerClose(mixer)
Catch ex As Exception
kcIntFunc.kcHandleError(ex,
System.Reflection.MethodInfo.GetCurrentMethod)
End Try
End Sub

Public Sub ToggleMute()
If GetMute() = False Then
SetMute(True)
Else
SetMute(False)
End If
End Sub

Public Sub VolumeDown(ByVal DeltaValue As Integer)
SetVolume(kcVol.GetVolume - DeltaValue)
End Sub

Public Sub VolumeUp(ByVal DeltaValue As Integer)
SetVolume(GetVolume() + DeltaValue)
End Sub
#End Region

End Class
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top