ReactOS 0.4.15-dev-8100-g1887773
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 37 of file sndvol32.c.

◆ GetWindowData

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

Definition at line 39 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 1460 of file sndvol32.c.

1464{
1465 MSG Msg;
1466 int Ret = 1;
1467 INITCOMMONCONTROLSEX Controls;
1468 WINDOW_MODE WindowMode = SMALL_MODE;
1469 UINT MixerId = 0;
1470 DWORD dwStyle;
1471
1472 UNREFERENCED_PARAMETER(hPrevInstance);
1473 UNREFERENCED_PARAMETER(nCmdShow);
1474
1477
1478 if (InitAppConfig())
1479 {
1480 dwStyle = GetStyleValue();
1481 HandleCommandLine(lpszCmdLine, dwStyle, &WindowMode, &MixerId);
1482
1483 /* load the application title */
1486 IDS_SNDVOL32))
1487 {
1488 lpAppTitle = NULL;
1489 }
1490
1491 Controls.dwSize = sizeof(INITCOMMONCONTROLSEX);
1493
1494 InitCommonControlsEx(&Controls);
1495
1496 if (WindowMode == TRAY_MODE)
1497 {
1500 NULL,
1502 0);
1503 }
1504 else
1505 {
1507 {
1508 hMainWnd = CreateApplicationWindow(WindowMode, MixerId);
1509 if (hMainWnd != NULL)
1510 {
1511 BOOL bRet;
1512 while ((bRet =GetMessage(&Msg,
1513 NULL,
1514 0,
1515 0)) != 0)
1516 {
1517 if (bRet != -1)
1518 {
1521 }
1522 }
1523
1525 Ret = 0;
1526 }
1527 else
1528 {
1529 DPRINT("Failed to create application window (LastError: %d)!\n", GetLastError());
1530 }
1531
1533 }
1534 else
1535 {
1536 DPRINT("Failed to register application classes (LastError: %d)!\n", GetLastError());
1537 }
1538 }
1539
1540 if (lpAppTitle != NULL)
1541 {
1543 }
1544
1546 }
1547 else
1548 {
1549 DPRINT("Unable to open the Volume Control registry key!\n");
1550 }
1551
1552 return Ret;
1553}
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 @1636 Msg[]
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:893
#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:317
struct tagINITCOMMONCONTROLSEX INITCOMMONCONTROLSEX
#define ICC_STANDARD_CLASSES
Definition: commctrl.h:73
#define ICC_BAR_CLASSES
Definition: commctrl.h:60
LPTSTR lpAppTitle
Definition: sndvol32.c:34
static BOOL HandleCommandLine(LPTSTR cmdline, DWORD dwStyle, PWINDOW_MODE pMode, PUINT pMixerId)
Definition: sndvol32.c:1399
static HWND CreateApplicationWindow(WINDOW_MODE WindowMode, UINT MixerId)
Definition: sndvol32.c:1336
HWND hMainWnd
Definition: sndvol32.c:32
static BOOL RegisterApplicationClasses(VOID)
Definition: sndvol32.c:1305
static VOID UnregisterApplicationClasses(VOID)
Definition: sndvol32.c:1329
HANDLE hAppHeap
Definition: sndvol32.c:33
HINSTANCE hAppInstance
Definition: sndvol32.c:30
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:262
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:5764
#define GetMessage
Definition: winuser.h:5790
#define DispatchMessage
Definition: winuser.h:5765
BOOL WINAPI DestroyWindow(_In_ HWND)
#define MAKEINTRESOURCE
Definition: winuser.h:591

◆ CreateApplicationWindow()

static HWND CreateApplicationWindow ( WINDOW_MODE  WindowMode,
UINT  MixerId 
)
static

Definition at line 1336 of file sndvol32.c.

1339{
1340 HWND hWnd;
1341
1342 PMIXER_WINDOW MixerWindow = HeapAlloc(hAppHeap,
1344 sizeof(MIXER_WINDOW));
1345 if (MixerWindow == NULL)
1346 {
1347 return NULL;
1348 }
1349
1350 MixerWindow->Mode = WindowMode;
1351 MixerWindow->MixerId = MixerId;
1352
1353 if (mixerGetNumDevs() > 0)
1354 {
1357 lpAppTitle,
1359 0, 0, 300, 315,
1360 NULL,
1364 MixerWindow);
1365 }
1366 else
1367 {
1368 LPTSTR lpErrMessage;
1369
1370 /*
1371 * no mixer devices are available!
1372 */
1373
1374 hWnd = NULL;
1375 if (AllocAndLoadString(&lpErrMessage,
1378 {
1380 lpErrMessage,
1381 lpAppTitle,
1383 LocalFree(lpErrMessage);
1384 }
1385 }
1386
1387 if (hWnd == NULL)
1388 {
1390 0,
1391 MixerWindow);
1392 }
1393
1394 return hWnd;
1395}
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
#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:5755
#define WS_EX_CONTROLPARENT
Definition: winuser.h:387
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
#define LoadMenu
Definition: winuser.h:5817
#define MessageBox
Definition: winuser.h:5822
#define MB_ICONINFORMATION
Definition: winuser.h:802
CHAR * LPTSTR
Definition: xmlstorage.h:192

Referenced by _tWinMain().

◆ DeleteMixerWindowControls()

static VOID DeleteMixerWindowControls ( PMIXER_WINDOW  MixerWindow)
static

Definition at line 597 of file sndvol32.c.

598{
599 DWORD Index;
600
601 for(Index = 0; Index < MixerWindow->WindowCount; Index++)
602 {
603 /* destroys the window */
604 DestroyWindow(MixerWindow->Window[Index]);
605 }
606
607 /* free memory */
608 HeapFree(GetProcessHeap(), 0, MixerWindow->Window);
609
610 /* set to null */
611 MixerWindow->Window = NULL;
612 MixerWindow->WindowCount = 0;
613}
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 407 of file sndvol32.c.

411{
413
414 switch (uMsg)
415 {
416 case WM_COMMAND:
417 {
418 Context = GetDialogData(hwndDlg,
420 switch (LOWORD(wParam))
421 {
422 case IDC_MIXERDEVICE:
423 {
425 {
427 (DWORD)-1);
428 }
429 break;
430 }
431
432 case IDC_LINE:
433 {
435 {
436 INT LineID;
437 INT Index;
438
439 Index = SendDlgItemMessage(hwndDlg,
440 IDC_LINE,
442 0,
443 0);
444 if (Index != CB_ERR)
445 {
446 LineID = SendDlgItemMessage(hwndDlg,
447 IDC_LINE,
449 Index,
450 0);
451 if (LineID != CB_ERR)
452 {
454 LineID);
455 }
456 }
457 }
458 break;
459 }
460
461 case IDC_PLAYBACK:
462 {
464 Context->PlaybackID);
465 EnableWindow(GetDlgItem(hwndDlg,
466 IDC_LINE),
467 FALSE);
468 break;
469 }
470
471 case IDC_RECORDING:
472 {
474 Context->RecordingID);
475 EnableWindow(GetDlgItem(hwndDlg,
476 IDC_LINE),
477 FALSE);
478 break;
479 }
480
481 case IDC_OTHER:
482 {
483 INT LineCbIndex;
484 INT LineID;
485
486 EnableWindow(GetDlgItem(hwndDlg,
487 IDC_LINE),
488 TRUE);
489
490 LineCbIndex = SendDlgItemMessage(hwndDlg,
491 IDC_LINE,
493 0,
494 0);
495 if (LineCbIndex != CB_ERR)
496 {
497 LineID = SendDlgItemMessage(hwndDlg,
498 IDC_LINE,
500 LineCbIndex,
501 0);
502 if (LineID != CB_ERR)
503 {
505 LineID);
506 }
507 }
508 break;
509 }
510
511 case IDOK:
512 {
513 /* write line settings */
514 WriteLineSettings(Context, hwndDlg);
515
516 /* fall through */
517 }
518 case IDCANCEL:
519 {
520 EndDialog(hwndDlg,
521 LOWORD(wParam));
522 break;
523 }
524 }
525 break;
526 }
527
528 case WM_INITDIALOG:
529 {
530 PREFERENCES_FILL_DEVICES FillDevContext;
531 LVCOLUMN lvc;
532 RECT rcClient;
533 HWND hwndControls;
534
535 SetWindowLongPtr(hwndDlg,
536 DWLP_USER,
539 Context->hwndDlg = hwndDlg;
540 Context->Mixer = SndMixerCreate(hwndDlg, Context->MixerWindow->MixerId);
541 Context->Selected = (UINT)-1;
542
543 FillDevContext.PrefContext = Context;
544 FillDevContext.hComboBox = GetDlgItem(hwndDlg,
546 FillDevContext.Selected = SndMixerGetSelection(Context->Mixer);
549 &FillDevContext);
550
551 /* initialize the list view control */
552 hwndControls = GetDlgItem(hwndDlg,
556
557 GetClientRect(hwndControls,
558 &rcClient);
559 lvc.mask = LVCF_TEXT | LVCF_WIDTH;
560 lvc.pszText = TEXT("");
561 lvc.cx = rcClient.right;
562 SendMessage(hwndControls,
564 0,
565 (LPARAM)&lvc);
566
567 /* update all controls */
569 (DWORD)Context->SelectedLine);
570 return TRUE;
571 }
572
573 case WM_CLOSE:
574 {
575 EndDialog(hwndDlg,
576 IDCANCEL);
577 break;
578 }
579
581 {
582 HWND hwndControls;
583
584 /* Forward WM_SYSCOLORCHANGE */
585 hwndControls = GetDlgItem(hwndDlg, IDC_CONTROLS);
586 SendMessage(hwndControls, WM_SYSCOLORCHANGE, 0, 0);
587 break;
588 }
589 }
590
591 return 0;
592}
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:26
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define LOWORD(l)
Definition: pedump.c:82
#define LVCF_WIDTH
Definition: commctrl.h:2587
#define LVS_EX_CHECKBOXES
Definition: commctrl.h:2731
#define LVM_INSERTCOLUMN
Definition: commctrl.h:2634
#define ListView_SetExtendedListViewStyle(hwndLV, dw)
Definition: commctrl.h:2725
#define LVCF_TEXT
Definition: commctrl.h:2588
#define LVCOLUMN
Definition: commctrl.h:2581
static VOID UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context, DWORD LineID)
Definition: sndvol32.c:230
static BOOL CALLBACK FillDeviceComboBox(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context)
Definition: sndvol32.c:54
static VOID WriteLineSettings(PPREFERENCES_CONTEXT Context, HWND hwndDlg)
Definition: sndvol32.c:345
#define GetDialogData(hwndDlg, type)
Definition: sndvol32.c:37
struct _PREFERENCES_CONTEXT * PPREFERENCES_CONTEXT
PPREFERENCES_CONTEXT PrefContext
Definition: sndvol32.c:48
LONG right
Definition: windef.h:308
#define SetWindowLongPtr
Definition: treelist.c:70
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
LONG_PTR LPARAM
Definition: windef.h:208
#define WM_CLOSE
Definition: winuser.h:1621
#define DWLP_USER
Definition: winuser.h:872
#define IDCANCEL
Definition: winuser.h:831
#define WM_COMMAND
Definition: winuser.h:1740
#define CB_ERR
Definition: winuser.h:2435
#define WM_INITDIALOG
Definition: winuser.h:1739
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1626
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define IDOK
Definition: winuser.h:830
#define CBN_SELCHANGE
Definition: winuser.h:1979
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define CB_GETITEMDATA
Definition: winuser.h:1950
#define SendMessage
Definition: winuser.h:5843
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
#define CB_GETCURSEL
Definition: winuser.h:1943
#define SendDlgItemMessage
Definition: winuser.h:5842
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 54 of file sndvol32.c.

58{
59 LRESULT lres;
61
63
64 lres = SendMessage(FillContext->hComboBox,
66 0,
67 (LPARAM)ProductName);
68 if (lres != CB_ERR)
69 {
70 /* save the index so we don't screw stuff when the combobox is sorted... */
71 SendMessage(FillContext->hComboBox,
73 (WPARAM)lres,
74 Id);
75
76 if (Id == FillContext->Selected)
77 {
78 SendMessage(FillContext->hComboBox,
80 (WPARAM)lres,
81 0);
82 }
83 }
84
85 return TRUE;
86}
DWORD Id
struct _PREFERENCES_FILL_DEVICES * PPREFERENCES_FILL_DEVICES
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define CB_SETITEMDATA
Definition: winuser.h:1966
#define CB_SETCURSEL
Definition: winuser.h:1961
#define CB_ADDSTRING
Definition: winuser.h:1936

Referenced by DlgPreferencesProc().

◆ HandleCommandLine()

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

Definition at line 1399 of file sndvol32.c.

1403{
1404 TCHAR option;
1405
1406 *pMixerId = PLAY_MIXER;
1407 *pMode = (dwStyle & 0x20) ? SMALL_MODE : NORMAL_MODE;
1408
1409 while (*cmdline == _T(' ') || *cmdline == _T('-') || *cmdline == _T('/'))
1410 {
1411 if (*cmdline++ == _T(' '))
1412 continue;
1413
1414 option = *cmdline;
1415 if (option)
1416 cmdline++;
1417 while (*cmdline == _T(' '))
1418 cmdline++;
1419
1420 switch (option)
1421 {
1422 case 'd': /* Device */
1423 case 'D':
1424 break;
1425
1426 case 'n': /* Small size */
1427 case 'N':
1428 *pMode = NORMAL_MODE;
1429 break;
1430
1431 case 's': /* Small size */
1432 case 'S':
1433 *pMode = SMALL_MODE;
1434 break;
1435
1436 case 't': /* Tray size */
1437 case 'T':
1438 *pMode = TRAY_MODE;
1439 break;
1440
1441 case 'p': /* Play mode */
1442 case 'P':
1443 *pMixerId = PLAY_MIXER;
1444 break;
1445
1446 case 'r': /* Record mode */
1447 case 'R':
1448 *pMixerId = RECORD_MIXER;
1449 break;
1450
1451 default:
1452 return FALSE;
1453 }
1454 }
1455
1456 return TRUE;
1457}
#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
char TCHAR
Definition: xmlstorage.h:189

Referenced by _tWinMain().

◆ MainWindowProc()

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

Definition at line 876 of file sndvol32.c.

880{
881 PMIXER_WINDOW MixerWindow;
882 DWORD CtrlID, LineOffset;
883 BOOL bRet;
884 LRESULT Result = 0;
886
887 switch (uMsg)
888 {
889 case WM_COMMAND:
890 {
891 MixerWindow = GetWindowData(hwnd,
893
894 switch (LOWORD(wParam))
895 {
896 case IDM_PROPERTIES:
897 {
899
900 Pref.MixerWindow = MixerWindow;
901 Pref.Mixer = NULL;
903
906 hwnd,
908 (LPARAM)&Pref) == IDOK)
909 {
910 /* update window */
911 TCHAR szProduct[MAXPNAMELEN];
912
913 /* get mixer product name */
914 if (SndMixerGetProductName(Pref.Mixer,
915 szProduct,
916 sizeof(szProduct) / sizeof(szProduct[0])) == -1)
917 {
918 /* failed to get name */
919 szProduct[0] = L'\0';
920 }
921 else
922 {
923 /* copy product */
924 wcscpy(Preferences.DeviceName, szProduct);
925 }
926
927 /* destroy old status bar */
928 if (MixerWindow->Mode == NORMAL_MODE)
929 DestroyWindow(MixerWindow->hStatusBar);
930
931 /* update details */
932 Preferences.SelectedLine = Pref.SelectedLine;
933
934 /* destroy old mixer */
936
937 /* use new selected mixer */
938 Preferences.MixerWindow->Mixer = Pref.Mixer;
939
940 /* create status window */
941 if (MixerWindow->Mode == NORMAL_MODE)
942 {
944 NULL,
945 hwnd,
946 0);
947 if (MixerWindow->hStatusBar)
948 {
949 /* Set status bar */
950 SendMessage(MixerWindow->hStatusBar,
952 0,
953 (LPARAM)szProduct);
954 }
955 }
956
957 /* rebuild dialog controls */
959 }
960 break;
961 }
962
964 MixerWindow->bShowExtendedControls = !MixerWindow->bShowExtendedControls;
969 break;
970
971 case IDM_EXIT:
972 {
975 break;
976 }
977
978 case IDM_ABOUT:
979 {
980 HICON hAppIcon = (HICON)GetClassLongPtrW(hwnd,
981 GCLP_HICON);
984 NULL,
985 hAppIcon);
986 break;
987 }
988
989 default:
990 {
991 /* get button id */
992 CtrlID = LOWORD(wParam);
993
994 /* check if the message is from the line switch */
995 if (HIWORD(wParam) == BN_CLICKED)
996 {
997 if (CtrlID % IDC_LINE_SWITCH == 0)
998 {
999 /* compute line offset */
1000 LineOffset = CtrlID / IDC_LINE_SWITCH;
1001
1002 /* compute window id of line name static control */
1003 CtrlID = LineOffset * IDC_LINE_NAME;
1004
1005 if (Preferences.MixerWindow->Mixer->MixerId == PLAY_MIXER)
1006 {
1007 /* get line name */
1008 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
1009 {
1010 /* setup context */
1011 Context.SliderPos = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
1012 Context.bVertical = FALSE;
1013 Context.bSwitch = TRUE;
1014
1015 /* set volume */
1017 }
1018 }
1019 else if (Preferences.MixerWindow->Mixer->MixerId == RECORD_MIXER)
1020 {
1021 UINT i;
1022
1023 for (i = 0; i < Preferences.MixerWindow->DialogCount; i++)
1024 {
1025 SendDlgItemMessageW(hwnd, (i + 1) * IDC_LINE_SWITCH, BM_SETCHECK, (WPARAM)((i + 1) == LineOffset), 0);
1026 }
1027 }
1028 }
1029 else if (CtrlID % IDC_LINE_ADVANCED == 0)
1030 {
1031 ADVANCED_CONTEXT AdvancedContext;
1032
1033 /* compute line offset */
1034 LineOffset = CtrlID / IDC_LINE_ADVANCED;
1035
1036 /* compute window id of line name static control */
1037 CtrlID = LineOffset * IDC_LINE_NAME;
1038
1039 /* get line name */
1040 if (GetDlgItemTextW(hwnd, CtrlID, AdvancedContext.LineName, MIXER_LONG_NAME_CHARS) != 0)
1041 {
1042 AdvancedContext.MixerWindow = Preferences.MixerWindow;
1043 AdvancedContext.Mixer = Preferences.MixerWindow->Mixer;
1046 AdvancedContext.LineName);
1047 if (AdvancedContext.Line)
1048 {
1051 hwnd,
1053 (LPARAM)&AdvancedContext);
1054 }
1055 }
1056 }
1057 }
1058 }
1059 }
1060 break;
1061 }
1062
1064 {
1065 DPRINT("MM_MIXM_LINE_CHANGE\n");
1066 break;
1067 }
1068
1070 {
1071 DPRINT("MM_MIXM_CONTROL_CHANGE\n");
1072
1073 /* get mixer window */
1074 MixerWindow = GetWindowData(hwnd,
1075 MIXER_WINDOW);
1076
1077 /* sanity checks */
1078 assert(MixerWindow);
1079 assert(MixerWindow->Mixer->hmx == (HMIXER)wParam);
1080
1082 break;
1083 }
1084
1085 case WM_VSCROLL:
1086 switch (LOWORD(wParam))
1087 {
1088 case TB_THUMBTRACK:
1089 /* get dialog item ctrl */
1090 CtrlID = GetDlgCtrlID((HWND)lParam);
1091
1092 /* get line index */
1093 LineOffset = CtrlID / IDC_LINE_SLIDER_VERT;
1094
1095 /* compute window id of line name static control */
1096 CtrlID = LineOffset * IDC_LINE_NAME;
1097
1098 /* get line name */
1099 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
1100 {
1101 /* setup context */
1102 Context.SliderPos = LineOffset;
1103 Context.bVertical = TRUE;
1104 Context.bSwitch = FALSE;
1105
1106 /* set volume */
1108 }
1109 break;
1110
1111 case TB_ENDTRACK:
1112 MixerWindow = GetWindowData(hwnd,
1113 MIXER_WINDOW);
1114
1115 /* get dialog item ctrl */
1116 CtrlID = GetDlgCtrlID((HWND)lParam);
1117
1118 /* get line index */
1119 LineOffset = CtrlID / IDC_LINE_SLIDER_VERT;
1120
1121 if (LineOffset == 1 && MixerWindow->Mixer->MixerId == 0)
1123 break;
1124
1125 default:
1126 break;
1127 }
1128 break;
1129
1130 case WM_HSCROLL:
1131 switch (LOWORD(wParam))
1132 {
1133 case TB_THUMBTRACK:
1134 /* get dialog item ctrl */
1135 CtrlID = GetDlgCtrlID((HWND)lParam);
1136
1137 /* get line index */
1138 LineOffset = CtrlID / IDC_LINE_SLIDER_HORZ;
1139
1140 /* compute window id of line name static control */
1141 CtrlID = LineOffset * IDC_LINE_NAME;
1142
1143 /* get line name */
1144 if (GetDlgItemTextW(hwnd, CtrlID, Context.LineName, MIXER_LONG_NAME_CHARS) != 0)
1145 {
1146 /* setup context */
1147 Context.SliderPos = LineOffset;
1148 Context.bVertical = TRUE;
1149 Context.bSwitch = FALSE;
1150
1151 /* set volume */
1153 }
1154 break;
1155
1156 case TB_ENDTRACK:
1157 MixerWindow = GetWindowData(hwnd,
1158 MIXER_WINDOW);
1159
1160 /* get dialog item ctrl */
1161 CtrlID = GetDlgCtrlID((HWND)lParam);
1162
1163 /* get line index */
1164 LineOffset = CtrlID / IDC_LINE_SLIDER_HORZ;
1165
1166 if (LineOffset == 1 && MixerWindow->Mixer->MixerId == 0)
1168 break;
1169
1170 default:
1171 break;
1172 }
1173 break;
1174
1175
1176 case WM_CREATE:
1177 {
1178 MixerWindow = ((LPCREATESTRUCT)lParam)->lpCreateParams;
1181 (LONG_PTR)MixerWindow);
1182 MixerWindow->hWnd = hwnd;
1183 MixerWindow->Mixer = SndMixerCreate(MixerWindow->hWnd, MixerWindow->MixerId);
1184 if (MixerWindow->Mixer != NULL)
1185 {
1186 TCHAR szProduct[MAXPNAMELEN];
1187
1188 /* get mixer product name */
1189 if (SndMixerGetProductName(MixerWindow->Mixer,
1190 szProduct,
1191 sizeof(szProduct) / sizeof(szProduct[0])) == -1)
1192 {
1193 /* failed to get name */
1194 szProduct[0] = L'\0';
1195 }
1196
1197
1198 /* initialize preferences */
1200
1201 /* store mixer */
1202 Preferences.Mixer = MixerWindow->Mixer;
1203
1204 /* store mixer window */
1205 Preferences.MixerWindow = MixerWindow;
1206
1207 /* first destination line id */
1208 Preferences.SelectedLine = 0xFFFF0000;
1209
1210 /* copy product */
1211 wcscpy(Preferences.DeviceName, szProduct);
1212
1213 /* Disable the 'Advanced Controls' menu item */
1215
1216 /* Load the placement coordinate data of the window */
1217 bRet = LoadXYCoordWnd(&Preferences);
1218 if (bRet)
1219 {
1220 /*
1221 * LoadXYCoordWnd() might fail for the first time of opening the application which is normal as
1222 * the Sound Control's applet settings haven't been saved yet to the Registry. At this point SetWindowPos()
1223 * call is skipped.
1224 */
1225 SetWindowPos(hwnd, NULL, MixerWindow->WndPosX, MixerWindow->WndPosY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1226 }
1227
1228 /* create status window */
1229 if (MixerWindow->Mode == NORMAL_MODE)
1230 {
1232 NULL,
1233 hwnd,
1234 0);
1235 if (MixerWindow->hStatusBar)
1236 {
1237 SendMessage(MixerWindow->hStatusBar,
1238 WM_SETTEXT,
1239 0,
1240 (LPARAM)szProduct);
1241 }
1242 }
1243
1245 {
1246 DPRINT("Rebuilding mixer window controls failed!\n");
1247 SndMixerDestroy(MixerWindow->Mixer);
1248 MixerWindow->Mixer = NULL;
1249 Result = -1;
1250 }
1251 }
1252
1254 break;
1255 }
1256
1257 case WM_DESTROY:
1258 {
1259 MixerWindow = GetWindowData(hwnd,
1260 MIXER_WINDOW);
1261 if (MixerWindow != NULL)
1262 {
1263 if (MixerWindow->Mixer != NULL)
1264 {
1265 SndMixerDestroy(MixerWindow->Mixer);
1266 }
1267 if (MixerWindow->hFont)
1268 DeleteObject(MixerWindow->hFont);
1269 HeapFree(hAppHeap, 0, MixerWindow);
1270 }
1271 break;
1272 }
1273
1274 case WM_CLOSE:
1275 {
1277 PostQuitMessage(0);
1278 break;
1279 }
1280
1281 case WM_HOTKEY:
1282 {
1283 if (wParam == HOTKEY_CTRL_S)
1284 {
1287 }
1288 break;
1289 }
1290
1291 default:
1292 {
1294 uMsg,
1295 wParam,
1296 lParam);
1297 break;
1298 }
1299 }
1300
1301 return Result;
1302}
#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(x)
Definition: debug.h:53
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 PlaySound
Definition: mmsystem.h:2842
#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:84
#define L(x)
Definition: ntvdm.h:50
#define WS_CHILD
Definition: pedump.c:617
#define TB_ENDTRACK
Definition: commctrl.h:2081
#define CreateStatusWindow
Definition: commctrl.h:1933
#define TB_THUMBTRACK
Definition: commctrl.h:2078
#define DefWindowProc
Definition: ros2win.h:31
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define ShellAbout
Definition: shellapi.h:692
static BOOL RebuildMixerWindowControls(PPREFERENCES_CONTEXT PrefContext)
Definition: sndvol32.c:616
static INT_PTR CALLBACK DlgPreferencesProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: sndvol32.c:407
#define GetWindowData(hwnd, type)
Definition: sndvol32.c:39
static BOOL CALLBACK SetVolumeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Ctx)
Definition: sndvol32.c:630
static BOOL CALLBACK MixerControlChangeCallback(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: sndvol32.c:755
PREFERENCES_CONTEXT Preferences
Definition: sndvol32.c:35
#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
#define ZeroMemory
Definition: winbase.h:1712
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define MF_BYCOMMAND
Definition: winuser.h:202
#define GWL_USERDATA
Definition: winuser.h:861
CREATESTRUCTA * LPCREATESTRUCT
Definition: winuser.h:5726
#define WM_HSCROLL
Definition: winuser.h:1743
#define WM_VSCROLL
Definition: winuser.h:1744
#define GCLP_HICON
Definition: winuser.h:674
#define WM_CREATE
Definition: winuser.h:1608
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:1245
#define MF_UNCHECKED
Definition: winuser.h:204
DWORD WINAPI CheckMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define BM_SETCHECK
Definition: winuser.h:1921
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_SETTEXT
Definition: winuser.h:1617
BOOL WINAPI RegisterHotKey(_In_opt_ HWND, _In_ int, _In_ UINT, _In_ UINT)
#define GetClassLongPtrW
Definition: winuser.h:4564
#define WM_HOTKEY
Definition: winuser.h:1879
int WINAPI GetDlgCtrlID(_In_ HWND)
#define BN_CLICKED
Definition: winuser.h:1925
#define WM_DESTROY
Definition: winuser.h:1609
#define SWP_NOZORDER
Definition: winuser.h:1247
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
HMENU WINAPI GetMenu(_In_ HWND)
#define BM_GETCHECK
Definition: winuser.h:1918
#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
const CHAR * LPCTSTR
Definition: xmlstorage.h:193

Referenced by RegisterApplicationClasses().

◆ MixerControlChangeCallback()

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

Definition at line 755 of file sndvol32.c.

756{
757 PMIXERCONTROLDETAILS_UNSIGNED pVolumeDetails = NULL;
758 UINT ControlCount = 0, Index;
760
761 /* check if the line has controls */
762 if (Line->cControls == 0)
763 {
764 /* no controls */
765 return TRUE;
766 }
767
768 /* query controls */
769 if (SndMixerQueryControls(Mixer, &ControlCount, Line, &Control) == FALSE)
770 {
771 /* failed to query for controls */
772 return FALSE;
773 }
774
775 pVolumeDetails = HeapAlloc(GetProcessHeap(),
776 0,
777 Line->cChannels * sizeof(MIXERCONTROLDETAILS_UNSIGNED));
778 if (pVolumeDetails == NULL)
779 goto done;
780
781 /* now go through all controls and compare control ids */
782 for (Index = 0; Index < ControlCount; Index++)
783 {
784 if (Control[Index].dwControlID == PtrToUlong(Context))
785 {
786 if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
787 {
789
790 /* get volume control details */
792 {
793 /* update dialog control */
795 }
796 }
797 else if (Control[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
798 {
799 /* get volume control details */
800 if (SndMixerGetVolumeControlDetails(Preferences.MixerWindow->Mixer, Control[Index].dwControlID, Line->cChannels, sizeof(MIXERCONTROLDETAILS_UNSIGNED), (LPVOID)pVolumeDetails) != -1)
801 {
802 /* update dialog control */
803 DWORD volumePosition, volumeStep, maxVolume, i;
804 DWORD balancePosition, balanceStep;
805
806 volumeStep = (Control[Index].Bounds.dwMaximum - Control[Index].Bounds.dwMinimum) / (VOLUME_MAX - VOLUME_MIN);
807
808 maxVolume = 0;
809 for (i = 0; i < Line->cChannels; i++)
810 {
811 if (pVolumeDetails[i].dwValue > maxVolume)
812 maxVolume = pVolumeDetails[i].dwValue;
813 }
814
815 volumePosition = (maxVolume - Control[Index].Bounds.dwMinimum) / volumeStep;
816
817 if (Line->cChannels == 1)
818 {
819 balancePosition = BALANCE_CENTER;
820 }
821 else if (Line->cChannels == 2)
822 {
823 if (pVolumeDetails[0].dwValue == pVolumeDetails[1].dwValue)
824 {
825 balancePosition = BALANCE_CENTER;
826 }
827 else if (pVolumeDetails[0].dwValue == Control[Index].Bounds.dwMinimum)
828 {
829 balancePosition = BALANCE_RIGHT;
830 }
831 else if (pVolumeDetails[1].dwValue == Control[Index].Bounds.dwMinimum)
832 {
833 balancePosition = BALANCE_LEFT;
834 }
835 else
836 {
837 balanceStep = (maxVolume - Control[Index].Bounds.dwMinimum) / (BALANCE_STEPS / 2);
838
839 if (pVolumeDetails[0].dwValue < pVolumeDetails[1].dwValue)
840 {
841 balancePosition = (pVolumeDetails[0].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
842 balancePosition = BALANCE_RIGHT - balancePosition;
843 }
844 else if (pVolumeDetails[1].dwValue < pVolumeDetails[0].dwValue)
845 {
846 balancePosition = (pVolumeDetails[1].dwValue - Control[Index].Bounds.dwMinimum) / balanceStep;
847 balancePosition = BALANCE_LEFT + balancePosition;
848 }
849 }
850 }
851
852 /* Update the volume control slider */
854
855 /* Update the balance control slider */
857 }
858 }
859 break;
860 }
861 }
862
863done:
864 /* Free the volume details */
865 if (pVolumeDetails)
866 HeapFree(GetProcessHeap(), 0, pVolumeDetails);
867
868 /* free controls */
870
871 /* done */
872 return TRUE;
873}
VOID UpdateDialogLineSliderControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, DWORD dwDialogID, DWORD Position)
Definition: dialog.c:815
VOID UpdateDialogLineSwitchControl(PPREFERENCES_CONTEXT PrefContext, LPMIXERLINE Line, LONG fValue)
Definition: dialog.c:769
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 166 of file sndvol32.c.

170{
172 HWND hwndControls;
173 LVITEM lvi;
174 UINT i;
175
178
179 if (Line->cControls != 0)
180 {
181 hwndControls = GetDlgItem(PrefContext->hwndDlg,
183
184 lvi.mask = LVIF_TEXT | LVIF_PARAM;
185 lvi.iItem = PrefContext->tmp++;
186 lvi.iSubItem = 0;
187 lvi.pszText = Line->szName;
188 lvi.lParam = (LPARAM)Line->dwSource;
189
190 i = SendMessage(hwndControls,
192 0,
193 (LPARAM)&lvi);
194 if (i != (UINT)-1)
195 {
197 DWORD Flags;
198 BOOL SelLine = FALSE;
199
200 if (SndMixerGetLineName(PrefContext->Mixer,
201 PrefContext->SelectedLine,
202 LineName,
204 TRUE) == -1)
205 {
206 LineName[0] = TEXT('\0');
207 }
208
209 if (ReadLineConfig(PrefContext->DeviceName,
210 LineName,
211 Line->szName,
212 &Flags))
213 {
214 if (Flags != 0x4)
215 {
216 SelLine = TRUE;
217 }
218 }
219
220 ListView_SetCheckState(hwndControls,
221 i,
222 SelLine);
223 }
224 }
225
226 return TRUE;
227}
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:2674
#define LVM_INSERTITEM
Definition: commctrl.h:2406
#define LVITEM
Definition: commctrl.h:2375
#define LVIF_PARAM
Definition: commctrl.h:2311
#define LVIF_TEXT
Definition: commctrl.h:2309
_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 89 of file sndvol32.c.

93{
95
97 UNREFERENCED_PARAMETER(DisplayControls);
98
99 switch (Line->dwComponentType)
100 {
102 if (PrefContext->PlaybackID == (DWORD)-1)
103 {
104 PrefContext->PlaybackID = Line->dwLineID;
105
106 if (PrefContext->SelectedLine == (DWORD)-1)
107 {
108 PrefContext->SelectedLine = Line->dwLineID;
109 }
110 }
111 else
112 goto AddToOthersLines;
113
114 break;
115
117 if (PrefContext->RecordingID == (DWORD)-1)
118 {
119 PrefContext->RecordingID = Line->dwLineID;
120
121 if (PrefContext->SelectedLine == (DWORD)-1)
122 {
123 PrefContext->SelectedLine = Line->dwLineID;
124 }
125 }
126 else
127 goto AddToOthersLines;
128
129 break;
130
131 default:
132 {
133 LRESULT lres;
134 HWND hwndCbOthers;
135
136 if (PrefContext->SelectedLine == (DWORD)-1)
137 {
138 PrefContext->SelectedLine = Line->dwLineID;
139 }
140
141AddToOthersLines:
142 hwndCbOthers = GetDlgItem(PrefContext->hwndDlg,
143 IDC_LINE);
144
145 lres = SendMessage(hwndCbOthers,
147 0,
148 (LPARAM)Line->szName);
149 if (lres != CB_ERR)
150 {
151 SendMessage(hwndCbOthers,
153 (WPARAM)lres,
154 Line->dwLineID);
155
156 PrefContext->OtherLines++;
157 }
158 break;
159 }
160 }
161
162 return TRUE;
163}
#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 616 of file sndvol32.c.

617{
618 /* delete existing mixer controls */
620
621 /* load new mixer controls */
622 LoadDialogCtrls(PrefContext);
623
624 return TRUE;
625}
VOID LoadDialogCtrls(PPREFERENCES_CONTEXT PrefContext)
Definition: dialog.c:676
static VOID DeleteMixerWindowControls(PMIXER_WINDOW MixerWindow)
Definition: sndvol32.c:597

Referenced by MainWindowProc().

◆ RegisterApplicationClasses()

static BOOL RegisterApplicationClasses ( VOID  )
static

Definition at line 1305 of file sndvol32.c.

1306{
1307 WNDCLASSEX wc;
1308
1309 wc.cbSize = sizeof(WNDCLASSEX);
1312 wc.cbClsExtra = 0;
1313 wc.cbWndExtra = sizeof(PMIXER_WINDOW);
1317 wc.hCursor = LoadCursor(NULL,
1318 IDC_ARROW);
1319 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1320 wc.lpszMenuName = NULL;
1322 wc.hIconSm = NULL;
1324
1325 return MainWindowClass != 0;
1326}
#define IDI_MAINAPP
Definition: resource.h:6
ATOM MainWindowClass
Definition: sndvol32.c:31
static LRESULT CALLBACK MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: sndvol32.c:876
struct _MIXER_WINDOW * PMIXER_WINDOW
int cbClsExtra
Definition: winuser.h:3204
HINSTANCE hInstance
Definition: winuser.h:3206
HCURSOR hCursor
Definition: winuser.h:3208
LPCSTR lpszMenuName
Definition: winuser.h:3210
HICON hIconSm
Definition: winuser.h:3212
UINT style
Definition: winuser.h:3202
int cbWndExtra
Definition: winuser.h:3205
UINT cbSize
Definition: winuser.h:3201
WNDPROC lpfnWndProc
Definition: winuser.h:3203
LPCSTR lpszClassName
Definition: winuser.h:3211
HICON hIcon
Definition: winuser.h:3207
HBRUSH hbrBackground
Definition: winuser.h:3209
#define CS_VREDRAW
Definition: winuser.h:658
#define CS_HREDRAW
Definition: winuser.h:653
#define IDC_ARROW
Definition: winuser.h:687
#define RegisterClassEx
Definition: winuser.h:5837
#define LoadIcon
Definition: winuser.h:5813
#define LoadCursor
Definition: winuser.h:5812
WNDCLASSEXA WNDCLASSEX
Definition: winuser.h:5719
#define COLOR_BTNFACE
Definition: winuser.h:928

Referenced by _tWinMain().

◆ SetVolumeCallback()

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

Definition at line 630 of file sndvol32.c.

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

Referenced by MainWindowProc().

◆ UnregisterApplicationClasses()

static VOID UnregisterApplicationClasses ( VOID  )
static

Definition at line 1329 of file sndvol32.c.

1330{
1332 hAppInstance);
1333}
#define UnregisterClass
Definition: winuser.h:5861

Referenced by _tWinMain().

◆ UpdatePrefDlgControls()

static VOID UpdatePrefDlgControls ( PPREFERENCES_CONTEXT  Context,
DWORD  LineID 
)
static

Definition at line 230 of file sndvol32.c.

232{
233 INT OldID, MixerID = 0;
234 INT DeviceCbIndex;
235
236 /* select the mixer */
237 DeviceCbIndex = SendDlgItemMessage(Context->hwndDlg,
240 0,
241 0);
242 if (DeviceCbIndex != CB_ERR)
243 {
244 MixerID = SendDlgItemMessage(Context->hwndDlg,
247 DeviceCbIndex,
248 0);
249 if (MixerID == CB_ERR)
250 {
251 MixerID = 0;
252 }
253 }
254
255 OldID = Context->Selected;
256 if (MixerID != OldID &&
257 SndMixerSelect(Context->Mixer,
258 MixerID))
259 {
260 Context->Selected = SndMixerGetSelection(Context->Mixer);
261
262 /* update the controls */
263 Context->PlaybackID = (DWORD)-1;
264 Context->RecordingID = (DWORD)-1;
265 Context->OtherLines = 0;
266 Context->SelectedLine = (DWORD)-1;
267
269 Context->DeviceName,
270 sizeof(Context->DeviceName) / sizeof(Context->DeviceName[0]));
271
272 if (SndMixerEnumLines(Context->Mixer,
274 Context))
275 {
276 UINT SelBox = 0;
277
278 /* enable/disable controls and make default selection */
281 Context->PlaybackID != (DWORD)-1);
282 CheckDlgButton(Context->hwndDlg,
284 (Context->PlaybackID != (DWORD)-1 && SelBox++ == 0) ?
286
289 Context->RecordingID != (DWORD)-1);
290 CheckDlgButton(Context->hwndDlg,
292 (Context->RecordingID != (DWORD)-1 && SelBox++ == 0) ?
294
295 if (Context->OtherLines != 0)
296 {
297 /* select the first item in the other lines combo box by default */
299 IDC_LINE,
301 0,
302 0);
303 }
305 IDC_LINE),
306 FALSE);
308 IDC_OTHER),
309 Context->OtherLines != 0);
310 CheckDlgButton(Context->hwndDlg,
311 IDC_LINE,
312 (Context->OtherLines != 0 && SelBox++ == 0) ?
314
315 /* disable the OK button if the device doesn't have any lines */
317 IDOK),
318 Context->PlaybackID != (DWORD)-1 ||
319 Context->RecordingID != (DWORD)-1 ||
320 Context->OtherLines != 0);
321
322 LineID = Context->SelectedLine;
323 }
324 }
325
326 /* update the line sources list */
327 if ((MixerID != OldID && Context->SelectedLine != (DWORD)-1) ||
328 (Context->SelectedLine != LineID && LineID != (DWORD)-1))
329 {
330 Context->SelectedLine = LineID;
331
333 IDC_CONTROLS));
334
335 Context->tmp = 0;
337 LineID,
339 Context);
340 }
341}
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:2414
static BOOL CALLBACK PrefDlgAddConnection(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context)
Definition: sndvol32.c:166
static BOOL CALLBACK PrefDlgAddLine(PSND_MIXER Mixer, LPMIXERLINE Line, UINT DisplayControls, PVOID Context)
Definition: sndvol32.c:89
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 345 of file sndvol32.c.

346{
347 HWND hwndControls;
348 INT Count, Index;
350 WCHAR DestinationName[MIXER_LONG_NAME_CHARS];
351 DWORD Flags;
352 PSNDVOL_REG_LINESTATE LineStates;
353
354 /* get list view */
355 hwndControls = GetDlgItem(hwndDlg, IDC_CONTROLS);
356
357 /* get list item count */
358 Count = ListView_GetItemCount(hwndControls);
359
360 /* sanity check */
361 assert(Count);
362
363 if (SndMixerGetLineName(Context->Mixer, Context->SelectedLine, DestinationName, MIXER_LONG_NAME_CHARS, TRUE) == -1)
364 {
365 /* failed to get destination line name */
366 return;
367 }
368
369 /* allocate line states array */
371 if (LineStates == NULL)
372 {
373 /* failed to allocate line states array */
374 return;
375 }
376
377
378 for(Index = 0; Index < Count; Index++)
379 {
380 /* set to empty */
381 LineName[0] = L'\0';
382
383 /* get item text */
384 ListView_GetItemText(hwndControls, Index, 0, LineName, MIXER_LONG_NAME_CHARS);
385
386 /* make sure it is null terminated */
387 LineName[MIXER_LONG_NAME_CHARS-1] = L'\0';
388
389 /* get check state */
390 Flags = (ListView_GetCheckState(hwndControls, Index) == 0 ? 0x4 : 0);
391
392 /* copy line name */
393 wcscpy(LineStates[Index].LineName, LineName);
394
395 /* store flags */
396 LineStates[Index].Flags = Flags;
397 }
398
399 /* now write the line config */
400 WriteLineConfig(Context->DeviceName, DestinationName, LineStates, sizeof(SNDVOL_REG_LINESTATE) * Count);
401
402 /* free line states */
403 HeapFree(GetProcessHeap(), 0, LineStates);
404}
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
#define ListView_GetItemText(hwndLV, i, iSubItem_, pszText_, cchTextMax_)
Definition: commctrl.h:2684
#define ListView_GetItemCount(hwnd)
Definition: commctrl.h:2307
#define ListView_GetCheckState(hwndLV, i)
Definition: commctrl.h:2677
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by DlgPreferencesProc().

Variable Documentation

◆ hAppHeap

HANDLE hAppHeap

Definition at line 33 of file sndvol32.c.

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

◆ hAppInstance

◆ hMainWnd

HWND hMainWnd

Definition at line 32 of file sndvol32.c.

Referenced by _tWinMain().

◆ lpAppTitle

LPTSTR lpAppTitle

Definition at line 34 of file sndvol32.c.

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

◆ MainWindowClass

ATOM MainWindowClass

Definition at line 31 of file sndvol32.c.

Referenced by RegisterApplicationClasses().

◆ Preferences

PREFERENCES_CONTEXT Preferences

Definition at line 35 of file sndvol32.c.

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