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_Mix er
#Region "Constants"
Private Const MMSYSERR_NOERRO R As Integer = 0
Private Const MAXPNAMELEN As Integer = 32
Private Const MIXER_LONG_NAME _CHARS As Integer = 64
Private Const MIXER_SHORT_NAM E_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_COMPO NENTTYPE_DST_FI RST As Integer = &H0&
Private Const MIXER_GETLINEIN FOF_COMPONENTTY PE As Integer = &H3&
Private Const MIXER_GETLINECO NTROLSF_ONEBYTY PE As Integer = &H2
Private Const MIXER_GETCONTRO LDETAILSF_VALUE As Integer = &H0
Private Const MIXER_SETCONTRO LDETAILSF_VALUE As Integer = &H0
Private Const MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS As Integer =
(MIXERLINE_COMP ONENTTYPE_DST_F IRST + 4)
Private Const MIXERCONTROL_CO NTROLTYPE_FADER As Integer =
(MIXERCONTROL_C T_CLASS_FADER Or MIXERCONTROL_CT _UNITS_UNSIGNED )
Private Const MIXERCONTROL_CO NTROLTYPE_VOLUM E As Integer =
(MIXERCONTROL_C ONTROLTYPE_FADE R + 1)
Private Const MIXERCONTROL_CO NTROLTYPE_BASS As Integer =
(MIXERCONTROL_C ONTROLTYPE_FADE R + 2)
Private Const MIXERCONTROL_CO NTROLTYPE_TREBL E As Integer =
(MIXERCONTROL_C ONTROLTYPE_FADE R + 3)
Private Const MIXERCONTROL_CO NTROLTYPE_EQUAL IZER As Integer =
(MIXERCONTROL_C ONTROLTYPE_FADE R + 4)
Private Const MIXERCONTROL_CO NTROLTYPE_BOOLE AN As Integer =
(MIXERCONTROL_C T_CLASS_SWITCH Or MIXERCONTROL_CT _UNITS_BOOLEAN)
Private Const MIXERCONTROL_CO NTROLTYPE_MUTE As Integer =
(MIXERCONTROL_C ONTROLTYPE_BOOL EAN + 2)
#End Region
#Region "Api Declaration"
Private Declare Function mixerClose Lib "winmm.dll" (ByVal hmx As
Integer) As Integer
Private Declare Function mixerGetControl DetailsA Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDET AILS, ByVal
fdwDetails As Integer) As Integer
Private Declare Function mixerGetDevCaps A 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 mixerGetLineCon trolsA Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxlc As MIXERLINECONTRO LS, ByVal
fdwControls As Integer) As Integer
Private Declare Function mixerGetLineInf oA 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 mixerSetControl Details Lib "winmm.dll"
(ByVal hmxobj As Integer, ByRef pmxcd As MIXERCONTROLDET AILS, 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(Unma nagedType.ByVal TStr, SizeConst:=MAXP NAMELEN)>
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(Unma nagedType.ByVal TStr,
SizeConst:=MIXE R_SHORT_NAME_CH ARS)> Public szShortName As String
<MarshalAs(Unma nagedType.ByVal TStr,
SizeConst:=MIXE R_LONG_NAME_CHA RS)> Public szName As String
Public lMinimum As Integer
Public lMaximum As Integer
<MarshalAs(Unma nagedType.U4, SizeConst:=10)> Public reserved As
Integer
End Structure 'MIXERCONTROL
Private Structure MIXERCONTROLDET AILS
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 'MIXERCONTROLDE TAILS
Private Structure MIXERCONTROLDET AILS_UNSIGNED
Public dwValue As Integer
End Structure 'MIXERCONTROLDE TAILS_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(Unma nagedType.ByVal TStr,
SizeConst:=MIXE R_SHORT_NAME_CH ARS)> Public szShortName As String
<MarshalAs(Unma nagedType.ByVal TStr,
SizeConst:=MIXE R_LONG_NAME_CHA RS)> 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(Unma nagedType.ByVal TStr, SizeConst:=MAXP NAMELEN)>
Public szPname As String
End Structure 'MIXERLINE
Private Structure MIXERLINECONTRO LS
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 'MIXERLINECONTR OLS
#End Region
#Region "Internal Functions"
Private Shared Function GetVolumeContro l(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 MIXERLINECONTRO LS
Dim mxl As New MIXERLINE
Dim pmxcd As New MIXERCONTROLDET AILS
Dim du As New MIXERCONTROLDET AILS_UNSIGNED
mxc = New MIXERCONTROL
Dim rc As Integer
Dim retValue As Boolean
vCurrentVol = -1
mxl.cbStruct = Marshal.SizeOf( mxl)
mxl.dwComponent Type = componentType
rc = mixerGetLineInf oA(hmixer, mxl,
MIXER_GETLINEIN FOF_COMPONENTTY PE)
If MMSYSERR_NOERRO R = rc Then
Dim sizeofMIXERCONT ROL As Integer = 152
Dim ctrl As Integer = Marshal.SizeOf( GetType(MIXERCO NTROL))
mxlc.pamxctrl = Marshal.AllocCo TaskMem(sizeofM IXERCONTROL)
mxlc.cbStruct = Marshal.SizeOf( mxlc)
mxlc.dwLineID = mxl.dwLineID
mxlc.dwControl = ctrlType
mxlc.cControls = 1
mxlc.cbmxctrl = sizeofMIXERCONT ROL
' Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONT ROL
' Get the control
rc = mixerGetLineCon trolsA(hmixer, mxlc,
MIXER_GETLINECO NTROLSF_ONEBYTY PE)
If MMSYSERR_NOERRO R = rc Then
retValue = True
' Copy the control into the destination structure
mxc = CType(Marshal.P trToStructure(m xlc.pamxctrl,
GetType(MIXERCO NTROL)), MIXERCONTROL)
Else
retValue = False
End If
Dim sizeofMIXERCONT ROLDETAILS As Integer =
Marshal.SizeOf( GetType(MIXERCO NTROLDETAILS))
Dim sizeofMIXERCONT ROLDETAILS_UNSI GNED As Integer =
Marshal.SizeOf( GetType(MIXERCO NTROLDETAILS_UN SIGNED))
pmxcd.cbStruct = sizeofMIXERCONT ROLDETAILS
pmxcd.dwControl ID = mxc.dwControlID
pmxcd.paDetails =
Marshal.AllocCo TaskMem(sizeofM IXERCONTROLDETA ILS_UNSIGNED)
pmxcd.cChannels = 1
pmxcd.item = 0
pmxcd.cbDetails = sizeofMIXERCONT ROLDETAILS_UNSI GNED
rc = mixerGetControl DetailsA(hmixer , pmxcd,
MIXER_GETCONTRO LDETAILSF_VALUE )
du = CType(Marshal.P trToStructure(p mxcd.paDetails,
GetType(MIXERCO NTROLDETAILS_UN SIGNED)),
kcVoiceControl. class_Audio_Mix er.MIXERCONTROL DETAILS_UNSIGNE D)
vCurrentVol = du.dwValue
Return retValue
End If
retValue = False
Return retValue
End Function 'GetVolumeContr ol
Private Shared Function SetVolumeContro l(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 MIXERCONTROLDET AILS
Dim vol As New MIXERCONTROLDET AILS_UNSIGNED
mxcd.item = 0
mxcd.dwControlI D = 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.AllocCo TaskMem(Marshal .SizeOf(GetType (MIXERCONTROLDE TAILS_UNSIGNED) ))
Marshal.Structu reToPtr(vol, mxcd.paDetails, False)
' Set the control value
rc = mixerSetControl Details(hmixer, mxcd,
MIXER_SETCONTRO LDETAILSF_VALUE )
If MMSYSERR_NOERRO R = rc Then
retValue = True
Else
retValue = False
End If
Return retValue
Catch ex As Exception
kcIntFunc.kcHan dleError(ex,
System.Reflecti on.MethodInfo.G etCurrentMethod )
Return False
End Try
End Function 'SetVolumeContr ol
#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)
GetVolumeContro l(mixer, MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS,
MIXERCONTROL_CO NTROLTYPE_VOLUM E, volCtrl, currentVol)
mixerClose(mixe r)
Dim kcCurrentPercen t As Integer = CInt(((currentV ol * 100) /
volCtrl.lMaximu m))
Return kcCurrentPercen t
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)
GetVolumeContro l(mixer, MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS,
MIXERCONTROL_CO NTROLTYPE_MUTE, volCtrl, currentVol)
mixerClose(mixe r)
Return CBool(currentVo l)
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)
GetVolumeContro l(mixer,
MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS, MIXERCONTROL_CO NTROLTYPE_VOLUM E,
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))
SetVolumeContro l(mixer, volCtrl, kcNewVolume)
mixerClose(mixe r)
Catch ex As Exception
kcIntFunc.kcHan dleError(ex,
System.Reflecti on.MethodInfo.G etCurrentMethod )
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)
GetVolumeContro l(mixer,
MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS, MIXERCONTROL_CO NTROLTYPE_MUTE,
volCtrl, currentVol)
If boolMute = True Then
lngVolSetting = 1
Else
lngVolSetting = 0
End If
SetVolumeContro l(mixer, volCtrl, lngVolSetting)
mixerClose(mixe r)
Catch ex As Exception
kcIntFunc.kcHan dleError(ex,
System.Reflecti on.MethodInfo.G etCurrentMethod )
End Try
End Sub
Public Sub ToggleMute()
If GetMute() = False Then
SetMute(True)
Else
SetMute(False)
End If
End Sub
Public Sub VolumeDown(ByVa l DeltaValue As Integer)
SetVolume(kcVol .GetVolume - DeltaValue)
End Sub
Public Sub VolumeUp(ByVal DeltaValue As Integer)
SetVolume(GetVo lume() + DeltaValue)
End Sub
#End Region
End Class