https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c73c7cc16efa53e9208acd64d1931c4a806e8692

commit c73c7cc16efa53e9208acd64d1931c4a806e8692
Author:     Eric Kohl <[email protected]>
AuthorDate: Sat Feb 2 14:43:30 2019 +0100
Commit:     Eric Kohl <[email protected]>
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:

Reply via email to