Teranas писал(а):Первая мысль проверить, какая из программ меняет эти настройки, это можно сделать, натравив RegMon.exe на эти ключи реестра
If Not s(strucMixerControl.szName) = "Усиление микрофона" Then GoTo NextControl
If Not s(strucMixerControl.szName) = "20dB boost" Then GoTo NextControl
...приведенный код служит не образцом "как надо делать", а просто - оторвал кусок не очень чистой тряпки и пытаюсь перевязать рану товарищу.
Однако, должен заметить, что я не очень понимаю способ использования этой отмычки - что, просто по timer'у все время устанавливать сей флажок?
If Not s(strucMixerLine.szName) = "Микрофон" Then GoTo NextSourceLine
If Not s(strucMixerLine.szName) = "Микрофон" Then GoTo NextSourceLine
...
If Not s(strucMixerControl.szName) = "Усиление микрофона" Then GoTo NextControl
If Not s(strucMixerLine.szName) = "Microphone" Then GoTo NextSourceLine
...
If Not s(strucMixerControl.szName) = "20dB boost" Then GoTo NextControl
Vova_2581 писал(а):А на работе на некоторых ПК я еще и такое чудо видел...
С прочтения толку не будет только в том случае, если это не приводит к пониманию. Поэтому нужно читать до тех пор, пока понимание не наступит. Что касается того топика Хакера, то его не просто нужно читать, а нужно еще и делать эксперименты. А в готовый код Sam777e при этом подглядывать. И читая топик и примеры кода добиться таки полного понимания происходящего.Vova_2581 писал(а):Вы бы лучше подсказали, где ошибка? А то... читай не читай, толку с того!
Vova_2581 писал(а):а на деле пока еще НИ ОДИН из Вас не доказал, что он на что-то способен, кроме как чесать языком. Все чешут и только ОДИН Sam777e НА ДЕЛЕ доказывает, что он не балабол! Вы уж меня простите! Говорю, как есть.
Sam777e писал(а):Увидел удивительную ситуацию:
1. вызов [ с успешным кодом возврата ] mixerGetControlDetails
НЕ формирует в details значения; я специально ставил там разные числа и они оставались неизменными.
2. вызов [ с успешным кодом возврата ] mixerSetControlDetails
НЕЗАВИСИМО от посылаемого в details значения - хоть Clng(True), хоть Clng(False) приводит к вожделенному появлению галочки в нужном чек-боксе ??!!. А если она там уже была, то ничего не меняется.
bon818 писал(а):С какой стати, кому то нужно вам, что то доказывать?
Vova_2581 писал(а):Я ПРОШУ помочь, а не ТРЕБУЮ - узрите разницу! Если ваше время такое драгоценное, то пожалуйста не пишите сюда ничего, займитесь своими драгоценными делами и НЕ ЧИТАЙТЕ мой пост, очень большая просьба ко всем: НЕ ПИШИТЕ ничего сюда, если Вам нечего сказать или некогда.
Так что не пишите, если Вам по фиг. Заранее спасибо за понимание.
Vova_2581 писал(а):Я НЕ УЧИЛСЯ НА ПРОГРАММИСТА и именно потому обратился на этот форум к профессионалам, чтобы помогли делом
Vova_2581 писал(а):Я ПРОШУ помочь, а не ТРЕБУЮ - узрите разницу!
Хакер писал(а):К тому же, отдельным сообщением хочу сказать, что я совершенно не понимаю, почему ты ожидаешь мой микшер?
Не прав. Вот например до этого топика я не имел не малейшего понятия, как этот микшер работает, можно было конечно искать информацию по крупицам. В MSDN можно найти описание отдельных функций, но Хакер описал именно концепцию в общем "как это работает". И в этом топике это есть самая ценная информация, потому что все изложено предельно понятно на нормальном русском языке. А уже примеры это как дополнение к теории. Имея знания теории любые примеры на эту тему становятся вполне понятными и их можно вполне понять. А можно вместо примеров воспользоваться тем же MSDN и читая описания функций сделать то что требуется. А ценность готового куска кода, без понимания как он работает практически нулевая, изменилось окружение (другой компьютер с измененным микшером) и все затык. Автор примера не имеет компьютера с таким окружением, а автор топика не хочет разобраться в работе примера и все - тупик. А для других полезность топика не том, что бы где то управлять микрофоном (это всего лишь мелкий частный случай), а в том чтобы можно было разобравшись с работой микшера сделать свое решение в том виде, в котором оно может потребоваться.Vova_2581 писал(а):Скажите, пожалуйста, неужели Вы на самом деле свято верите, что все, кто будет в будущем посещать этот топик, станут разбираться в теории?? Я Вас умоляю! 99.999% даже не станут читать то, что мы тут с Вами пишем, а будут искать и скачивать себе готовые коды в приложениях. Я не прав???
Мне пришлось сказать ему:
— Есть кое-что повыше справедливости!
— Ого! — сказал Зарецкий. — Это интересно! Говорите, я вас с удовольствием послушаю. Внимание, господа! Так что же выше справедливости?
— Да что угодно, — отвечаю.
— Ну, а если более конкретно?
— Если более конкретно — милосердие...
ger_kar писал(а):Хакер описал именно концепцию в общем "как это работает". И в этом топике это есть самая ценная информация
ger_kar писал(а): потому что все изложено предельно понятно на нормальном русском языке.
ger_kar писал(а):А уже примеры это как дополнение к теории. Имея знания теории любые примеры на эту тему становятся вполне понятными и их можно вполне понять.
ger_kar писал(а): воспользоваться тем же MSDN и читая описания функций сделать то что требуется.
К тому же, отдельным сообщением хочу сказать, что я совершенно не понимаю, почему ты ожидаешь мой микшер?
Кстати, давно хочу написать замену стандартному микшеру
ger_kar писал(а):вместо примеров воспользоваться тем же MSDN и читая описания функций сделать то что требуется
ger_kar писал(а):А ценность готового куска кода, без понимания как он работает практически нулевая
ger_kar писал(а): изменилось окружение (другой компьютер с измененным микшером) и все затык.
Vova_2581 писал(а):Я думаю, ответ очевиден!
Чтобы сразу прояснить ситуацию решил дать ответ на этот момент. А суть тут в следующем. Вообще есть два вида структур использующих строки. В одних на строки есть только указатель, а сам строковый буфер идет отдельно, в других (например MIXERCAPS) сам строковый буфер входит в состав указанной структуры. Для второго варианта объявить такой буфер в составе структуры можно только таким способом szPName As String * MAXPNAMELEN ' product name и тут сразу надо вспомнить про то, что длина указывается в символах, а на хранение каждого символа VB6 отводит 2 байта. И далее у нас есть 2 варианта функций mixerGetControlDetailsA и mixerGetControlDetailsW. Для каждой из этих функций есть свой вариант структуры, разница между ними в том, что для одной используется текстовый буфер с 1 байтом на символ, а в другой 2 байта, и длина этих структур будет естественно разной.Sam777e писал(а):Стал приглядываться к коду. Почти везде длина структуры использует LenB, но есть места, где просто Len. Понять суть мне не дано, увы ...
Sam777e писал(а):А вот великий математик Владимир Игоревич Арнольд любил цитировать небезызвестного Ньютона, который полагал, что "Примеры важнее правил"
ger_kar писал(а):Решил таки сделать перечислитель всего и вся, что содержится в миксере (для примера).
ger_kar писал(а):... Надеюсь пояснил понятно.
Option Explicit
'[КОНСТАНТЫ И ПЕРЕЧИСЛЕНИЯ WIN API]
'
Private Const MAXPNAMELEN As Long = 32
Private Const MIXER_LONG_NAME_CHARS As Long = 64
Private Const MIXER_SHORT_NAME_CHARS As Long = 16
'
Private Const MMSYSERR_BASE As Long = 0
Private Const MMSYSERR_ALLOCATED As Long = (MMSYSERR_BASE + 4)
Private Const MMSYSERR_BADDB As Long = (MMSYSERR_BASE + 14)
Private Const MMSYSERR_BADDEVICEID As Long = (MMSYSERR_BASE + 2)
Private Const MMSYSERR_BADERRNUM As Long = (MMSYSERR_BASE + 9)
Private Const MMSYSERR_DELETEERROR As Long = (MMSYSERR_BASE + 18)
Private Const MMSYSERR_ERROR As Long = (MMSYSERR_BASE + 1)
Private Const MMSYSERR_HANDLEBUSY As Long = (MMSYSERR_BASE + 12)
Private Const MMSYSERR_INVALFLAG As Long = (MMSYSERR_BASE + 10)
Private Const MMSYSERR_INVALHANDLE As Long = (MMSYSERR_BASE + 5)
Private Const MMSYSERR_INVALIDALIAS As Long = (MMSYSERR_BASE + 13)
Private Const MMSYSERR_INVALPARAM As Long = (MMSYSERR_BASE + 11)
Private Const MMSYSERR_KEYNOTFOUND As Long = (MMSYSERR_BASE + 15)
Private Const MMSYSERR_LASTERROR As Long = (MMSYSERR_BASE + 13)
Private Const MMSYSERR_MOREDATA As Long = (MMSYSERR_BASE + 21)
Private Const MMSYSERR_NODRIVER As Long = (MMSYSERR_BASE + 6)
Private Const MMSYSERR_NODRIVERCB As Long = (MMSYSERR_BASE + 20)
'
Private Const MMSYSERR_NOERROR As Long = 0
Private Const MMSYSERR_NOMEM As Long = (MMSYSERR_BASE + 7)
Private Const MMSYSERR_NOTENABLED As Long = (MMSYSERR_BASE + 3)
Private Const MMSYSERR_NOTSUPPORTED As Long = (MMSYSERR_BASE + 8)
Private Const MMSYSERR_READERROR As Long = (MMSYSERR_BASE + 16)
Private Const MMSYSERR_VALNOTFOUND As Long = (MMSYSERR_BASE + 19)
Private Const MMSYSERR_WRITEERROR As Long = (MMSYSERR_BASE + 17)
'
Private Const MIXER_GETCONTROLDETAILSF_LISTTEXT As Long = &H1&
Private Const MIXER_GETCONTROLDETAILSF_QUERYMASK As Long = &HF&
Private Const MIXER_GETCONTROLDETAILSF_VALUE As Long = &H0&
Private Const MIXER_GETLINECONTROLSF_ALL As Long = &H0&
Private Const MIXER_GETLINECONTROLSF_ONEBYID As Long = &H1&
Private Const MIXER_GETLINECONTROLSF_ONEBYTYPE As Long = &H2&
Private Const MIXER_GETLINECONTROLSF_QUERYMASK As Long = &HF&
'
Private Const MIXER_GETLINEINFOF_COMPONENTTYPE As Long = &H3&
Private Const MIXER_GETLINEINFOF_DESTINATION As Long = &H0&
Private Const MIXER_GETLINEINFOF_LINEID As Long = &H2&
Private Const MIXER_GETLINEINFOF_QUERYMASK As Long = &HF&
Private Const MIXER_GETLINEINFOF_SOURCE As Long = &H1&
Private Const MIXER_GETLINEINFOF_TARGETTYPE As Long = &H4&
'
Private Const MIXER_OBJECTF_MIXER As Long = &H0&
Private Const MIXER_OBJECTF_AUX As Long = &H50000000
Private Const MIXER_OBJECTF_HANDLE As Long = &H80000000
Private Const MIXER_OBJECTF_MIDIIN As Long = &H40000000
Private Const MIXER_OBJECTF_MIDIOUT As Long = &H30000000
Private Const MIXER_OBJECTF_WAVEIN As Long = &H20000000
Private Const MIXER_OBJECTF_WAVEOUT As Long = &H10000000
Private Const MIXER_OBJECTF_HMIDIIN As Long = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIIN)
Private Const MIXER_OBJECTF_HMIDIOUT As Long = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIDIOUT)
Private Const MIXER_OBJECTF_HMIXER As Long = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_MIXER)
Private Const MIXER_OBJECTF_HWAVEIN As Long = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEIN)
Private Const MIXER_OBJECTF_HWAVEOUT As Long = (MIXER_OBJECTF_HANDLE Or MIXER_OBJECTF_WAVEOUT)
'
Private Const MIXERCONTROL_CT_CLASS_FADER As Long = &H50000000
Private Const MIXERCONTROL_CT_UNITS_UNSIGNED As Long = &H30000
Private Const MIXERCONTROL_CONTROLTYPE_FADER As Long = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Private Const MIXERCONTROL_CONTROLTYPE_VOLUME As Long = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
'[СТРУКТУРЫ WIN API]
'
'[MIXERCAPS]
Private Type MIXERCAPS
wMid As Integer ' manufacturer id
wPid As Integer ' product id
vDriverVersion As Long ' version of the driver
szPName As String * MAXPNAMELEN ' product name
fdwSupport As Long ' misc. support bits
cDestinations As Long ' count of destinations
End Type
'[MIXERCONTROL]
Private Type MIXERCONTROL
cbStruct As Long ' size Byte of MIXERCONTROL
dwControlID As Long ' unique control id for mixer device
dwControlType As Long ' MIXERCONTROL_CONTROLTYPE_xxx
fdwControl As Long ' MIXERCONTROL_CONTROLF_xxx
cMultipleItems As Long ' if MIXERCONTROL_CONTROLF_MULTIPLE set
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
IMinimum As Long
IMaximum As Long
Metrics(9) As Long
End Type
'[MIXERCONTROLDETAILS]
Private Type MIXERCONTROLDETAILS
cbStruct As Long ' size Byte of MIXERCONTROLDETAILS
dwControlID As Long ' control id to get/set details on
cChannels As Long ' number of channels paDetails array
item As Long ' hwndOwner or cMultipleItems
cbDetails As Long ' size of _one_ details_XX struct
paDetails As Long ' pointer to array of details_XX structs
End Type
'[Target]
Private Type Target
dwType As Long ' MIXERLINE_TARGETTYPE_xxxx
dwDeviceID As Long ' target device ID of device type
wMid As Integer ' of target device
wPid As Integer ' "
vDriverVersion As Long ' "
szPName As String * MAXPNAMELEN
End Type
'[MIXERLINE]
Private Type MIXERLINE
cbStruct As Long ' size of MIXERLINE structure
dwDestination As Long ' zero based destinationdex
dwSource As Long ' zero based sourcedex (if source)
dwLineID As Long ' unique line id for mixer device
fdwLine As Long ' state/information about line
dwUser As Long ' driver specificformation
dwComponentType As Long ' component type line connects to
cChannels As Long ' number of channels line supports
cConnections As Long ' number of connections (possible)
cControls As Long ' number of controls at this line
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
lpTarget As Target
End Type
'[MIXERLINECONTROLS]
Private Type MIXERLINECONTROLS
cbStruct As Long ' size Byte of MIXERLINECONTROLS
dwLineID As Long ' line id (from MIXERLINE.dwLineID)
'{Union '
dwControl As Long ' MIXER_GETLINECONTROLSF_ONEBYID or MIXER_GETLINECONTROLSF_ONEBYTYPE
'}
cControls As Long ' count of controls pmxctrl points to
cbMxCtrl As Long ' size Byte of _one_ MIXERCONTROL
paMxCtrl As Long ' pointer to first MIXERCONTROL array
End Type
'[ФУНКЦИИ WIN API (Используются юникодные варианты функций!!!)]
'
'[mixerGetNumDevs]
Private Declare Function mixerGetNumDevs Lib "winmm.dll" () As Long
'[mixerGetDevCaps]
Private Declare Function mixerGetDevCaps Lib "winmm.dll" Alias "mixerGetDevCapsW" ( _
ByVal uMxId As Long, _
ByVal pMIXERCAPS As Long, _
ByVal cbmxcaps As Long _
) As Long
'[mixerOpen]
Private Declare Function mixerOpen Lib "winmm.dll" ( _
ByRef phmx As Long, _
ByVal uMxId As Long, _
ByVal dwCallback As Long, _
ByVal dwInstance As Long, _
ByVal fdwOpen As Long _
) As Long
'[mixerClose]
Private Declare Function mixerClose Lib "winmm.dll" ( _
ByVal hmx As Long _
) As Long
'[mixerGetLineInfo]
Private Declare Function mixerGetLineInfo Lib "winmm.dll" Alias "mixerGetLineInfoW" ( _
ByVal hmxobj As Long, _
ByVal pMIXERLINE As Long, _
ByVal fdwInfo As Long _
) As Long
'[mixerGetLineControls]
Private Declare Function mixerGetLineControls Lib "winmm.dll" Alias "mixerGetLineControlsW" ( _
ByVal hmxobj As Long, _
ByVal pMIXERLINECONTROLS As Long, _
ByVal fdwControls As Long _
) As Long
'[mixerGetControlDetails]
Private Declare Function mixerGetControlDetails Lib "winmm.dll" Alias "mixerGetControlDetailsW" ( _
ByVal hmxobj As Long, _
ByVal pMIXERCONTROLDETAILS As Long, _
ByVal fdwDetails As Long _
) As Long
'[mixerGetID]
Private Declare Function mixerGetID Lib "winmm.dll" ( _
ByVal hmxobj As Long, _
ByRef pumxID As Long, _
ByVal fdwId As Long _
) As Long
'[mixerMessage]
Private Declare Function mixerMessage Lib "winmm.dll" ( _
ByVal hmx As Long, _
ByVal uMsg As Long, _
ByVal dwParam1 As Long, _
ByVal dwParam2 As Long _
) As Long
'[mixerSetControlDetails]
Private Declare Function mixerSetControlDetails Lib "winmm.dll" ( _
ByVal hmxobj As Long, _
ByRef pmxcd As MIXERCONTROLDETAILS, _
ByVal fdwDetails As Long _
) As Long
'
'[USER ENUM]
'
Public Enum OutType
Hierarchy = 0
List = 1
End Enum
'[ПЕРЕМЕННЫЕ УРОВНЯ МОДУЛЯ]
'
Private m_OutputType As OutType 'Тип вывода информации
Private m_hMixer As Long 'Хендл открытого микшера
'
'[EnumDevice]
'========================================================================================================
'ПРОЦЕДУРА ПЕРЕЧИСЛЕНИЯ УСТРОЙСТВ
'========================================================================================================
Public Sub EnumDevice(ByVal OutType As OutType)
'#[in]OutType 'Тип вывода (Иерархический или список)
Dim lStatus As Long 'Статус вызова WinAPI функций
Dim lDeviceNum As Long 'Количество устройств
Dim lDevId As Long 'Идентификатор устройства
Dim pMIXERCAPS As MIXERCAPS
m_OutputType = OutType
'
' В этой процедуре перечисляются устройства микшера. Сначала получаем количество устройств в системе
' и цикле делаем их перебор. Для каждого найденного устройства вызывается процедура перечисления
' всех линий, которые это устройство содержит.
'
lDeviceNum = mixerGetNumDevs()
'Перечисление устройств в цикле (отсчет идентификаторов от 0)
For lDevId = 0 To lDeviceNum - 1
'Получение данных устройства в структуру MIXERCAPS
lStatus = mixerGetDevCaps(lDevId, VarPtr(pMIXERCAPS), LenB(pMIXERCAPS))
If lStatus = MMSYSERR_NOERROR Then
'Вывод полученного имени устройства и вызов перечислений для его линий
If m_OutputType = Hierarchy Then Call PrintInfo(0, "Device - " & GetBSTR(pMIXERCAPS.szPName))
Call EnumLine(lDevId, pMIXERCAPS.cDestinations)
End If
Next
End Sub
'[EnumLine]
'========================================================================================================
'ПРОЦЕДУРА ПЕРЕЧИСЛЕНИЯ ЛИНИЙ ДЛЯ ОТДЕЛЬНОГО УСТРОЙСТВА МИКШЕРА
'========================================================================================================
Private Sub EnumLine(ByVal lDevId As Long, ByVal lLineCount As Long)
'#[in]lDevId 'Идентификатор устройства
'#[in]lLineCount 'Количество линий устройства
Dim lStatus As Long 'Статус вызова WinAPI функций
Dim lLineId As Long 'Идентификатор линии
Dim lConnect As Long 'Номер соединения
Dim pMxLine As MIXERLINE
'
' В этой процедуре перечисляются все линии одного устройства микшера.
' Перед работой с устройством его необходимо открыть, а после использования закрыть.
' Перечисляются все линии назначения (DESTINATION) по идентификатору (отсчет от 0)
' Для каждой линии (DESTINATION) вызывается процедура перечисления контролов и далее
' идет перечисление всех связанных с этой линией источников (SOURCE). Для каждой линии
' источника также вызывается процедура перечисления контролов связанных с ней.
' Линии источников идентифицируется полями структуры MIXERLINE (.dwDestination и .dwSource)
'
lStatus = mixerOpen(m_hMixer, lDevId, 0, 0, MIXER_OBJECTF_MIXER)
If lStatus = MMSYSERR_NOERROR Then
pMxLine.cbStruct = LenB(pMxLine)
'Цикл обхода линий назначения (DESTINATION)
For lLineId = 0 To lLineCount - 1
pMxLine.dwDestination = lLineId
If m_OutputType = Hierarchy Then Call PrintInfo(1, "LINE OF DESTINATION")
lStatus = mixerGetLineInfo(m_hMixer, VarPtr(pMxLine), MIXER_GETLINEINFOF_DESTINATION)
If lStatus = MMSYSERR_NOERROR Then
'Вывод наименования линии и вызов процедуры перечисления всех её контролов
If m_OutputType = Hierarchy Then Call PrintInfo(2, "Line - " & GetBSTR(pMxLine.szName))
Call EnumControls(pMxLine.dwLineID, pMxLine.cControls)
If m_OutputType = Hierarchy Then Call PrintInfo(2, "LINE OF SOURCE")
'Цикл обхода линий источников (SOURCE)
For lConnect = 0 To pMxLine.cConnections - 1
pMxLine.dwSource = lConnect
lStatus = mixerGetLineInfo(m_hMixer, VarPtr(pMxLine), MIXER_GETLINEINFOF_SOURCE)
If lStatus = MMSYSERR_NOERROR Then
'Вывод наименования линии и вызов процедуры перечисления всех её контролов
If m_OutputType = Hierarchy Then Call PrintInfo(2, "Line - " & GetBSTR(pMxLine.szName))
Call EnumControls(pMxLine.dwLineID, pMxLine.cControls)
End If
Next
If m_OutputType = Hierarchy Then Call PrintInfo(2, vbNullString)
End If
Next
lStatus = mixerClose(m_hMixer)
End If
End Sub
'[EnumControls]
'========================================================================================================
'ПРОЦЕДУРА ПЕРЕЧИСЛЕНИЯ КОНТРОЛОВ
'========================================================================================================
Private Sub EnumControls(ByVal lLineId As Long, ByVal lCtrlCount As Long)
'#[in]lLineId 'Идентификатор линии
'#[in]lCtrlCount 'Количество контролов
Dim lStatus As Long 'Статус вызова WinAPI функций
Dim lCtrlId As Long 'Идентификатор контрола
Dim cbMxCtrl As Long 'Размер структуры MIXERCONTROL в байтах
Dim pMxCtrl() As MIXERCONTROL 'Массив структур MIXERCONTROL
Dim pMxLnCtrls As MIXERLINECONTROLS
'
' В этой процедуре перечисляются все контролы одной линии и для каждого контрола
' вызывается обработчик в который передается ссылка на структуру MIXERCONTROL
'
If lCtrlCount < 1 Then Exit Sub
'Инициализация массива структур MIXERCONTROL по количеству lCtrlCount
ReDim pMxCtrl(lCtrlCount - 1): cbMxCtrl = LenB(pMxCtrl(0))
For lCtrlId = 0 To UBound(pMxCtrl)
'Для каждого элемента заполняется поле указавающее размер структуры
pMxCtrl(lCtrlId).cbStruct = cbMxCtrl
Next
'MIXERLINECONTROLS
With pMxLnCtrls
.cbStruct = LenB(pMxLnCtrls) 'Размер структуры MIXERLINECONTROLS
.cbMxCtrl = cbMxCtrl 'Размео одного элемента MIXERCONTROL
.paMxCtrl = VarPtr(pMxCtrl(0)) 'Указатель на MIXERCONTROL
.dwLineID = lLineId 'Идентификатор линии
.cControls = lCtrlCount 'Количество контролов
End With
lStatus = mixerGetLineControls(m_hMixer, VarPtr(pMxLnCtrls), MIXER_GETLINECONTROLSF_ALL)
If lStatus = MMSYSERR_NOERROR Then
'После получение массива контролов обходим его и для каждого контрола вызываем обработчик
For lCtrlId = 0 To UBound(pMxCtrl)
If m_OutputType = Hierarchy Then Call PrintInfo(3, "Control - " & GetBSTR(pMxCtrl(lCtrlId).szName))
Call HandlerControls(pMxCtrl(lCtrlId))
Next
End If
End Sub
'[HandlerControls]
'========================================================================================================
'ПРОЦЕДУРА ОБРАБОТЧИК КОНТРОЛОВ МИКШЕРА
'========================================================================================================
Private Sub HandlerControls(ByRef pCtrl As MIXERCONTROL)
If m_OutputType = List Then Call PrintInfo(0, GetBSTR(pCtrl.szName))
' Эта процедура вызывается для всех найденых контролов микшера в процессе перечисления
' Данные содержаться в структуре MIXERCONTROL
' Используя эти данные здесь можно реализовать логику идентификации нужных контролов
' После чего для отобранных контролов(контрола) можно вызвать mixerGetControlDetails
' для анализа состояния и mixerSetControlDetails для установки нового состояния
End Sub
'[GetBSTR]
'========================================================================================================
'ФУНКЦИЯ ВОЗВРАЩАЕТ СТРОКУ BSTR ПОЛУЧЕННУЮ ИЗ СТРОКОВОГО БУФЕРА ЗАВЕРШАЕМОГО НУЛЕМ
'========================================================================================================
Private Function GetBSTR(ByVal pszBuff As String) As String
'#[in] pszBuff 'Ссылка на тектовый буфер с завершающим нулём
'#[out]GetBSTR 'Обычная строка VB (BSTR)
GetBSTR = Left$(pszBuff, InStr(1, pszBuff, vbNullChar) - 1)
End Function
'[PrintInfo]
'========================================================================================================
'ПРОЦЕДУРА ВЫВОДА ОТЛАДОЧНОЙ ИНФОРМАЦИИ О ПЕРИЧИСЛЯЕМЫХ ЭЛЕМЕНТАХ МИКШЕРА
'========================================================================================================
Private Sub PrintInfo(ByVal Level As Long, ByVal sTextOut As String)
'#[in]Level 'Уровень в иерархии вывода
'#[in]sTextOut 'Выводимая строка
Debug.Print Space(Level * 4) & sTextOut
'
' Вместо вывода отладочной информации можно реализовать вывод в лог
' или другие места по необходимости
'
End Sub
Sub Main()
Call EnumDevice(Hierarchy)
' Call EnumDevice(List)
End Sub
Сейчас этот форум просматривают: SemrushBot и гости: 16