https://git.reactos.org/?p=reactos.git;a=commitdiff;h=431f9bf3110b6868ab2d0…
commit 431f9bf3110b6868ab2d08fab0812841bc0a7f6e
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Jan 20 21:59:45 2019 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Jan 20 22:00:42 2019 +0100
[MMSYS] Improvements to the speaker volume property page
- Open a separate mixer instance for the page, so that MM_MIXM_CONTROL_CHANGE
notifications can be received.
- Keep line and channel configurations in a global struct.
- Handle MM_MIXM_CONTROL_CHANGE and WM_HSCROLL notifications.
---
dll/cpl/mmsys/mmsys.c | 14 ++--
dll/cpl/mmsys/mmsys.h | 6 +-
dll/cpl/mmsys/speakervolume.c | 169 +++++++++++++++++++++++++++++++++++-------
dll/cpl/mmsys/volume.c | 2 +-
4 files changed, 153 insertions(+), 38 deletions(-)
diff --git a/dll/cpl/mmsys/mmsys.c b/dll/cpl/mmsys/mmsys.c
index c7c1ca9a6e..e2d7c8e539 100644
--- a/dll/cpl/mmsys/mmsys.c
+++ b/dll/cpl/mmsys/mmsys.c
@@ -733,11 +733,11 @@ MmSysApplet(HWND hwnd,
psh.ppsp = psp;
psh.pfnCallback = PropSheetProc;
- InitPropSheetPage(&psp[0], IDD_VOLUME,VolumeDlgProc, 0);
- InitPropSheetPage(&psp[1], IDD_SOUNDS,SoundsDlgProc, 0);
- InitPropSheetPage(&psp[2], IDD_AUDIO,AudioDlgProc, 0);
- InitPropSheetPage(&psp[3], IDD_VOICE,VoiceDlgProc, 0);
- InitPropSheetPage(&psp[4], IDD_HARDWARE,HardwareDlgProc, 0);
+ InitPropSheetPage(&psp[0], IDD_VOLUME,VolumeDlgProc);
+ InitPropSheetPage(&psp[1], IDD_SOUNDS,SoundsDlgProc);
+ InitPropSheetPage(&psp[2], IDD_AUDIO,AudioDlgProc);
+ InitPropSheetPage(&psp[3], IDD_VOICE,VoiceDlgProc);
+ InitPropSheetPage(&psp[4], IDD_HARDWARE,HardwareDlgProc);
return (LONG)(PropertySheet(&psh) != -1);
}
@@ -745,8 +745,7 @@ MmSysApplet(HWND hwnd,
VOID
InitPropSheetPage(PROPSHEETPAGE *psp,
WORD idDlg,
- DLGPROC DlgProc,
- LPARAM lParam)
+ DLGPROC DlgProc)
{
ZeroMemory(psp, sizeof(PROPSHEETPAGE));
psp->dwSize = sizeof(PROPSHEETPAGE);
@@ -754,7 +753,6 @@ InitPropSheetPage(PROPSHEETPAGE *psp,
psp->hInstance = hApplet;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pfnDlgProc = DlgProc;
- psp->lParam = lParam;
}
diff --git a/dll/cpl/mmsys/mmsys.h b/dll/cpl/mmsys/mmsys.h
index 63d6b2d900..0fdae63c8c 100644
--- a/dll/cpl/mmsys/mmsys.h
+++ b/dll/cpl/mmsys/mmsys.h
@@ -48,8 +48,7 @@ VOID
InitPropSheetPage(
PROPSHEETPAGE *psp,
WORD idDlg,
- DLGPROC DlgProc,
- LPARAM lParam);
+ DLGPROC DlgProc);
LONG APIENTRY
MmSysApplet(HWND hwnd,
@@ -93,7 +92,6 @@ AudioDlgProc(HWND hwndDlg,
/* speakervolume.c */
INT_PTR
-SpeakerVolume(HWND hwndDlg,
- HMIXER hMixer);
+SpeakerVolume(HWND hwndDlg);
#endif /* _MMSYS_H */
diff --git a/dll/cpl/mmsys/speakervolume.c b/dll/cpl/mmsys/speakervolume.c
index 270cdfcd02..4acb5a82c5 100644
--- a/dll/cpl/mmsys/speakervolume.c
+++ b/dll/cpl/mmsys/speakervolume.c
@@ -7,30 +7,48 @@
#include "mmsys.h"
+typedef struct _PAGE_DATA
+{
+ HMIXER hMixer;
+ DWORD volumeControlID;
+ DWORD volumeChannels;
+ DWORD volumeMinimum;
+ DWORD volumeMaximum;
+ DWORD volumeStep;
+ PMIXERCONTROLDETAILS_UNSIGNED volumeValues;
+} PAGE_DATA, *PPAGE_DATA;
+
+
static
BOOL
OnInitDialog(
- HWND hwndDlg,
- LPARAM lParam)
+ PPAGE_DATA pPageData,
+ HWND hwndDlg)
{
TCHAR szBuffer[256];
MIXERLINE mxln;
MIXERCONTROL mxc;
MIXERLINECONTROLS mxlctrl;
MIXERCONTROLDETAILS mxcd;
- MIXERCONTROLDETAILS_UNSIGNED mxcdVolume[8];
INT i, j;
- DWORD dwStep;
- HMIXER hMixer;
- hMixer = (HMIXER)((LPPROPSHEETPAGE)lParam)->lParam;
+ /* Open the mixer */
+ if (mixerOpen(&pPageData->hMixer, 0, PtrToUlong(hwndDlg), 0,
MIXER_OBJECTF_MIXER | CALLBACK_WINDOW) != MMSYSERR_NOERROR)
+ {
+ MessageBox(hwndDlg, _T("Cannot open mixer"), NULL, MB_OK);
+ return FALSE;
+ }
+ /* Retrieve the mixer information */
mxln.cbStruct = sizeof(MIXERLINE);
mxln.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
- if (mixerGetLineInfo((HMIXEROBJ)hMixer, &mxln, MIXER_OBJECTF_HMIXER |
MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
+ if (mixerGetLineInfo((HMIXEROBJ)pPageData->hMixer, &mxln, MIXER_OBJECTF_HMIXER
| MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
return FALSE;
+ pPageData->volumeChannels = mxln.cChannels;
+
+ /* Retrieve the line information */
mxlctrl.cbStruct = sizeof(MIXERLINECONTROLS);
mxlctrl.dwLineID = mxln.dwLineID;
mxlctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
@@ -38,39 +56,46 @@ OnInitDialog(
mxlctrl.cbmxctrl = sizeof(MIXERCONTROL);
mxlctrl.pamxctrl = &mxc;
- if (mixerGetLineControls((HMIXEROBJ)hMixer, &mxlctrl, MIXER_OBJECTF_HMIXER |
MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
+ if (mixerGetLineControls((HMIXEROBJ)pPageData->hMixer, &mxlctrl,
MIXER_OBJECTF_HMIXER | MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR)
return FALSE;
-// pGlobalData->volumeMinimum = mxc.Bounds.dwMinimum;
-// pGlobalData->volumeMaximum = mxc.Bounds.dwMaximum;
-// pGlobalData->volumeControlID = mxc.dwControlID;
-// pGlobalData->volumeStep = (pGlobalData->volumeMaximum -
pGlobalData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
- dwStep = (mxc.Bounds.dwMaximum - mxc.Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
+ pPageData->volumeControlID = mxc.dwControlID;
+ pPageData->volumeMinimum = mxc.Bounds.dwMinimum;
+ pPageData->volumeMaximum = mxc.Bounds.dwMaximum;
+ pPageData->volumeStep = (pPageData->volumeMaximum -
pPageData->volumeMinimum) / (VOLUME_MAX - VOLUME_MIN);
+ /* Allocate a buffer for all channel volume values */
+ pPageData->volumeValues = HeapAlloc(GetProcessHeap(),
+ 0,
+ mxln.cChannels *
sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+ if (pPageData->volumeValues == NULL)
+ return FALSE;
+
+ /* 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 = &mxcdVolume;
+ mxcd.paDetails = pPageData->volumeValues;
- if (mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_OBJECTF_HMIXER |
MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
+ if (mixerGetControlDetails((HMIXEROBJ)pPageData->hMixer, &mxcd,
MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
return FALSE;
-// pGlobalData->volumeValue[i] = mxcdVolume[i].dwValue;
-
/* Initialize the channels */
for (i = 0; i < min(mxln.cChannels, 5); i++)
{
j = i * 4;
- LoadString(hApplet, 5792 + i, szBuffer, _countof(szBuffer));
+
+ /* Set the channel name */
+ LoadString(hApplet, IDS_SPEAKER_LEFT + i, szBuffer, _countof(szBuffer));
SetWindowText(GetDlgItem(hwndDlg, 9472 + j), szBuffer);
+ /* Initialize the channel trackbar */
SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETRANGE, (WPARAM)TRUE,
(LPARAM)MAKELONG(VOLUME_MIN, VOLUME_MAX));
SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETTICFREQ, VOLUME_TICFREQ, 0);
SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPAGESIZE, 0, VOLUME_PAGESIZE);
-// SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE,
(LPARAM)(pGlobalData->volumeValue - pGlobalData->volumeMinimum) /
pGlobalData->volumeStep);
- SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE,
(LPARAM)(mxcdVolume[i].dwValue - mxc.Bounds.dwMinimum) / dwStep);
+ SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE,
(LPARAM)(pPageData->volumeValues[i].dwValue - pPageData->volumeMinimum) /
pPageData->volumeStep);
}
/* Hide the unused controls */
@@ -87,6 +112,69 @@ OnInitDialog(
}
+static
+VOID
+OnMixerControlChange(
+ PPAGE_DATA pPageData,
+ HWND hwndDlg)
+{
+ MIXERCONTROLDETAILS mxcd;
+ INT i, j;
+
+ /* Retrieve the channel volume values */
+ mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ mxcd.dwControlID = pPageData->volumeControlID;
+ mxcd.cChannels = pPageData->volumeChannels;
+ mxcd.cMultipleItems = 0;
+ mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ mxcd.paDetails = pPageData->volumeValues;
+
+ if (mixerGetControlDetails((HMIXEROBJ)pPageData->hMixer, &mxcd,
MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
+ return;
+
+ for (i = 0; i < min(pPageData->volumeChannels, 5); i++)
+ {
+ j = i * 4;
+
+ SendDlgItemMessage(hwndDlg, 9475 + j, TBM_SETPOS, (WPARAM)TRUE,
(LPARAM)(pPageData->volumeValues[i].dwValue - pPageData->volumeMinimum) /
pPageData->volumeStep);
+ }
+}
+
+
+static
+VOID
+OnHScroll(
+ PPAGE_DATA pPageData,
+ HWND hwndDlg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ MIXERCONTROLDETAILS mxcd;
+ INT id, idx;
+
+ id = (INT)GetWindowLongPtr((HWND)lParam, GWLP_ID);
+ if (id < 9475 && id > 9503)
+ return;
+
+ if ((id - 9475) % 4 != 0)
+ return;
+
+ idx = (id - 9475) / 4;
+
+ pPageData->volumeValues[idx].dwValue = ((DWORD)SendDlgItemMessage(hwndDlg, id,
TBM_GETPOS, 0, 0) * pPageData->volumeStep) + pPageData->volumeMinimum;
+
+ mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
+ mxcd.dwControlID = pPageData->volumeControlID;
+ mxcd.cChannels = pPageData->volumeChannels;
+ mxcd.cMultipleItems = 0;
+ mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+ mxcd.paDetails = pPageData->volumeValues;
+
+ if (mixerSetControlDetails((HMIXEROBJ)pPageData->hMixer, &mxcd,
MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE) != MMSYSERR_NOERROR)
+ return;
+}
+
+
INT_PTR
CALLBACK
SpeakerVolumeDlgProc(
@@ -95,19 +183,51 @@ SpeakerVolumeDlgProc(
WPARAM wParam,
LPARAM lParam)
{
+ PPAGE_DATA pPageData;
+
UNREFERENCED_PARAMETER(wParam);
+ pPageData = (PPAGE_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
+
switch(uMsg)
{
case WM_INITDIALOG:
- OnInitDialog(hwndDlg, lParam);
+ pPageData = (PPAGE_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(PAGE_DATA));
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPageData);
+
+ if (pPageData)
+ {
+ OnInitDialog(pPageData, hwndDlg);
+ }
break;
case WM_DESTROY:
+ if (pPageData)
+ {
+ if (pPageData->volumeValues)
+ HeapFree(GetProcessHeap(), 0, pPageData->volumeValues);
+
+ if (pPageData->hMixer)
+ mixerClose(pPageData->hMixer);
+
+ HeapFree(GetProcessHeap(), 0, pPageData);
+ pPageData = NULL;
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL);
+ }
+ break;
+
+ case WM_HSCROLL:
+ if (pPageData)
+ OnHScroll(pPageData, hwndDlg, wParam, lParam);
break;
case WM_NOTIFY:
return TRUE;
+
+ case MM_MIXM_CONTROL_CHANGE:
+ if (pPageData)
+ OnMixerControlChange(pPageData, hwndDlg);
+ break;
}
return FALSE;
@@ -116,8 +236,7 @@ SpeakerVolumeDlgProc(
INT_PTR
SpeakerVolume(
- HWND hwnd,
- HMIXER hMixer)
+ HWND hwndDlg)
{
PROPSHEETPAGE psp[1];
PROPSHEETHEADER psh;
@@ -128,14 +247,14 @@ SpeakerVolume(
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE;
- psh.hwndParent = hwnd;
+ psh.hwndParent = hwndDlg;
psh.hInstance = hApplet;
psh.pszCaption = Caption;
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
psh.ppsp = psp;
- InitPropSheetPage(&psp[0], IDD_MULTICHANNEL, SpeakerVolumeDlgProc,
(LPARAM)hMixer);
+ InitPropSheetPage(&psp[0], IDD_MULTICHANNEL, SpeakerVolumeDlgProc);
return (LONG)(PropertySheet(&psh) != -1);
}
diff --git a/dll/cpl/mmsys/volume.c b/dll/cpl/mmsys/volume.c
index e5cda69108..2d08037484 100644
--- a/dll/cpl/mmsys/volume.c
+++ b/dll/cpl/mmsys/volume.c
@@ -443,7 +443,7 @@ VolumeDlgProc(HWND hwndDlg,
break;
case IDC_SPEAKER_VOL_BTN:
- SpeakerVolume(hwndDlg, pGlobalData->hMixer);
+ SpeakerVolume(hwndDlg);
break;
}
break;