https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c73c7cc16efa53e9208ac…
commit c73c7cc16efa53e9208acd64d1931c4a806e8692
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sat Feb 2 14:43:30 2019 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sat Feb 2 14:44:14 2019 +0100
[SNDVOL32] Implement the volume control for the tray window.
---
base/applications/sndvol32/tray.c | 187 +++++++++++++++++++++++++++++++++++++-
1 file changed, 186 insertions(+), 1 deletion(-)
diff --git a/base/applications/sndvol32/tray.c b/base/applications/sndvol32/tray.c
index 2223aadaef..e871520d64 100644
--- a/base/applications/sndvol32/tray.c
+++ b/base/applications/sndvol32/tray.c
@@ -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: