mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 08:41:41 +00:00
[SNDVOL32] Implement the volume control for the tray window.
This commit is contained in:
parent
f5960cea70
commit
c73c7cc16e
1 changed files with 186 additions and 1 deletions
|
@ -7,6 +7,22 @@
|
|||
|
||||
#include "sndvol32.h"
|
||||
|
||||
typedef struct _DIALOG_DATA
|
||||
{
|
||||
HMIXER hMixer;
|
||||
DWORD volumeControlID;
|
||||
DWORD volumeChannels;
|
||||
DWORD volumeMinimum;
|
||||
DWORD volumeMaximum;
|
||||
DWORD volumeStep;
|
||||
|
||||
DWORD maxVolume;
|
||||
DWORD maxChannel;
|
||||
PMIXERCONTROLDETAILS_UNSIGNED volumeInitValues;
|
||||
PMIXERCONTROLDETAILS_UNSIGNED volumeCurrentValues;
|
||||
} DIALOG_DATA, *PDIALOG_DATA;
|
||||
|
||||
|
||||
static VOID
|
||||
OnTrayInitDialog(
|
||||
HWND hwnd,
|
||||
|
@ -40,11 +56,147 @@ OnTrayInitDialog(
|
|||
SetWindowPos(hwnd, HWND_TOPMOST, x, y, 0, 0, SWP_NOSIZE);
|
||||
|
||||
/* Disable the controls for now */
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_LINE_SLIDER_VERT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_LINE_SWITCH), FALSE);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
OnTrayInitMixer(
|
||||
PDIALOG_DATA pDialogData,
|
||||
HWND hwndDlg)
|
||||
{
|
||||
MIXERLINE mxln;
|
||||
MIXERCONTROL mxc;
|
||||
MIXERLINECONTROLS mxlctrl;
|
||||
MIXERCONTROLDETAILS mxcd;
|
||||
DWORD i;
|
||||
|
||||
/* Open the mixer */
|
||||
if (mixerOpen(&pDialogData->hMixer, 0, PtrToUlong(hwndDlg), 0, MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR)
|
||||
return;
|
||||
|
||||
/* Retrieve the mixer information */
|
||||
mxln.cbStruct = sizeof(MIXERLINE);
|
||||
mxln.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
|
||||
|
||||
if (mixerGetLineInfo((HMIXEROBJ)pDialogData->hMixer, &mxln, MIXER_OBJECTF_HMIXER | MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
|
||||
return;
|
||||
|
||||
pDialogData->volumeChannels = mxln.cChannels;
|
||||
|
||||
/* Retrieve the line information */
|
||||
mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
|
||||
mxlctrl.dwLineID = mxln.dwLineID;
|
||||
mxlctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
|
||||
mxlctrl.cControls = 1;
|
||||
mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
|
||||
mxlctrl.pamxctrl = &mxc;
|
||||
|
||||
if (mixerGetLineControls((HMIXEROBJ)pDialogData->hMixer, &mxlctrl, MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
|
||||
return;
|
||||
|
||||
pDialogData->volumeControlID = mxc.dwControlID;
|
||||
pDialogData->volumeMinimum = mxc.Bounds.dwMinimum;
|
||||
pDialogData->volumeMaximum = mxc.Bounds.dwMaximum;
|
||||
pDialogData->volumeStep = (pDialogData->volumeMaximum - pDialogData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
|
||||
|
||||
/* Allocate a buffer for all channel volume values */
|
||||
pDialogData->volumeInitValues = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
|
||||
if (pDialogData->volumeInitValues == NULL)
|
||||
return;
|
||||
|
||||
pDialogData->volumeCurrentValues = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
mxln.cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
|
||||
if (pDialogData->volumeCurrentValues == NULL)
|
||||
return;
|
||||
|
||||
/* Retrieve the channel volume values */
|
||||
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||||
mxcd.dwControlID = mxc.dwControlID;
|
||||
mxcd.cChannels = mxln.cChannels;
|
||||
mxcd.cMultipleItems = 0;
|
||||
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
|
||||
mxcd.paDetails = pDialogData->volumeInitValues;
|
||||
|
||||
if (mixerGetControlDetails((HMIXEROBJ)pDialogData->hMixer, &mxcd, MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
|
||||
return;
|
||||
|
||||
pDialogData->maxVolume = pDialogData->volumeInitValues[0].dwValue;
|
||||
pDialogData->maxChannel = 0;
|
||||
for (i = 1; i < pDialogData->volumeChannels; i++)
|
||||
{
|
||||
if (pDialogData->volumeInitValues[i].dwValue > pDialogData->maxVolume)
|
||||
{
|
||||
pDialogData->maxVolume = pDialogData->volumeInitValues[i].dwValue;
|
||||
pDialogData->maxChannel = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the volume trackbar */
|
||||
SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_SETRANGE, TRUE, MAKELONG(VOLUME_MIN, VOLUME_MAX));
|
||||
SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_SETPAGESIZE, 0, VOLUME_PAGE_SIZE);
|
||||
SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_SETPOS, TRUE, VOLUME_MAX -(pDialogData->maxVolume - pDialogData->volumeMinimum) / pDialogData->volumeStep);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
OnVScroll(
|
||||
PDIALOG_DATA pDialogData,
|
||||
HWND hwndDlg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
MIXERCONTROLDETAILS mxcd;
|
||||
DWORD dwPos, dwVolume, i;
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case TB_THUMBTRACK:
|
||||
|
||||
dwPos = VOLUME_MAX - (DWORD)SendDlgItemMessage(hwndDlg, IDC_LINE_SLIDER_VERT, TBM_GETPOS, 0, 0);
|
||||
dwVolume = (dwPos * pDialogData->volumeStep) + pDialogData->volumeMinimum;
|
||||
|
||||
for (i = 0; i < pDialogData->volumeChannels; i++)
|
||||
{
|
||||
if (i == pDialogData->maxChannel)
|
||||
{
|
||||
pDialogData->volumeCurrentValues[i].dwValue = dwVolume;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDialogData->volumeCurrentValues[i].dwValue =
|
||||
pDialogData->volumeInitValues[i].dwValue * dwVolume / pDialogData-> maxVolume;
|
||||
}
|
||||
}
|
||||
|
||||
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
|
||||
mxcd.dwControlID = pDialogData->volumeControlID;
|
||||
mxcd.cChannels = pDialogData->volumeChannels;
|
||||
mxcd.cMultipleItems = 0;
|
||||
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
|
||||
mxcd.paDetails = pDialogData->volumeCurrentValues;
|
||||
|
||||
mixerSetControlDetails((HMIXEROBJ)pDialogData->hMixer,
|
||||
&mxcd,
|
||||
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
|
||||
break;
|
||||
|
||||
case TB_ENDTRACK:
|
||||
PlaySound((LPCTSTR)SND_ALIAS_SYSTEMDEFAULT, NULL, SND_ASYNC | SND_ALIAS_ID);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
INT_PTR
|
||||
CALLBACK
|
||||
TrayDlgProc(
|
||||
|
@ -53,10 +205,43 @@ TrayDlgProc(
|
|||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
PDIALOG_DATA pDialogData;
|
||||
|
||||
pDialogData = (PDIALOG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
OnTrayInitDialog(hwndDlg, wParam, lParam);
|
||||
|
||||
pDialogData = (PDIALOG_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIALOG_DATA));
|
||||
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pDialogData);
|
||||
|
||||
if (pDialogData)
|
||||
OnTrayInitMixer(pDialogData, hwndDlg);
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
if (pDialogData)
|
||||
OnVScroll(pDialogData, hwndDlg, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
if (pDialogData)
|
||||
{
|
||||
if (pDialogData->volumeInitValues)
|
||||
HeapFree(GetProcessHeap(), 0, pDialogData->volumeInitValues);
|
||||
|
||||
if (pDialogData->volumeCurrentValues)
|
||||
HeapFree(GetProcessHeap(), 0, pDialogData->volumeCurrentValues);
|
||||
|
||||
if (pDialogData->hMixer)
|
||||
mixerClose(pDialogData->hMixer);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pDialogData);
|
||||
pDialogData = NULL;
|
||||
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue