ReactOS 0.4.17-dev-116-ga4b6fe9
sndvol32.c File Reference
#include "sndvol32.h"
#include <shellapi.h>
Include dependency graph for sndvol32.c:

Go to the source code of this file.

Classes

struct  _PREFERENCES_FILL_DEVICES
 

Macros

#define GetDialogData(hwndDlg, type)    ( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)
 
#define GetWindowData(hwnd, type)    ( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)
 

Typedefs

typedef struct _PREFERENCES_FILL_DEVICES PREFERENCES_FILL_DEVICES
 
typedef struct _PREFERENCES_FILL_DEVICESPPREFERENCES_FILL_DEVICES
 

Functions

static BOOL CALLBACK FillDeviceComboBox (PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context)
 
static BOOL CALLBACK PrefDlgAddLine (PSND_MIXER Mixer, LPMIXERLINE Line, UINT DisplayControls, PVOID Context)
 
static BOOL CALLBACK PrefDlgAddConnection (PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
 
static VOID UpdatePrefDlgControls (PPREFERENCES_CONTEXT Context, DWORD LineID)
 
static VOID WriteLineSettings (PPREFERENCES_CONTEXT Context, HWND hwndDlg)
 
static INT_PTR CALLBACK DlgPreferencesProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
static VOID DeleteMixerWindowControls (PMIXER_WINDOW MixerWindow)
 
static BOOL RebuildMixerWindowControls (PPREFERENCES_CONTEXT PrefContext)
 
static BOOL CALLBACK SetVolumeCallback (PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Ctx)
 
static BOOL CALLBACK MixerControlChangeCallback (PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
 
static LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
static BOOL RegisterApplicationClasses (VOID)
 
static VOID UnregisterApplicationClasses (VOID)
 
static HWND CreateApplicationWindow (WINDOW_MODE WindowMode, UINT MixerId)
 
static BOOL HandleCommandLine (LPTSTR cmdline, DWORD dwStyle, PWINDOW_MODE pMode, PUINT pMixerId)
 
int WINAPI _tWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
 

Variables

HINSTANCE hAppInstance
 
ATOM MainWindowClass
 
HWND hMainWnd
 
HANDLE hAppHeap
 
LPTSTR lpAppTitle
 
PREFERENCES_CONTEXT Preferences
 

Macro Definition Documentation

◆ GetDialogData

#define GetDialogData (   hwndDlg,
  type 
)     ( P##type )GetWindowLongPtr((hwndDlg), DWLP_USER)

Definition at line 21 of file sndvol32.c.

◆ GetWindowData

#define GetWindowData (   hwnd,
  type 
)     ( P##type )GetWindowLongPtr((hwnd), GWL_USERDATA)

Definition at line 23 of file sndvol32.c.

Typedef Documentation

◆ PPREFERENCES_FILL_DEVICES

◆ PREFERENCES_FILL_DEVICES

Function Documentation

◆ _tWinMain()

int WINAPI _tWinMain ( HINSTANCE  hInstance,
HINSTANCE  hPrevInstance,
LPTSTR  lpszCmdLine,
int  nCmdShow 
)

Definition at line 1444 of file sndvol32.c.

1448{
1449 MSG Msg;
1450 int Ret = 1;
1451 INITCOMMONCONTROLSEX Controls;
1452 WINDOW_MODE WindowMode = SMALL_MODE;
1453 UINT MixerId = 0;
1454 DWORD dwStyle;
1455
1456 UNREFERENCED_PARAMETER(hPrevInstance);
1457 UNREFERENCED_PARAMETER(nCmdShow);
1458
1461
1462 if (InitAppConfig())
1463 {
1464 dwStyle = GetStyleValue();
1465 HandleCommandLine(lpszCmdLine, dwStyle, &WindowMode, &MixerId);
1466
1467 /* load the application title */
1470 IDS_SNDVOL32))
1471 {
1472 lpAppTitle = NULL;
1473 }
1474
1475 Controls.dwSize = sizeof(INITCOMMONCONTROLSEX);
1477
1478 InitCommonControlsEx(&Controls);
1479
1480 if (WindowMode == TRAY_MODE)
1481 {
1484 NULL,
1486 0);
1487 }
1488 else
1489 {
1491 {
1492 hMainWnd = CreateApplicationWindow(WindowMode, MixerId);
1493 if (hMainWnd != NULL)
1494 {
1495 BOOL bRet;
1496 while ((bRet =GetMessage(&Msg,
1497 NULL,
1498 0,
1499 0)) != 0)
1500 {
1501 if (bRet != -1)
1502 {
1505 }
1506 }
1507
1509 Ret = 0;
1510 }
1511 else
1512 {
1513 DPRINT("Failed to create application window (LastError: %d)!\n", GetLastError());
1514 }
1515
1517 }
1518 else
1519 {
1520 DPRINT("Failed to register application classes (LastError: %d)!\n", GetLastError());
1521 }
1522 }
1523
1524 if (lpAppTitle != NULL)
1525 {
1527 }
1528
1530 }
1531 else
1532 {
1533 DPRINT("Unable to open the Volume Control registry key!\n");
1534 }
1535
1536 return Ret;
1537}
INT AllocAndLoadString(OUT LPTSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID)
Definition: misc.c:59
BOOL InitAppConfig(VOID)
Definition: misc.c:138
VOID CloseAppConfig(VOID)
Definition: misc.c:152
DWORD GetStyleValue(VOID)
Definition: misc.c:388
#define IDS_SNDVOL32
Definition: resources.h:41
#define IDD_TRAY_MASTER
Definition: resources.h:52
HINSTANCE hInstance
Definition: charmap.c:19
struct @1767 Msg[]
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:904
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
unsigned int UINT
Definition: ndis.h:50
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
struct tagINITCOMMONCONTROLSEX INITCOMMONCONTROLSEX
#define ICC_STANDARD_CLASSES
Definition: commctrl.h:73
#define ICC_BAR_CLASSES
Definition: commctrl.h:60
LPTSTR lpAppTitle
Definition: sndvol32.c:18
static BOOL HandleCommandLine(LPTSTR cmdline, DWORD dwStyle, PWINDOW_MODE pMode, PUINT pMixerId)
Definition: sndvol32.c:1383
static HWND CreateApplicationWindow(WINDOW_MODE WindowMode, UINT MixerId)
Definition: sndvol32.c:1320
HWND hMainWnd
Definition: sndvol32.c:16
static BOOL RegisterApplicationClasses(VOID)
Definition: sndvol32.c:1289
static VOID UnregisterApplicationClasses(VOID)
Definition: sndvol32.c:1313
HANDLE hAppHeap
Definition: sndvol32.c:17
HINSTANCE hAppInstance
Definition: sndvol32.c:14
enum _WINDOW_MODE WINDOW_MODE
#define DPRINT
Definition: sndvol32.h:73
@ SMALL_MODE
Definition: sndvol32.h:39
@ TRAY_MODE
Definition: sndvol32.h:40
INT_PTR CALLBACK TrayDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: tray.c:324
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define DialogBoxParam
Definition: winuser.h:5930
#define GetMessage
Definition: winuser.h:5956
#define DispatchMessage
Definition: winuser.h:5931
BOOL WINAPI DestroyWindow(_In_ HWND)

◆ CreateApplicationWindow()

static HWND CreateApplicationWindow ( WINDOW_MODE  WindowMode,
UINT  MixerId 
)
static

Definition at line 1320 of file sndvol32.c.

1323{
1324 HWND hWnd;
1325
1326 PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap,
1328 sizeof(MIXER_WINDOW));
1329 if (MixerWindow == NULL)
1330 {
1331 return NULL;
1332 }
1333
1334 MixerWindow->Mode = WindowMode;
1335 MixerWindow->MixerId = MixerId;
1336
1337 if (mixerGetNumDevs() > 0)
1338 {
1341 lpAppTitle,
1343 0, 0, 300, 315,
1344 NULL,
1348 MixerWindow);
1349 }
1350 else
1351 {
1352 LPTSTR lpErrMessage;
1353
1354 /*
1355 * no mixer devices are available!
1356 */
1357
1358 hWnd = NULL;
1359 if (AllocAndLoadString(&lpErrMessage,
1362 {
1364 lpErrMessage,
1365 lpAppTitle,
1367 LocalFree(lpErrMessage);
1368 }
1369 }
1370
1371 if (hWnd == NULL)
1372 {
1374 0,
1375 MixerWindow);
1376 }
1377
1378 return hWnd;
1379}
HWND hWnd
Definition: settings.c:17
#define IDS_NOMIXERDEVICES
Definition: resources.h:42
#define IDM_MAINMENU
Definition: resources.h:3
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
LPSTR LPTSTR
Definition: ms-dtyp.idl:131
#define WS_CAPTION
Definition: pedump.c:624
#define WS_SYSMENU
Definition: pedump.c:629
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_DLGFRAME
Definition: pedump.c:626
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_CLIPCHILDREN
Definition: pedump.c:619
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define SZ_APP_CLASS
Definition: sndvol32.h:69
WINDOW_MODE Mode
Definition: sndvol32.h:53
UINT MixerId
Definition: sndvol32.h:54
UINT WINAPI mixerGetNumDevs(void)
Definition: winmm.c:280
#define CreateWindowEx
Definition: winuser.h:5921
#define WS_EX_CONTROLPARENT
Definition: winuser.h:387
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
#define LoadMenu
Definition: winuser.h:5983
#define MessageBox
Definition: winuser.h:5988
#define MB_ICONINFORMATION
Definition: winuser.h:813

Referenced by _tWinMain().

◆ DeleteMixerWindowControls()

static VOID DeleteMixerWindowControls ( PMIXER_WINDOW  MixerWindow)
static

Definition at line 581 of file sndvol32.c.

582{
583 DWORD Index;
584
585 for(Index = 0; Index < MixerWindow->WindowCount; Index++)
586 {
587 /* destroys the window */
588 DestroyWindow(MixerWindow->Window[Index]);
589 }
590
591 /* free memory */
592 HeapFree(GetProcessHeap(), 0, MixerWindow->Window);
593
594 /* set to null */
595 MixerWindow->Window = NULL;
596 MixerWindow->WindowCount = 0;
597}
HWND * Window
Definition: sndvol32.h:50
UINT WindowCount
Definition: sndvol32.h:49
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by RebuildMixerWindowControls().

◆ DlgPreferencesProc()

static INT_PTR CALLBACK DlgPreferencesProc ( HWND  hwndDlg,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 391 of file sndvol32.c.

395{
397
398 switch (uMsg)
399 {
400 case WM_COMMAND:
401 {
402 Context = GetDialogData(hwndDlg,
404 switch (LOWORD(wParam))
405 {
406 case IDC_MIXERDEVICE:
407 {
409 {
411 (DWORD)-1);
412 }
413 break;
414 }
415
416 case IDC_LINE:
417 {
419 {
420 INT LineID;
421 INT Index;
422
423 Index = SendDlgItemMessage(hwndDlg,
424 IDC_LINE,
426 0,
427 0);
428 if (Index != CB_ERR)
429 {
430 LineID = SendDlgItemMessage(hwndDlg,
431 IDC_LINE,
433 Index,
434 0);
435 if (LineID != CB_ERR)
436 {
438 LineID);
439 }
440 }
441 }
442 break;
443 }
444
445 case IDC_PLAYBACK:
446 {
448 Context->PlaybackID);
449 EnableWindow(GetDlgItem(hwndDlg,
450 IDC_LINE),
451 FALSE);
452 break;
453 }
454
455 case IDC_RECORDING:
456 {
458 Context->RecordingID);
459 EnableWindow(GetDlgItem(hwndDlg,
460 IDC_LINE),
461 FALSE);
462 break;
463 }
464
465 case IDC_OTHER:
466 {
467 INT LineCbIndex;
468 INT LineID;
469
470 EnableWindow(GetDlgItem(hwndDlg,
471 IDC_LINE),
472 TRUE);
473
474 LineCbIndex = SendDlgItemMessage(hwndDlg,
475 IDC_LINE,
477 0,
478 0);
479 if (LineCbIndex != CB_ERR)
480 {
481 LineID = SendDlgItemMessage(hwndDlg,
482 IDC_LINE,
484 LineCbIndex,
485 0);
486 if (LineID != CB_ERR)
487 {
489 LineID);
490 }
491 }
492 break;
493 }
494
495 case IDOK:
496 {
497 /* write line settings */
498 WriteLineSettings(Context, hwndDlg);
499
500 /* fall through */
501 }
502 case IDCANCEL:
503 {
504 EndDialog(hwndDlg,
505 LOWORD(wParam));
506 break;
507 }
508 }
509 break;
510 }
511
512 case WM_INITDIALOG:
513 {
514 PREFERENCES_FILL_DEVICES FillDevContext;
515 LVCOLUMN lvc;
516 RECT rcClient;
517 HWND hwndControls;
518
519 SetWindowLongPtr(hwndDlg,
520 DWLP_USER,
523 Context->hwndDlg = hwndDlg;
524 Context->Mixer = SndMixerCreate(hwndDlg, Context->MixerWindow->MixerId);
525 Context->Selected = (UINT)-1;
526
527 FillDevContext.PrefContext = Context;
528 FillDevContext.hComboBox = GetDlgItem(hwndDlg,
530 FillDevContext.Selected = SndMixerGetSelection(Context->Mixer);
533 &FillDevContext);
534
535 /* initialize the list view control */
536 hwndControls = GetDlgItem(hwndDlg,
540
541 GetClientRect(hwndControls,
542 &rcClient);
543 lvc.mask = LVCF_TEXT | LVCF_WIDTH;
544 lvc.pszText = TEXT("");
545 lvc.cx = rcClient.right;
546 SendMessage(hwndControls,
548 0,
549 (LPARAM)&lvc);
550
551 /* update all controls */
553 (DWORD)Context->SelectedLine);
554 return TRUE;
555 }
556
557 case WM_CLOSE:
558 {
559 EndDialog(hwndDlg,
560 IDCANCEL);
561 break;
562 }
563
565 {
566 HWND hwndControls;
567
568 /* Forward WM_SYSCOLORCHANGE */
569 hwndControls = GetDlgItem(hwndDlg, IDC_CONTROLS);
570 SendMessage(hwndControls, WM_SYSCOLORCHANGE, 0, 0);
571 break;
572 }
573 }
574
575 return 0;
576}
PSND_MIXER SndMixerCreate(HWND hWndNotification, UINT MixerId)
Definition: mixer.c:69
UINT SndMixerGetSelection(PSND_MIXER Mixer)
Definition: mixer.c:361
BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context)
Definition: mixer.c:431
#define IDC_OTHER
Definition: resources.h:18
#define IDC_MIXERDEVICE
Definition: resources.h:15
#define IDC_LINE
Definition: resources.h:19
#define IDC_PLAYBACK
Definition: resources.h:16
#define IDC_RECORDING
Definition: resources.h:17
#define IDC_CONTROLS
Definition: resources.h:21
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TEXT(s)
Definition: k32.h:28
LONG_PTR LPARAM
Definition: minwindef.h:175
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define LOWORD(l)
Definition: pedump.c:82
#define LVCF_WIDTH
Definition: commctrl.h:2592
#define LVS_EX_CHECKBOXES
Definition: commctrl.h:2736
#define LVM_INSERTCOLUMN
Definition: commctrl.h:2639
#define ListView_SetExtendedListViewStyle(hwndLV, dw)
Definition: commctrl.h:2730
#define LVCF_TEXT
Definition: commctrl.h:2593
#define LVCOLUMN
Definition: commctrl.h:2586
static VOID UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context, DWORD LineID)
Definition: sndvol32.c:214
static BOOL CALLBACK FillDeviceComboBox(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context)
Definition: sndvol32.c:38
static VOID WriteLineSettings(PPREFERENCES_CONTEXT Context, HWND hwndDlg)
Definition: sndvol32.c:329
#define GetDialogData(hwndDlg, type)
Definition: sndvol32.c:21
struct _PREFERENCES_CONTEXT * PPREFERENCES_CONTEXT
_In_ PVOID Context
Definition: storport.h:2269
PPREFERENCES_CONTEXT PrefContext
Definition: sndvol32.c:32
LONG right
Definition: windef.h:108
#define SetWindowLongPtr
Definition: treelist.c:70
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
#define WM_CLOSE
Definition: winuser.h:1649
#define DWLP_USER
Definition: winuser.h:883
#define IDCANCEL
Definition: winuser.h:842
#define WM_COMMAND
Definition: winuser.h:1768
#define CB_ERR
Definition: winuser.h:2471
#define WM_INITDIALOG
Definition: winuser.h:1767
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1654
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:841
#define CBN_SELCHANGE
Definition: winuser.h:2008
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define CB_GETITEMDATA
Definition: winuser.h:1979
#define SendMessage
Definition: winuser.h:6009
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
#define CB_GETCURSEL
Definition: winuser.h:1972
#define SendDlgItemMessage
Definition: winuser.h:6008
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)

Referenced by MainWindowProc().

◆ FillDeviceComboBox()

static BOOL CALLBACK FillDeviceComboBox ( PSND_MIXER  Mixer,
UINT  Id,
LPCTSTR  ProductName,
PVOID  Context 
)
static

Definition at line 38 of file sndvol32.c.

42{
43 LRESULT lres;
45
47
48 lres = SendMessage(FillContext->hComboBox,
50 0,
51 (LPARAM)ProductName);
52 if (lres != CB_ERR)
53 {
54 /* save the index so we don't screw stuff when the combobox is sorted... */
55 SendMessage(FillContext->hComboBox,
57 (WPARAM)lres,
58 Id);
59
60 if (Id == FillContext->Selected)
61 {
62 SendMessage(FillContext->hComboBox,
64 (WPARAM)lres,
65 0);
66 }
67 }
68
69 return TRUE;
70}
DWORD Id
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
struct _PREFERENCES_FILL_DEVICES * PPREFERENCES_FILL_DEVICES
#define CB_SETITEMDATA
Definition: winuser.h:1995
#define CB_SETCURSEL
Definition: winuser.h:1990
#define CB_ADDSTRING
Definition: winuser.h:1965

Referenced by DlgPreferencesProc().

◆ HandleCommandLine()

static BOOL HandleCommandLine ( LPTSTR  cmdline,
DWORD  dwStyle,
PWINDOW_MODE  pMode,
PUINT  pMixerId 
)
static

Definition at line 1383 of file sndvol32.c.

1387{
1388 TCHAR option;
1389
1390 *pMixerId = PLAY_MIXER;
1391 *pMode = (dwStyle & 0x20) ? SMALL_MODE : NORMAL_MODE;
1392
1393 while (*cmdline == _T(' ') || *cmdline == _T('-') || *cmdline == _T('/'))
1394 {
1395 if (*cmdline++ == _T(' '))
1396 continue;
1397
1398 option = *cmdline;
1399 if (option)
1400 cmdline++;
1401 while (*cmdline == _T(' '))
1402 cmdline++;
1403
1404 switch (option)
1405 {
1406 case 'd': /* Device */
1407 case 'D':
1408 break;
1409
1410 case 'n': /* Small size */
1411 case 'N':
1412 *pMode = NORMAL_MODE;
1413 break;
1414
1415 case 's': /* Small size */
1416 case 'S':
1417 *pMode = SMALL_MODE;
1418 break;
1419
1420 case 't': /* Tray size */
1421 case 'T':
1422 *pMode = TRAY_MODE;
1423 break;
1424
1425 case 'p': /* Play mode */
1426 case 'P':
1427 *pMixerId = PLAY_MIXER;
1428 break;
1429
1430 case 'r': /* Record mode */
1431 case 'R':
1432 *pMixerId = RECORD_MIXER;
1433 break;
1434
1435 default:
1436 return FALSE;
1437 }
1438 }
1439
1440 return TRUE;
1441}
char TCHAR
Definition: tchar.h:1402
#define PLAY_MIXER
Definition: sndvol32.h:29
#define RECORD_MIXER
Definition: sndvol32.h:30
@ NORMAL_MODE
Definition: sndvol32.h:38
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: getopt.h:109
#define _T(x)
Definition: vfdio.h:22

Referenced by _tWinMain().

◆ MainWindowProc()

static LRESULT CALLBACK MainWindowProc ( HWND  hwnd,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 860 of file sndvol32.c.

864{
865 PMIXER_WINDOW MixerWindow;
866 DWORD CtrlID, LineOffset;
867 BOOL bRet;
868 LRESULT Result = 0;
870
871 switch (uMsg)
872 {
873 case WM_COMMAND:
874 {
875 MixerWindow = GetWindowData(hwnd,
877
878 switch (LOWORD(wParam))
879 {
880 case IDM_PROPERTIES:
881 {
883
884 Pref.MixerWindow = MixerWindow;
885 Pref.Mixer = NULL;
887
890 hwnd,
892 (LPARAM)&Pref) == IDOK)
893 {
894 /* update window */
895 TCHAR szProduct[MAXPNAMELEN];
896
897 /* get mixer product name */
898 if (SndMixerGetProductName(Pref.Mixer,
899 szProduct,
900 sizeof(szProduct) / sizeof(szProduct[0])) == -1)
901 {
902 /* failed to get name */
903 szProduct[0] = L'\0';
904 }
905 else
906 {
907 /* copy product */
908 wcscpy(Preferences.DeviceName, szProduct);
909 }
910
911 /* destroy old status bar */
912 if (MixerWindow->Mode == NORMAL_MODE)
913 DestroyWindow(MixerWindow->hStatusBar);
914
915 /* update details */
916 Preferences.SelectedLine = Pref.SelectedLine;
917
918 /* destroy old mixer */
920
921 /* use new selected mixer */
922 Preferences.MixerWindow->Mixer = Pref.Mixer;
923
924 /* create status window */
925 if (MixerWindow->Mode == NORMAL_MODE)
926 {
928 NULL,
929 hwnd,
930 0);
931 if (MixerWindow->hStatusBar)
932 {
933 /* Set status bar */
934 SendMessage(MixerWindow->hStatusBar,
936 0,
937 (LPARAM)szProduct);
938 }
939 }
940
941 /* rebuild dialog controls */
943 }
944 break;
945 }
946
948 MixerWindow->bShowExtendedControls = !MixerWindow->bShowExtendedControls;
953 break;
954
955 case IDM_EXIT:
956 {
959 break;
960 }
961
962 case IDM_ABOUT:
963 {
964 HICON hAppIcon = (HICON)GetClassLongPtrW(hwnd,
965 GCLP_HICON);
968 NULL,
969 hAppIcon);
970 break;
971 }
972
973 default:
974 {
975 /* get button id */
976 CtrlID = LOWORD(wParam);
977
978 /* check if the message is from the line switch */
979 if (HIWORD(wParam) == BN_CLICKED)
980 {
981 if (CtrlID % IDC_LINE_SWITCH == 0)
982 {
983 /* compute line offset */
984 LineOffset = CtrlID / IDC_LINE_SWITCH;
985
986 /* compute window id of line name static control */
987 CtrlID = LineOffset * IDC_LINE_NAME;
988
989 if (Preferences.MixerWindow->Mixer->MixerId == PLAY_MIXER)
990 {
991 /* get line name */
992 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
993 {
994 /* setup context */
995 Context.SliderPos = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
996 Context.bVertical = FALSE;
997 Context.bSwitch = TRUE;
998
999 /* set volume */
1001 }
1002 }
1003 else if (Preferences.MixerWindow->Mixer->MixerId == RECORD_MIXER)
1004 {
1005 UINT i;
1006
1007 for (i = 0; i < Preferences.MixerWindow->DialogCount; i++)
1008 {
1009 SendDlgItemMessageW(hwnd, (i + 1) * IDC_LINE_SWITCH, BM_SETCHECK, (WPARAM)((i + 1) == LineOffset), 0);
1010 }
1011 }
1012 }
1013 else if (CtrlID % IDC_LINE_ADVANCED == 0)
1014 {
1015 ADVANCED_CONTEXT AdvancedContext;
1016
1017 /* compute line offset */
1018 LineOffset = CtrlID / IDC_LINE_ADVANCED;
1019
1020 /* compute window id of line name static control */
1021 CtrlID = LineOffset * IDC_LINE_NAME;
1022
1023 /* get line name */
1024 if (GetDlgItemTextW(hwnd, CtrlID, AdvancedContext.LineName, MIXER_LONG_NAME_CHARS) != 0)
1025 {
1026 AdvancedContext.MixerWindow = Preferences.MixerWindow;
1027 AdvancedContext.Mixer = Preferences.MixerWindow->Mixer;
1030 AdvancedContext.LineName);
1031 if (AdvancedContext.Line)
1032 {
1035 hwnd,
1037 (LPARAM)&AdvancedContext);
1038 }
1039 }
1040 }
1041 }
1042 }
1043 }
1044 break;
1045 }
1046
1048 {
1049 DPRINT("MM_MIXM_LINE_CHANGE\n");
1050 break;
1051 }
1052
1054 {
1055 DPRINT("MM_MIXM_CONTROL_CHANGE\n");
1056
1057 /* get mixer window */
1058 MixerWindow = GetWindowData(hwnd,
1059 MIXER_WINDOW);
1060
1061 /* sanity checks */
1062 assert(MixerWindow);
1063 assert(MixerWindow->Mixer->hmx == (HMIXER)wParam);
1064
1066 break;
1067 }
1068
1069 case WM_VSCROLL:
1070 switch (LOWORD(wParam))
1071 {
1072 case TB_THUMBTRACK:
1073 /* get dialog item ctrl */
1074 CtrlID = GetDlgCtrlID((HWND)lParam);
1075
1076 /* get line index */
1077 LineOffset = CtrlID / IDC_LINE_SLIDER_VERT;
1078
1079 /* compute window id of line name static control */
1080 CtrlID = LineOffset * IDC_LINE_NAME;
1081
1082 /* get line name */
1083 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
1084 {
1085 /* setup context */
1086 Context.SliderPos = LineOffset;
1087 Context.bVertical = TRUE;
1088 Context.bSwitch = FALSE;
1089
1090 /* set volume */
1092 }
1093 break;
1094
1095 case TB_ENDTRACK:
1096 MixerWindow = GetWindowData(hwnd,
1097 MIXER_WINDOW);
1098
1099 /* get dialog item ctrl */
1100 CtrlID = GetDlgCtrlID((HWND)lParam);
1101
1102 /* get line index */
1103 LineOffset = CtrlID / IDC_LINE_SLIDER_VERT;
1104
1105 if (LineOffset == 1 && MixerWindow->Mixer->MixerId == 0)
1107 break;
1108
1109 default:
1110 break;
1111 }
1112 break;
1113
1114 case WM_HSCROLL:
1115 switch (LOWORD(wParam))
1116 {
1117 case TB_THUMBTRACK:
1118 /* get dialog item ctrl */
1119 CtrlID = GetDlgCtrlID((HWND)lParam);
1120
1121 /* get line index */
1122 LineOffset = CtrlID / IDC_LINE_SLIDER_HORZ;
1123
1124 /* compute window id of line name static control */
1125 CtrlID = LineOffset * IDC_LINE_NAME;
1126
1127 /* get line name */
1128 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
1129 {
1130 /* setup context */
1131 Context.SliderPos = LineOffset;
1132 Context.bVertical = TRUE;
1133 Context.bSwitch = FALSE;
1134
1135 /* set volume */
1137 }
1138 break;
1139
1140 case TB_ENDTRACK:
1141 MixerWindow = GetWindowData(hwnd,
1142 MIXER_WINDOW);
1143
1144 /* get dialog item ctrl */
1145 CtrlID = GetDlgCtrlID((HWND)lParam);
1146
1147 /* get line index */
1148 LineOffset = CtrlID / IDC_LINE_SLIDER_HORZ;
1149
1150 if (LineOffset == 1 && MixerWindow->Mixer->MixerId == 0)
1152 break;
1153
1154 default:
1155 break;
1156 }
1157 break;
1158
1159
1160 case WM_CREATE:
1161 {
1162 MixerWindow = ((LPCREATESTRUCT)lParam)->lpCreateParams;
1165 (LONG_PTR)MixerWindow);
1166 MixerWindow->hWnd = hwnd;
1167 MixerWindow->Mixer = SndMixerCreate(MixerWindow->hWnd, MixerWindow->MixerId);
1168 if (MixerWindow->Mixer != NULL)
1169 {
1170 TCHAR szProduct[MAXPNAMELEN];
1171
1172 /* get mixer product name */
1173 if (SndMixerGetProductName(MixerWindow->Mixer,
1174 szProduct,
1175 sizeof(szProduct) / sizeof(szProduct[0])) == -1)
1176 {
1177 /* failed to get name */
1178 szProduct[0] = L'\0';
1179 }
1180
1181
1182 /* initialize preferences */
1184
1185 /* store mixer */
1186 Preferences.Mixer = MixerWindow->Mixer;
1187
1188 /* store mixer window */
1189 Preferences.MixerWindow = MixerWindow;
1190
1191 /* first destination line id */
1192 Preferences.SelectedLine = 0xFFFF0000;
1193
1194 /* copy product */
1195 wcscpy(Preferences.DeviceName, szProduct);
1196
1197 /* Disable the 'Advanced Controls' menu item */
1199
1200 /* Load the placement coordinate data of the window */
1201 bRet = LoadXYCoordWnd(&Preferences);
1202 if (bRet)
1203 {
1204 /*
1205 * LoadXYCoordWnd() might fail for the first time of opening the application which is normal as
1206 * the Sound Control's applet settings haven't been saved yet to the Registry. At this point SetWindowPos()
1207 * call is skipped.
1208 */
1209 SetWindowPos(hwnd, NULL, MixerWindow->WndPosX, MixerWindow->WndPosY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1210 }
1211
1212 /* create status window */
1213 if (MixerWindow->Mode == NORMAL_MODE)
1214 {
1216 NULL,
1217 hwnd,
1218 0);
1219 if (MixerWindow->hStatusBar)
1220 {
1221 SendMessage(MixerWindow->hStatusBar,
1222 WM_SETTEXT,
1223 0,
1224 (LPARAM)szProduct);
1225 }
1226 }
1227
1229 {
1230 DPRINT("Rebuilding mixer window controls failed!\n");
1231 SndMixerDestroy(MixerWindow->Mixer);
1232 MixerWindow->Mixer = NULL;
1233 Result = -1;
1234 }
1235 }
1236
1238 break;
1239 }
1240
1241 case WM_DESTROY:
1242 {
1243 MixerWindow = GetWindowData(hwnd,
1244 MIXER_WINDOW);
1245 if (MixerWindow != NULL)
1246 {
1247 if (MixerWindow->Mixer != NULL)
1248 {
1249 SndMixerDestroy(MixerWindow->Mixer);
1250 }
1251 if (MixerWindow->hFont)
1252 DeleteObject(MixerWindow->hFont);
1253 HeapFree(hAppHeap, 0, MixerWindow);
1254 }
1255 break;
1256 }
1257
1258 case WM_CLOSE:
1259 {
1261 PostQuitMessage(0);
1262 break;
1263 }
1264
1265 case WM_HOTKEY:
1266 {
1267 if (wParam == HOTKEY_CTRL_S)
1268 {
1271 }
1272 break;
1273 }
1274
1275 default:
1276 {
1278 uMsg,
1279 wParam,
1280 lParam);
1281 break;
1282 }
1283 }
1284
1285 return Result;
1286}
#define IDD_ADVANCED
Definition: resource.h:10
#define IDM_ABOUT
Definition: resource.h:29
#define IDM_EXIT
Definition: resource.h:27
BOOL SaveXYCoordWnd(IN HWND hWnd, IN PPREFERENCES_CONTEXT PrefContext)
Definition: misc.c:218
BOOL LoadXYCoordWnd(IN PPREFERENCES_CONTEXT PrefContext)
Definition: misc.c:162
VOID SndMixerDestroy(PSND_MIXER Mixer)
Definition: mixer.c:91
LPMIXERLINE SndMixerGetLineByName(PSND_MIXER Mixer, DWORD LineID, LPWSTR LineName)
Definition: mixer.c:615
INT SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize)
Definition: mixer.c:367
BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context)
Definition: mixer.c:552
#define IDC_LINE_SLIDER_VERT
Definition: resources.h:25
#define IDM_ADVANCED_CONTROLS
Definition: resources.h:10
#define IDM_PROPERTIES
Definition: resources.h:9
#define IDC_LINE_ADVANCED
Definition: resources.h:26
#define IDD_PREFERENCES
Definition: resources.h:53
#define IDC_LINE_NAME
Definition: resources.h:22
#define IDC_LINE_SWITCH
Definition: resources.h:23
#define IDC_LINE_SLIDER_HORZ
Definition: resources.h:24
static INT_PTR CALLBACK AdvancedDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
Definition: charmap.c:480
#define assert(_expr)
Definition: assert.h:32
#define L(x)
Definition: resources.c:13
pKey DeleteObject()
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MOD_CONTROL
Definition: imm.h:185
#define ZeroMemory
Definition: minwinbase.h:31
#define PlaySound
Definition: mmsystem.h:2844
#define SND_ALIAS_SYSTEMDEFAULT
Definition: mmsystem.h:175
#define MM_MIXM_CONTROL_CHANGE
Definition: mmsystem.h:83
#define MIXER_LONG_NAME_CHARS
Definition: mmsystem.h:294
#define MM_MIXM_LINE_CHANGE
Definition: mmsystem.h:82
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define MAXPNAMELEN
Definition: mmsystem.h:24
#define SND_ASYNC
Definition: mmsystem.h:154
static HICON
Definition: imagelist.c:80
LPCSTR LPCTSTR
Definition: ms-dtyp.idl:130
#define WS_CHILD
Definition: pedump.c:617
#define TB_ENDTRACK
Definition: commctrl.h:2086
#define CreateStatusWindow
Definition: commctrl.h:1938
#define TB_THUMBTRACK
Definition: commctrl.h:2083
#define DefWindowProc
Definition: ros2win.h:31
wcscpy
#define ShellAbout
Definition: shellapi.h:737
static BOOL RebuildMixerWindowControls(PPREFERENCES_CONTEXT PrefContext)
Definition: sndvol32.c:600
static INT_PTR CALLBACK DlgPreferencesProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: sndvol32.c:391
#define GetWindowData(hwnd, type)
Definition: sndvol32.c:23
static BOOL CALLBACK SetVolumeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Ctx)
Definition: sndvol32.c:614
static BOOL CALLBACK MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: sndvol32.c:739
PREFERENCES_CONTEXT Preferences
Definition: sndvol32.c:19
#define HOTKEY_CTRL_S
Definition: sndvol32.h:34
PMIXER_WINDOW MixerWindow
Definition: sndvol32.h:135
PSND_MIXER Mixer
Definition: sndvol32.h:136
WCHAR LineName[MIXER_LONG_NAME_CHARS]
Definition: sndvol32.h:134
LPMIXERLINE Line
Definition: sndvol32.h:137
HFONT hFont
Definition: sndvol32.h:58
BOOL bShowExtendedControls
Definition: sndvol32.h:56
struct _SND_MIXER * Mixer
Definition: sndvol32.h:47
UINT DialogCount
Definition: sndvol32.h:51
HWND hStatusBar
Definition: sndvol32.h:46
TCHAR DeviceName[128]
Definition: sndvol32.h:119
PSND_MIXER Mixer
Definition: sndvol32.h:111
PMIXER_WINDOW MixerWindow
Definition: sndvol32.h:110
UINT WINAPI GetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPWSTR lpString, int nMaxCount)
Definition: dialog.c:2263
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define MF_BYCOMMAND
Definition: winuser.h:202
#define GWL_USERDATA
Definition: winuser.h:872
CREATESTRUCTA * LPCREATESTRUCT
Definition: winuser.h:5892
#define WM_HSCROLL
Definition: winuser.h:1771
#define WM_VSCROLL
Definition: winuser.h:1772
#define GCLP_HICON
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1636
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
BOOL WINAPI UnregisterHotKey(_In_opt_ HWND, _In_ int)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define MF_CHECKED
Definition: winuser.h:132
#define SWP_NOSIZE
Definition: winuser.h:1256
#define MF_UNCHECKED
Definition: winuser.h:204
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define BM_SETCHECK
Definition: winuser.h:1950
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_SETTEXT
Definition: winuser.h:1645
BOOL WINAPI RegisterHotKey(_In_opt_ HWND, _In_ int, _In_ UINT, _In_ UINT)
#define GetClassLongPtrW
Definition: winuser.h:4718
#define WM_HOTKEY
Definition: winuser.h:1907
int WINAPI GetDlgCtrlID(_In_ HWND)
#define BN_CLICKED
Definition: winuser.h:1954
#define WM_DESTROY
Definition: winuser.h:1637
#define SWP_NOZORDER
Definition: winuser.h:1258
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
HMENU WINAPI GetMenu(_In_ HWND)
#define BM_GETCHECK
Definition: winuser.h:1947
#define MF_GRAYED
Definition: winuser.h:129
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by RegisterApplicationClasses().

◆ MixerControlChangeCallback()

static BOOL CALLBACK MixerControlChangeCallback ( PSND_MIXER  Mixer,
DWORD  LineID,
LPMIXERLINE  Line,
PVOID  Context 
)
static

Definition at line 739 of file sndvol32.c.

740{
741 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
742 UINT ControlCount = 0, Index;
744
745 /* check if the line has controls */
746 if (Line->cControls == 0)
747 {
748 /* no controls */
749 return TRUE;
750 }
751
752 /* query controls */
753 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) == FALSE)
754 {
755 /* failed to query for controls */
756 return FALSE;
757 }
758
759 pVolumeDetails = HeapAlloc(GetProcessHeap(),
760 0,
761 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
762 if (pVolumeDetails == NULL)
763 goto done;
764
765 /* now go through all controls and compare control ids */
766 for (Index = 0; Index < ControlCount; Index++)
767 {
768 if (Control[Index].dwControlID == PtrToUlong(Context))
769 {
770 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
771 {
773
774 /* get volume control details */
776 {
777 /* update dialog control */
779 }
780 }
781 else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
782 {
783 /* get volume control details */
784 if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
785 {
786 /* update dialog control */
787 DWORD volumePosition, volumeStep, maxVolume, i;
788 DWORD balancePosition, balanceStep;
789
790 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
791
792 maxVolume = 0;
793 for (i = 0; i < Line->cChannels; i++)
794 {
795 if (pVolumeDetails[i].dwValue > maxVolume)
796 maxVolume = pVolumeDetails[i].dwValue;
797 }
798
799 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
800
801 if (Line->cChannels == 1)
802 {
803 balancePosition = BALANCE_CENTER;
804 }
805 else if (Line->cChannels == 2)
806 {
807 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
808 {
809 balancePosition = BALANCE_CENTER;
810 }
811 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
812 {
813 balancePosition = BALANCE_RIGHT;
814 }
815 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
816 {
817 balancePosition = BALANCE_LEFT;
818 }
819 else
820 {
821 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
822
823 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
824 {
825 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
826 balancePosition = BALANCE_RIGHT - balancePosition;
827 }
828 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
829 {
830 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
831 balancePosition = BALANCE_LEFT + balancePosition;
832 }
833 }
834 }
835
836 /* Update the volume control slider */
838
839 /* Update the balance control slider */
841 }
842 }
843 break;
844 }
845 }
846
847done:
848 /* Free the volume details */
849 if (pVolumeDetails)
850 HeapFree(GetProcessHeap(), 0, pVolumeDetails);
851
852 /* free controls */
854
855 /* done */
856 return TRUE;
857}
VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID, DWORD Position)
Definition: dialog.c:830
VOID UpdateDialogLineSwitchControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, LONG fValue)
Definition: dialog.c:805
BOOL SndMixerQueryControls(PSND_MIXER Mixer, PUINT DisplayControls, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls)
Definition: mixer.c:112
INT SndMixerGetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
Definition: mixer.c:498
#define PtrToUlong(u)
Definition: config.h:107
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
#define VOLUME_MAX
Definition: sndvol32.h:19
#define BALANCE_RIGHT
Definition: sndvol32.h:24
#define VOLUME_MIN
Definition: sndvol32.h:18
#define BALANCE_STEPS
Definition: sndvol32.h:25
#define BALANCE_CENTER
Definition: sndvol32.h:23
#define BALANCE_LEFT
Definition: sndvol32.h:22
Definition: ncftp.h:79
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166

Referenced by MainWindowProc().

◆ PrefDlgAddConnection()

static BOOL CALLBACK PrefDlgAddConnection ( PSND_MIXER  Mixer,
DWORD  LineID,
LPMIXERLINE  Line,
PVOID  Context 
)
static

Definition at line 150 of file sndvol32.c.

154{
156 HWND hwndControls;
157 LVITEM lvi;
158 UINT i;
159
162
163 if (Line->cControls != 0)
164 {
165 hwndControls = GetDlgItem(PrefContext->hwndDlg,
167
168 lvi.mask = LVIF_TEXT | LVIF_PARAM;
169 lvi.iItem = PrefContext->tmp++;
170 lvi.iSubItem = 0;
171 lvi.pszText = Line->szName;
172 lvi.lParam = (LPARAM)Line->dwSource;
173
174 i = SendMessage(hwndControls,
176 0,
177 (LPARAM)&lvi);
178 if (i != (UINT)-1)
179 {
181 DWORD Flags;
182 BOOL SelLine = FALSE;
183
184 if (SndMixerGetLineName(PrefContext->Mixer,
185 PrefContext->SelectedLine,
186 LineName,
188 TRUE) == -1)
189 {
190 LineName[0] = TEXT('\0');
191 }
192
193 if (ReadLineConfig(PrefContext->DeviceName,
194 LineName,
195 Line->szName,
196 &Flags))
197 {
198 if (Flags != 0x4)
199 {
200 SelLine = TRUE;
201 }
202 }
203
204 ListView_SetCheckState(hwndControls,
205 i,
206 SelLine);
207 }
208 }
209
210 return TRUE;
211}
BOOL ReadLineConfig(IN LPTSTR szDeviceName, IN LPTSTR szLineName, IN LPTSTR szControlName, OUT DWORD *Flags)
Definition: misc.c:307
INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName)
Definition: mixer.c:390
#define ListView_SetCheckState(hwndLV, i, fCheck)
Definition: commctrl.h:2679
#define LVM_INSERTITEM
Definition: commctrl.h:2411
#define LVITEM
Definition: commctrl.h:2380
#define LVIF_PARAM
Definition: commctrl.h:2316
#define LVIF_TEXT
Definition: commctrl.h:2314
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UpdatePrefDlgControls().

◆ PrefDlgAddLine()

static BOOL CALLBACK PrefDlgAddLine ( PSND_MIXER  Mixer,
LPMIXERLINE  Line,
UINT  DisplayControls,
PVOID  Context 
)
static

Definition at line 73 of file sndvol32.c.

77{
79
81 UNREFERENCED_PARAMETER(DisplayControls);
82
83 switch (Line->dwComponentType)
84 {
86 if (PrefContext->PlaybackID == (DWORD)-1)
87 {
88 PrefContext->PlaybackID = Line->dwLineID;
89
90 if (PrefContext->SelectedLine == (DWORD)-1)
91 {
92 PrefContext->SelectedLine = Line->dwLineID;
93 }
94 }
95 else
96 goto AddToOthersLines;
97
98 break;
99
101 if (PrefContext->RecordingID == (DWORD)-1)
102 {
103 PrefContext->RecordingID = Line->dwLineID;
104
105 if (PrefContext->SelectedLine == (DWORD)-1)
106 {
107 PrefContext->SelectedLine = Line->dwLineID;
108 }
109 }
110 else
111 goto AddToOthersLines;
112
113 break;
114
115 default:
116 {
117 LRESULT lres;
118 HWND hwndCbOthers;
119
120 if (PrefContext->SelectedLine == (DWORD)-1)
121 {
122 PrefContext->SelectedLine = Line->dwLineID;
123 }
124
125AddToOthersLines:
126 hwndCbOthers = GetDlgItem(PrefContext->hwndDlg,
127 IDC_LINE);
128
129 lres = SendMessage(hwndCbOthers,
131 0,
132 (LPARAM)Line->szName);
133 if (lres != CB_ERR)
134 {
135 SendMessage(hwndCbOthers,
137 (WPARAM)lres,
138 Line->dwLineID);
139
140 PrefContext->OtherLines++;
141 }
142 break;
143 }
144 }
145
146 return TRUE;
147}
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
#define MIXERLINE_COMPONENTTYPE_DST_WAVEIN
Definition: mmsystem.h:322

Referenced by UpdatePrefDlgControls().

◆ RebuildMixerWindowControls()

static BOOL RebuildMixerWindowControls ( PPREFERENCES_CONTEXT  PrefContext)
static

Definition at line 600 of file sndvol32.c.

601{
602 /* delete existing mixer controls */
604
605 /* load new mixer controls */
606 LoadDialogCtrls(PrefContext);
607
608 return TRUE;
609}
VOID LoadDialogCtrls(PPREFERENCES_CONTEXT PrefContext)
Definition: dialog.c:678
static VOID DeleteMixerWindowControls(PMIXER_WINDOW MixerWindow)
Definition: sndvol32.c:581

Referenced by MainWindowProc().

◆ RegisterApplicationClasses()

static BOOL RegisterApplicationClasses ( VOID  )
static

Definition at line 1289 of file sndvol32.c.

1290{
1291 WNDCLASSEX wc;
1292
1293 wc.cbSize = sizeof(WNDCLASSEX);
1296 wc.cbClsExtra = 0;
1297 wc.cbWndExtra = sizeof(PMIXER_WINDOW);
1301 wc.hCursor = LoadCursor(NULL,
1302 IDC_ARROW);
1303 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1304 wc.lpszMenuName = NULL;
1306 wc.hIconSm = NULL;
1308
1309 return MainWindowClass != 0;
1310}
#define IDI_MAINAPP
Definition: resource.h:6
ATOM MainWindowClass
Definition: sndvol32.c:15
static LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: sndvol32.c:860
struct _MIXER_WINDOW * PMIXER_WINDOW
int cbClsExtra
Definition: winuser.h:3312
HINSTANCE hInstance
Definition: winuser.h:3314
HCURSOR hCursor
Definition: winuser.h:3316
LPCSTR lpszMenuName
Definition: winuser.h:3318
HICON hIconSm
Definition: winuser.h:3320
UINT style
Definition: winuser.h:3310
int cbWndExtra
Definition: winuser.h:3313
UINT cbSize
Definition: winuser.h:3309
WNDPROC lpfnWndProc
Definition: winuser.h:3311
LPCSTR lpszClassName
Definition: winuser.h:3319
HICON hIcon
Definition: winuser.h:3315
HBRUSH hbrBackground
Definition: winuser.h:3317
#define CS_VREDRAW
Definition: winuser.h:666
#define CS_HREDRAW
Definition: winuser.h:661
#define IDC_ARROW
Definition: winuser.h:695
#define RegisterClassEx
Definition: winuser.h:6003
#define LoadIcon
Definition: winuser.h:5979
#define LoadCursor
Definition: winuser.h:5978
WNDCLASSEXA WNDCLASSEX
Definition: winuser.h:5885
#define COLOR_BTNFACE
Definition: winuser.h:939

Referenced by _tWinMain().

◆ SetVolumeCallback()

static BOOL CALLBACK SetVolumeCallback ( PSND_MIXER  Mixer,
DWORD  LineID,
LPMIXERLINE  Line,
PVOID  Ctx 
)
static

Definition at line 614 of file sndvol32.c.

615{
616 UINT ControlCount = 0, Index;
621
622 /* check if the line name is equal */
623 if (_wcsicmp(Line->szName, Context->LineName))
624 {
625 /* it is not */
626 return TRUE;
627 }
628
629 /* query controls */
630 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) == FALSE)
631 {
632 /* failed to query for controls */
633 return FALSE;
634 }
635
636 puDetails = HeapAlloc(GetProcessHeap(), 0, Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
637 if (puDetails == NULL)
638 return FALSE;
639
640 /* now go through all controls and compare control ids */
641 for (Index = 0; Index < ControlCount; Index++)
642 {
643 if (Context->bVertical)
644 {
645 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
646 {
647 DWORD LineOffset, volumePosition, balancePosition;
648 DWORD volumeStep, balanceStep;
649
650 LineOffset = Context->SliderPos;
651
652 volumePosition = (DWORD)SendDlgItemMessage(Preferences.MixerWindow->hWnd, LineOffset * IDC_LINE_SLIDER_VERT, TBM_GETPOS, 0, 0);
653 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
654
655 if (Line->cChannels == 1)
656 {
657 /* set up details */
658 puDetails[0].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
659 }
660 else if (Line->cChannels == 2)
661 {
662 balancePosition = (DWORD)SendDlgItemMessage(Preferences.MixerWindow->hWnd, LineOffset * IDC_LINE_SLIDER_HORZ, TBM_GETPOS, 0, 0);
663 if (balancePosition == BALANCE_CENTER)
664 {
665 puDetails[0].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
666 puDetails[1].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
667 }
668 else if (balancePosition == BALANCE_LEFT)
669 {
670 puDetails[0].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
671 puDetails[1].dwValue = Control[Index].Bounds.dwMinimum;
672 }
673 else if (balancePosition == BALANCE_RIGHT)
674 {
675 puDetails[0].dwValue = Control[Index].Bounds.dwMinimum;
676 puDetails[1].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
677 }
678 else if (balancePosition < BALANCE_CENTER) // Left
679 {
680 puDetails[0].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
681
682 balanceStep = (puDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
683
684 puDetails[1].dwValue = (balancePosition * balanceStep) + Control[Index].Bounds.dwMinimum;
685 }
686 else if (balancePosition > BALANCE_CENTER) // Right
687 {
688 puDetails[1].dwValue = ((VOLUME_MAX - volumePosition) * volumeStep) + Control[Index].Bounds.dwMinimum;
689
690 balanceStep = (puDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
691
692 puDetails[0].dwValue = ((BALANCE_RIGHT - balancePosition) * balanceStep) + Control[Index].Bounds.dwMinimum;
693 }
694 }
695 else
696 {
698
699 /* FIXME */
700 }
701
702 /* set volume */
704
705 /* done */
706 break;
707 }
708 }
709 else if (Context->bSwitch)
710 {
711 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
712 {
713 /* set up details */
714 bDetails.fValue = Context->SliderPos;
715
716 /* set volume */
718
719 /* done */
720 break;
721 }
722 }
723 }
724
725 if (puDetails != NULL)
726 HeapFree(GetProcessHeap(), 0, puDetails);
727
728 /* free controls */
730
731
732 /* done */
733 return TRUE;
734}
INT SndMixerSetVolumeControlDetails(PSND_MIXER Mixer, DWORD dwControlID, DWORD cChannels, DWORD cbDetails, LPVOID paDetails)
Definition: mixer.c:474
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
#define DWORD
Definition: nt_native.h:44
#define TBM_GETPOS
Definition: commctrl.h:2036
struct _SET_VOLUME_CONTEXT * PSET_VOLUME_CONTEXT

Referenced by MainWindowProc().

◆ UnregisterApplicationClasses()

static VOID UnregisterApplicationClasses ( VOID  )
static

Definition at line 1313 of file sndvol32.c.

1314{
1316 hAppInstance);
1317}
#define UnregisterClass
Definition: winuser.h:6027

Referenced by _tWinMain().

◆ UpdatePrefDlgControls()

static VOID UpdatePrefDlgControls ( PPREFERENCES_CONTEXT  Context,
DWORD  LineID 
)
static

Definition at line 214 of file sndvol32.c.

216{
217 INT OldID, MixerID = 0;
218 INT DeviceCbIndex;
219
220 /* select the mixer */
221 DeviceCbIndex = SendDlgItemMessage(Context->hwndDlg,
224 0,
225 0);
226 if (DeviceCbIndex != CB_ERR)
227 {
228 MixerID = SendDlgItemMessage(Context->hwndDlg,
231 DeviceCbIndex,
232 0);
233 if (MixerID == CB_ERR)
234 {
235 MixerID = 0;
236 }
237 }
238
239 OldID = Context->Selected;
240 if (MixerID != OldID &&
241 SndMixerSelect(Context->Mixer,
242 MixerID))
243 {
244 Context->Selected = SndMixerGetSelection(Context->Mixer);
245
246 /* update the controls */
247 Context->PlaybackID = (DWORD)-1;
248 Context->RecordingID = (DWORD)-1;
249 Context->OtherLines = 0;
250 Context->SelectedLine = (DWORD)-1;
251
253 Context->DeviceName,
254 sizeof(Context->DeviceName) / sizeof(Context->DeviceName[0]));
255
256 if (SndMixerEnumLines(Context->Mixer,
258 Context))
259 {
260 UINT SelBox = 0;
261
262 /* enable/disable controls and make default selection */
265 Context->PlaybackID != (DWORD)-1);
266 CheckDlgButton(Context->hwndDlg,
268 (Context->PlaybackID != (DWORD)-1 && SelBox++ == 0) ?
270
273 Context->RecordingID != (DWORD)-1);
274 CheckDlgButton(Context->hwndDlg,
276 (Context->RecordingID != (DWORD)-1 && SelBox++ == 0) ?
278
279 if (Context->OtherLines != 0)
280 {
281 /* select the first item in the other lines combo box by default */
283 IDC_LINE,
285 0,
286 0);
287 }
289 IDC_LINE),
290 FALSE);
292 IDC_OTHER),
293 Context->OtherLines != 0);
294 CheckDlgButton(Context->hwndDlg,
295 IDC_LINE,
296 (Context->OtherLines != 0 && SelBox++ == 0) ?
298
299 /* disable the OK button if the device doesn't have any lines */
301 IDOK),
302 Context->PlaybackID != (DWORD)-1 ||
303 Context->RecordingID != (DWORD)-1 ||
304 Context->OtherLines != 0);
305
306 LineID = Context->SelectedLine;
307 }
308 }
309
310 /* update the line sources list */
311 if ((MixerID != OldID && Context->SelectedLine != (DWORD)-1) ||
312 (Context->SelectedLine != LineID && LineID != (DWORD)-1))
313 {
314 Context->SelectedLine = LineID;
315
317 IDC_CONTROLS));
318
319 Context->tmp = 0;
321 LineID,
323 Context);
324 }
325}
BOOL SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context)
Definition: mixer.c:526
BOOL SndMixerSelect(PSND_MIXER Mixer, UINT MixerId)
Definition: mixer.c:304
#define ListView_DeleteAllItems(hwnd)
Definition: commctrl.h:2419
static BOOL CALLBACK PrefDlgAddConnection(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: sndvol32.c:150
static BOOL CALLBACK PrefDlgAddLine(PSND_MIXER Mixer, LPMIXERLINE Line, UINT DisplayControls, PVOID Context)
Definition: sndvol32.c:73
BOOL WINAPI CheckDlgButton(_In_ HWND, _In_ int, _In_ UINT)
#define BST_UNCHECKED
Definition: winuser.h:199
#define BST_CHECKED
Definition: winuser.h:197

Referenced by DlgPreferencesProc().

◆ WriteLineSettings()

static VOID WriteLineSettings ( PPREFERENCES_CONTEXT  Context,
HWND  hwndDlg 
)
static

Definition at line 329 of file sndvol32.c.

330{
331 HWND hwndControls;
332 INT Count, Index;
334 WCHAR DestinationName[MIXER_LONG_NAME_CHARS];
335 DWORD Flags;
336 PSNDVOL_REG_LINESTATE LineStates;
337
338 /* get list view */
339 hwndControls = GetDlgItem(hwndDlg, IDC_CONTROLS);
340
341 /* get list item count */
342 Count = ListView_GetItemCount(hwndControls);
343
344 /* sanity check */
345 assert(Count);
346
347 if (SndMixerGetLineName(Context->Mixer, Context->SelectedLine, DestinationName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
348 {
349 /* failed to get destination line name */
350 return;
351 }
352
353 /* allocate line states array */
355 if (LineStates == NULL)
356 {
357 /* failed to allocate line states array */
358 return;
359 }
360
361
362 for(Index = 0; Index < Count; Index++)
363 {
364 /* set to empty */
365 LineName[0] = L'\0';
366
367 /* get item text */
368 ListView_GetItemText(hwndControls, Index, 0, LineName, MIXER_LONG_NAME_CHARS);
369
370 /* make sure it is null terminated */
371 LineName[MIXER_LONG_NAME_CHARS-1] = L'\0';
372
373 /* get check state */
374 Flags = (ListView_GetCheckState(hwndControls, Index) == 0 ? 0x4 : 0);
375
376 /* copy line name */
377 wcscpy(LineStates[Index].LineName, LineName);
378
379 /* store flags */
380 LineStates[Index].Flags = Flags;
381 }
382
383 /* now write the line config */
384 WriteLineConfig(Context->DeviceName, DestinationName, LineStates, sizeof(SNDVOL_REG_LINESTATE) * Count);
385
386 /* free line states */
387 HeapFree(GetProcessHeap(), 0, LineStates);
388}
BOOL WriteLineConfig(IN LPTSTR szDeviceName, IN LPTSTR szLineName, IN PSNDVOL_REG_LINESTATE LineState, IN DWORD cbSize)
Definition: misc.c:272
int Count
Definition: noreturn.cpp:7
short WCHAR
Definition: pedump.c:58
#define ListView_GetItemText(hwndLV, i, iSubItem_, pszText_, cchTextMax_)
Definition: commctrl.h:2689
#define ListView_GetItemCount(hwnd)
Definition: commctrl.h:2312
#define ListView_GetCheckState(hwndLV, i)
Definition: commctrl.h:2682

Referenced by DlgPreferencesProc().

Variable Documentation

◆ hAppHeap

HANDLE hAppHeap

Definition at line 17 of file sndvol32.c.

Referenced by _tWinMain(), CreateApplicationWindow(), and MainWindowProc().

◆ hAppInstance

◆ hMainWnd

HWND hMainWnd

Definition at line 16 of file sndvol32.c.

Referenced by _tWinMain().

◆ lpAppTitle

LPTSTR lpAppTitle

Definition at line 18 of file sndvol32.c.

Referenced by _tWinMain(), CreateApplicationWindow(), and MainWindowProc().

◆ MainWindowClass

ATOM MainWindowClass

Definition at line 15 of file sndvol32.c.

Referenced by RegisterApplicationClasses().

◆ Preferences

PREFERENCES_CONTEXT Preferences

Definition at line 19 of file sndvol32.c.

Referenced by MainWindowProc(), MixerControlChangeCallback(), and SetVolumeCallback().