home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / mixapp / malist.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  23KB  |  840 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (C) 1993 - 1997  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. //  malist.c
  13. //
  14. //  Description:
  15. //
  16. //
  17. //  History:
  18. //       9/21/93
  19. //
  20. //==========================================================================;
  21.  
  22. #include <windows.h>
  23. #include <windowsx.h>
  24. #include <mmsystem.h>
  25.  
  26. #include "mixapp.h"
  27.  
  28. #include "debug.h"
  29.  
  30.  
  31. //
  32. //
  33. //
  34. typedef struct tMACONTROLINSTANCE_LIST
  35. {
  36.     LPMACONTROLINSTANCE             pmaci;
  37.     BOOL                            fSingleSelect;
  38.     MIXERCONTROLDETAILS_BOOLEAN     pmxcd_f[];
  39.  
  40. } MACONTROLINSTANCE_LIST, *PMACONTROLINSTANCE_LIST;
  41.  
  42.  
  43. //==========================================================================;
  44. //
  45. //
  46. //
  47. //
  48. //==========================================================================;
  49.  
  50. //--------------------------------------------------------------------------;
  51. //
  52. //  BOOL MixAppControlChangeList
  53. //
  54. //  Description:
  55. //
  56. //
  57. //  Arguments:
  58. //      HWND hwnd:
  59. //
  60. //      HMIXER hmx:
  61. //
  62. //      DWORD dwControlID:
  63. //
  64. //  Return (BOOL):
  65. //
  66. //  History:
  67. //      09/22/93
  68. //
  69. //--------------------------------------------------------------------------;
  70.  
  71. BOOL FNLOCAL MixAppControlChangeList
  72. (
  73.     HWND                    hwnd,
  74.     HMIXER                  hmx,
  75.     DWORD                   dwControlID
  76. )
  77. {
  78.     MMRESULT                        mmr;
  79.     HWND                            htxt;
  80.     PMACONTROLINSTANCE_LIST         pmaci_list;
  81.     LPMACONTROLINSTANCE             pmaci;
  82.     LPMIXERLINE                     pmxl;
  83.     LPMIXERCONTROL                  pmxctrl;
  84.     PMIXERCONTROLDETAILS_BOOLEAN    pmxcd_f;
  85.     UINT                            cChannels;
  86.     UINT                            cMultipleItems;
  87.     UINT                            u;
  88.     UINT                            uIndex;
  89.     UINT                            v;
  90.     BOOL                            fValue;
  91.     MIXERCONTROLDETAILS             mxcd;
  92.     HWND                            hcheckFocus;
  93.     HWND                            hcheck;
  94.  
  95.  
  96.     hcheckFocus = GetFocus();
  97.     if (NULL == hcheckFocus)
  98.     {
  99.         hcheckFocus = GetDlgItem(hwnd, IDD_MACONTROL_MULTICHANNEL_BASE);
  100.     }
  101.     else
  102.     {
  103.         uIndex = GetDlgCtrlID(hcheckFocus);
  104.         if (uIndex < IDD_MACONTROL_MULTICHANNEL_BASE)
  105.         {
  106.             hcheckFocus = GetDlgItem(hwnd, IDD_MACONTROL_MULTICHANNEL_BASE);
  107.         }
  108.     }
  109.  
  110.  
  111.     //
  112.     //
  113.     //
  114.     pmaci_list = (PMACONTROLINSTANCE_LIST)(UINT)GetWindowLong(hwnd, DWL_USER);
  115.     pmaci      = pmaci_list->pmaci;
  116.     pmxl       = pmaci->pmxl;
  117.     pmxctrl    = pmaci->pmxctrl;
  118.     pmxcd_f    = &pmaci_list->pmxcd_f[0];
  119.  
  120.     cChannels = (UINT)pmxl->cChannels;
  121.     if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
  122.         cChannels = 1;
  123.  
  124.  
  125.     //
  126.     //
  127.     //
  128.     mxcd.cbStruct       = sizeof(mxcd);
  129.     mxcd.dwControlID    = pmxctrl->dwControlID;
  130.     mxcd.cChannels      = cChannels;
  131.     mxcd.cMultipleItems = pmxctrl->cMultipleItems;
  132.     mxcd.cbDetails      = sizeof(*pmxcd_f);
  133.     mxcd.paDetails      = pmxcd_f;
  134.  
  135.     mmr = mixerGetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE);
  136.     if (MMSYSERR_NOERROR != mmr)
  137.     {
  138.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  139.                   "mixerGetControlDetails(ctrlid=%.08lXh) failed on hmx=%.04Xh, mmr=%u!",
  140.                   pmxctrl->dwControlID, pmaci->hmx, mmr);
  141.         return (FALSE);
  142.     }
  143.  
  144.  
  145.     cMultipleItems = 1;
  146.     if (MIXERCONTROL_CONTROLF_MULTIPLE & pmxctrl->fdwControl)
  147.         cMultipleItems = (UINT)pmxctrl->cMultipleItems;
  148.  
  149.  
  150.     for (u = 0; u < cChannels; u++)
  151.     {
  152.         for (v = 0; v < cMultipleItems; v++)
  153.         {
  154.             uIndex = (u * cMultipleItems) + v;
  155.  
  156.             fValue = (BOOL)pmxcd_f[uIndex].fValue;
  157.  
  158.             hcheck = GetDlgItem(hwnd, IDD_MACONTROL_MULTICHANNEL_BASE + uIndex);
  159.             if (hcheckFocus == hcheck)
  160.             {
  161.                 htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_VALUE);
  162.                 AppSetWindowText(htxt, "mapped=%d, fValue=%ld",
  163.                                 fValue,
  164.                                 pmxcd_f[uIndex].fValue);
  165.             }
  166.  
  167.             if (fValue == (BOOL)IsDlgButtonChecked(hwnd, IDD_MACONTROL_MULTICHANNEL_BASE + uIndex))
  168.                 continue;
  169.  
  170.             CheckDlgButton(hwnd, IDD_MACONTROL_MULTICHANNEL_BASE + uIndex, fValue);
  171.         }
  172.     }
  173.  
  174.  
  175.  
  176.  
  177.     //
  178.     //
  179.     //
  180.     mxcd.cbStruct       = sizeof(mxcd);
  181.     mxcd.dwControlID    = pmxctrl->dwControlID;
  182.     mxcd.cChannels      = 1;
  183.     mxcd.cMultipleItems = pmxctrl->cMultipleItems;
  184.     mxcd.cbDetails      = sizeof(*pmxcd_f);
  185.     mxcd.paDetails      = pmxcd_f;
  186.  
  187.     mmr = mixerGetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE);
  188.     if (MMSYSERR_NOERROR != mmr)
  189.     {
  190.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  191.                   "mixerGetControlDetails(ctrlid=%.08lXh) failed on hmx=%.04Xh, mmr=%u!",
  192.                   pmxctrl->dwControlID, pmaci->hmx, mmr);
  193.         return (FALSE);
  194.     }
  195.  
  196.  
  197.     for (v = 0; v < cMultipleItems; v++)
  198.     {
  199.         uIndex = v;
  200.  
  201.         fValue = (BOOL)pmxcd_f[uIndex].fValue;
  202.  
  203.         hcheck = GetDlgItem(hwnd, IDD_MACONTROL_UNIFORM_BASE + uIndex);
  204.         if (hcheckFocus == hcheck)
  205.         {
  206.             htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_VALUE);
  207.             AppSetWindowText(htxt, "mapped=%d, fValue=%ld",
  208.                              fValue,
  209.                              pmxcd_f[uIndex].fValue);
  210.         }
  211.  
  212.         if (fValue == (BOOL)IsDlgButtonChecked(hwnd, IDD_MACONTROL_UNIFORM_BASE + uIndex))
  213.             continue;
  214.  
  215.         CheckDlgButton(hwnd, IDD_MACONTROL_UNIFORM_BASE + uIndex, fValue);
  216.     }
  217.  
  218.  
  219.     return (TRUE);
  220. } // MixAppControlChangeList()
  221.  
  222.  
  223. //--------------------------------------------------------------------------;
  224. //
  225. //  BOOL MixAppControlSetList
  226. //
  227. //  Description:
  228. //
  229. //
  230. //  Arguments:
  231. //      HWND hwnd:
  232. //
  233. //      HWND hcheck:
  234. //
  235. //  Return (BOOL):
  236. //
  237. //  History:
  238. //      09/22/93
  239. //
  240. //--------------------------------------------------------------------------;
  241.  
  242. BOOL FNLOCAL MixAppControlSetList
  243. (
  244.     HWND                    hwnd,
  245.     HWND                    hcheck
  246. )
  247. {
  248.     PMACONTROLINSTANCE_LIST         pmaci_list;
  249.     LPMACONTROLINSTANCE             pmaci;
  250.     LPMIXERLINE                     pmxl;
  251.     LPMIXERCONTROL                  pmxctrl;
  252.     PMIXERCONTROLDETAILS_BOOLEAN    pmxcd_f;
  253.     MMRESULT                        mmr;
  254.     BOOL                            fValue;
  255.     UINT                            cChannels;
  256.     UINT                            uIndex;
  257.     MIXERCONTROLDETAILS             mxcd;
  258.  
  259.     //
  260.     //
  261.     //
  262.     pmaci_list = (PMACONTROLINSTANCE_LIST)(UINT)GetWindowLong(hwnd, DWL_USER);
  263.     pmaci      = pmaci_list->pmaci;
  264.     pmxl       = pmaci->pmxl;
  265.     pmxctrl    = pmaci->pmxctrl;
  266.     pmxcd_f    = &pmaci_list->pmxcd_f[0];
  267.  
  268.     uIndex = GetDlgCtrlID(hcheck);
  269.  
  270.     if (pmaci_list->fSingleSelect)
  271.     {
  272.         fValue = TRUE;
  273.     }
  274.     else
  275.     {
  276.         //
  277.         //  get current value and toggle..
  278.         //
  279.         fValue = (0 == IsDlgButtonChecked(hwnd, uIndex));
  280.     }
  281.  
  282.     if (uIndex < IDD_MACONTROL_UNIFORM_BASE)
  283.     {
  284.         cChannels = (UINT)pmxl->cChannels;
  285.         if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
  286.             cChannels = 1;
  287.  
  288.         uIndex -= IDD_MACONTROL_MULTICHANNEL_BASE;
  289.     }
  290.     else
  291.     {
  292.         cChannels = 1;
  293.  
  294.         uIndex -= IDD_MACONTROL_UNIFORM_BASE;
  295.     }
  296.  
  297.  
  298.     //
  299.     //
  300.     //
  301.     //
  302.     mxcd.cbStruct       = sizeof(mxcd);
  303.     mxcd.dwControlID    = pmxctrl->dwControlID;
  304.     mxcd.cChannels      = cChannels;
  305.     mxcd.cMultipleItems = pmxctrl->cMultipleItems;
  306.     mxcd.cbDetails      = sizeof(*pmxcd_f);
  307.     mxcd.paDetails      = pmxcd_f;
  308.  
  309.     mmr = mixerGetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, 0L);
  310.     if (MMSYSERR_NOERROR != mmr)
  311.     {
  312.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  313.                   "mixerGetControlDetails(ctrlid=%.08lXh) failed on hmx=%.04Xh, mmr=%u!",
  314.                   pmxctrl->dwControlID, pmaci->hmx, mmr);
  315.         return (FALSE);
  316.     }
  317.  
  318.  
  319.     if (pmaci_list->fSingleSelect)
  320.     {
  321.         UINT        u;
  322.         UINT        v;
  323.         UINT        cMultipleItems;
  324.  
  325.  
  326.         //
  327.         //  reset all settings in the correct channel
  328.         //
  329.         cMultipleItems = (UINT)pmxctrl->cMultipleItems;
  330.  
  331.         u = uIndex / (cChannels * cMultipleItems);
  332.  
  333.         for (v = 0; v < cMultipleItems; v++)
  334.         {
  335.             pmxcd_f[(u * cMultipleItems) + v].fValue = FALSE;
  336.         }
  337.     }
  338.  
  339.     pmxcd_f[uIndex].fValue = fValue;
  340.  
  341.  
  342.     mmr = mixerSetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, 0L);
  343.     if (MMSYSERR_NOERROR != mmr)
  344.     {
  345.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  346.                   "mixerSetControlDetails(ctrlid=%.08lXh) failed on hmx=%.04Xh, mmr=%u!",
  347.                   pmxctrl->dwControlID, pmaci->hmx, mmr);
  348.         return (FALSE);
  349.     }
  350.  
  351.     CheckDlgButton(hwnd, GetDlgCtrlID(hcheck), (BOOL)pmxcd_f[uIndex].fValue);
  352. #if 0
  353.     if (0 == uIndex)
  354.     {
  355.         htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_VALUE);
  356.         AppSetWindowText(htxt, "mapped=%d, fValue=%ld",
  357.                          nValue,
  358.                          pmxcd_f[uIndex].fValue);
  359.     }
  360. #endif
  361.  
  362.     return (TRUE);
  363. } // MixAppControlSetList()
  364.  
  365.  
  366. //--------------------------------------------------------------------------;
  367. //
  368. //  BOOL MixAppLineChangeList
  369. //
  370. //  Description:
  371. //
  372. //
  373. //  Arguments:
  374. //      HWND hwnd:
  375. //
  376. //      HMIXER hmx:
  377. //
  378. //      DWORD dwLineID:
  379. //
  380. //  Return (BOOL):
  381. //
  382. //  History:
  383. //      09/24/93
  384. //
  385. //--------------------------------------------------------------------------;
  386.  
  387. BOOL FNLOCAL MixAppLineChangeList
  388. (
  389.     HWND                    hwnd,
  390.     HMIXER                  hmx,
  391.     DWORD                   dwLineID
  392. )
  393. {
  394.     MMRESULT                    mmr;
  395.     PMACONTROLINSTANCE_LIST     pmaci_list;
  396.     LPMACONTROLINSTANCE         pmaci;
  397.     LPMIXERLINE                 pmxl;
  398.     MIXERLINE                   mxl;
  399.     BOOL                        fSource;
  400.     BOOL                        fActive;
  401.     BOOL                        fDisconnected;
  402.     HWND                        htxt;
  403.  
  404.  
  405.     //
  406.     //
  407.     //
  408.     pmaci_list = (PMACONTROLINSTANCE_LIST)(UINT)GetWindowLong(hwnd, DWL_USER);
  409.     pmaci       = pmaci_list->pmaci;
  410.     pmxl        = pmaci->pmxl;
  411.  
  412.     if (pmxl->dwLineID != dwLineID)
  413.     {
  414.         DPF(0, "!MixAppLineChangeList: why am i getting notifications for some other line??");
  415.  
  416.         //
  417.         //  this would be a bug in this app... keep from bombing though
  418.         //  until i fix it.
  419.         //
  420.         dwLineID = pmxl->dwLineID;
  421.     }
  422.  
  423.     //
  424.     //  get the current state of the line that changed.. this is actually
  425.     //  silly that you have to do this just to determine if the line went
  426.     //  [in]active. sigh..
  427.     //
  428.     mxl.cbStruct      = sizeof(mxl);
  429.     mxl.dwLineID      = dwLineID;
  430.  
  431.     mmr = mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_LINEID);
  432.     if (MMSYSERR_NOERROR != mmr)
  433.     {
  434.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  435.                   "mixerGetLineInfo(lineid=%.08lXh) failed on hmx=%.04Xh, mmr=%u!",
  436.                   dwLineID, hmx, mmr);
  437.  
  438.         return (FALSE);
  439.     }
  440.  
  441.     fSource       = (0 != (MIXERLINE_LINEF_SOURCE & mxl.fdwLine));
  442.     fActive       = (0 != (MIXERLINE_LINEF_ACTIVE & mxl.fdwLine));
  443.     fDisconnected = (0 != (MIXERLINE_LINEF_DISCONNECTED & mxl.fdwLine));
  444.  
  445.  
  446.     htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_LINEINFO);
  447.     AppSetWindowText(htxt, "(%s), '%s', %s, %s",
  448.                      fSource ? (LPSTR)"src" : (LPSTR)"DST",
  449.                      (LPSTR)mxl.szShortName,
  450.                      fActive ? (LPSTR)"ACTIVE" : (LPSTR)"inactive",
  451.                      fDisconnected ? (LPSTR)"DISCONNECTED" : (LPSTR)"connected");
  452.  
  453.     return (fActive);
  454. } // MixAppLineChangeList()
  455.  
  456.  
  457. //--------------------------------------------------------------------------;
  458. //
  459. //  BOOL MixAppInitDialogList
  460. //
  461. //  Description:
  462. //
  463. //
  464. //  Arguments:
  465. //      HWND hwnd:
  466. //
  467. //      HWND hwndFocus:
  468. //
  469. //      LPARAM lParam:
  470. //
  471. //  Return (BOOL):
  472. //
  473. //  History:
  474. //      09/22/93
  475. //
  476. //--------------------------------------------------------------------------;
  477.  
  478. BOOL FNLOCAL MixAppInitDialogList
  479. (
  480.     HWND                    hwnd,
  481.     HWND                    hwndFocus,
  482.     LPARAM                  lParam
  483. )
  484. {
  485.     #define FCB_DEF_STYLE   (WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_TABSTOP)
  486.  
  487.     static TCHAR        szButton[]  = TEXT("button");
  488.     static TCHAR        szTitle[]   = TEXT("List Class: '%s'");
  489.  
  490.     MMRESULT                    mmr;
  491.     TCHAR                       szControlType[64];
  492.     LPMACONTROLINSTANCE         pmaci;
  493.     PMACONTROLINSTANCE_LIST     pmaci_list;
  494.  
  495.     LPMIXERLINE                 pmxl;
  496.     LPMIXERCONTROL              pmxctrl;
  497.  
  498.     HWND                        htxt;
  499.     UINT                        u;
  500.     UINT                        v;
  501.     HWND                        hcheck;
  502.     RECT                        rcM;
  503.     RECT                        rcU;
  504.     int                         cycap;
  505.     UINT                        cb;
  506.     UINT                        cChannels;
  507.     UINT                        cMultipleItems;
  508.     UINT                        uIndex;
  509.     BOOL                        fSingleSelect;
  510.     PMIXERCONTROLDETAILS_LISTTEXT pmxcd_lt;
  511.     MIXERCONTROLDETAILS         mxcd;
  512.  
  513.  
  514.     //
  515.     //
  516.     //
  517.     pmaci = (LPMACONTROLINSTANCE)lParam;
  518.     if (NULL == pmaci)
  519.     {
  520.         DPF(0, "!MixAppInitDialogList: pmaci passed in lParam is NULL!?!");
  521.         return (FALSE);
  522.     }
  523.  
  524.     pmxl    = pmaci->pmxl;
  525.     pmxctrl = pmaci->pmxctrl;
  526.  
  527.     if (!MixAppGetControlTypeName(pmxctrl, szControlType))
  528.     {
  529.         return (FALSE);
  530.     }
  531.  
  532.     //
  533.     //
  534.     //
  535.     switch (pmxctrl->dwControlType)
  536.     {
  537.         case MIXERCONTROL_CONTROLTYPE_SINGLESELECT:
  538.         case MIXERCONTROL_CONTROLTYPE_MUX:
  539.         case MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT:
  540.         case MIXERCONTROL_CONTROLTYPE_MIXER:
  541.             break;
  542.  
  543.         default:
  544.             DPF(0, "!MixAppInitDialogList: pmxctrl->dwControlType=%.08lXh not valid list type!", pmxctrl->dwControlType);
  545.             return (FALSE);
  546.     }
  547.  
  548.     fSingleSelect = (MIXERCONTROL_CT_SC_LIST_SINGLE == (MIXERCONTROL_CT_SUBCLASS_MASK & pmxctrl->dwControlType));
  549.  
  550.  
  551.     //
  552.     //
  553.     //
  554.     AppSetWindowText(hwnd, szTitle, (LPTSTR)szControlType);
  555.     SetDlgItemText(hwnd, IDD_MACONTROL_TXT_SHORT_NAME, pmxctrl->szShortName);
  556.     SetDlgItemText(hwnd, IDD_MACONTROL_TXT_LONG_NAME,  pmxctrl->szName);
  557.  
  558.     htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_BOUNDS);
  559.     AppSetWindowText(htxt, "dwMinimum=%lu, dwMaximum=%lu",
  560.                      pmxctrl->Bounds.dwMinimum,
  561.                      pmxctrl->Bounds.dwMaximum);
  562.  
  563.     htxt = GetDlgItem(hwnd, IDD_MACONTROL_TXT_METRICS);
  564.     AppSetWindowText(htxt, "N/A");
  565.  
  566.  
  567.  
  568.     //
  569.     //
  570.     //
  571.     cChannels = (UINT)pmxl->cChannels;
  572.     if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
  573.         cChannels = 1;
  574.  
  575.     cMultipleItems = 1;
  576.     if (MIXERCONTROL_CONTROLF_MULTIPLE & pmxctrl->fdwControl)
  577.         cMultipleItems = (UINT)pmxctrl->cMultipleItems;
  578.  
  579.     cb  = sizeof(*pmaci_list);
  580.     cb += cChannels * cMultipleItems * sizeof(pmaci_list->pmxcd_f[0]);
  581.     pmaci_list = (PMACONTROLINSTANCE_LIST)LocalAlloc(LPTR, cb);
  582.     if (NULL == pmaci_list)
  583.     {
  584.         DPF(0, "!MixAppInitDialogList: failed trying to alloc %u bytes for control instance!", cb);
  585.         return (FALSE);
  586.     }
  587.  
  588.     //
  589.     //
  590.     //
  591.     SetWindowLong(hwnd, DWL_USER, (LPARAM)(UINT)pmaci_list);
  592.  
  593.     pmaci_list->pmaci         = pmaci;
  594.     pmaci_list->fSingleSelect = fSingleSelect;
  595.  
  596.  
  597.     //
  598.     //
  599.     //
  600.     cb = cChannels * cMultipleItems * sizeof(*pmxcd_lt);
  601.     pmxcd_lt = (PMIXERCONTROLDETAILS_LISTTEXT)LocalAlloc(LPTR, cb);
  602.     if (NULL == pmaci_list)
  603.     {
  604.         DPF(0, "!MixAppInitDialogList: failed trying to alloc %u bytes for control list text!", cb);
  605.         return (FALSE);
  606.     }
  607.  
  608.  
  609.     //
  610.     //
  611.     //
  612.     mxcd.cbStruct       = sizeof(mxcd);
  613.     mxcd.dwControlID    = pmxctrl->dwControlID;
  614.     mxcd.cChannels      = cChannels;
  615.     mxcd.cMultipleItems = cMultipleItems;
  616.     mxcd.cbDetails      = sizeof(*pmxcd_lt);
  617.     mxcd.paDetails      = pmxcd_lt;
  618.  
  619.     mmr = mixerGetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, MIXER_GETCONTROLDETAILSF_LISTTEXT);
  620.     if (MMSYSERR_NOERROR != mmr)
  621.     {
  622.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  623.                     "mixerGetControlDetails(ctrlid=%.08lXh) on LISTTEXT failed on hmx=%.04Xh, mmr=%u!",
  624.                     pmxctrl->dwControlID, pmaci->hmx, mmr);
  625.         return (FALSE);
  626.     }
  627.  
  628.  
  629.     //
  630.     //
  631.     //
  632.     //
  633.     cycap = GetSystemMetrics(SM_CYCAPTION);
  634.  
  635.     hcheck = GetDlgItem(hwnd, IDD_MACONTROL_GRP_MULTICHANNEL);
  636.     GetWindowRect(hcheck, &rcM);
  637.  
  638.     InflateRect(&rcM, -10, -20);
  639.     ScreenToClient(hwnd, (LPPOINT)&rcM.left);
  640.     ScreenToClient(hwnd, (LPPOINT)&rcM.right);
  641.  
  642.     rcM.bottom = rcM.top + cycap;
  643.  
  644.     for (u = 0; u < cChannels; u++)
  645.     {
  646.         for (v = 0; v < cMultipleItems; v++)
  647.         {
  648.             uIndex = (u * cMultipleItems) + v;
  649.  
  650.             hcheck = CreateWindow(szButton,
  651.                                   pmxcd_lt[uIndex].szName,
  652.                                   FCB_DEF_STYLE,
  653.                                   rcM.left, rcM.top,
  654.                                   rcM.right - rcM.left,
  655.                                   rcM.bottom - rcM.top,
  656.                                   hwnd, (HMENU)(IDD_MACONTROL_MULTICHANNEL_BASE + uIndex),
  657.                                   ghinst, NULL);
  658.  
  659.             rcM.top    += cycap + 4;
  660.             rcM.bottom += cycap + 4;
  661.         }
  662.  
  663.         //
  664.         //  add more separation between channels
  665.         //
  666.         rcM.top    += cycap;
  667.         rcM.bottom += cycap;
  668.     }
  669.  
  670.  
  671.  
  672.     //
  673.     //
  674.     //
  675.     mxcd.cbStruct       = sizeof(mxcd);
  676.     mxcd.dwControlID    = pmxctrl->dwControlID;
  677.     mxcd.cChannels      = 1;
  678.     mxcd.cMultipleItems = cMultipleItems;
  679.     mxcd.cbDetails      = sizeof(*pmxcd_lt);
  680.     mxcd.paDetails      = pmxcd_lt;
  681.  
  682.     mmr = mixerGetControlDetails((HMIXEROBJ)pmaci->hmx, &mxcd, MIXER_GETCONTROLDETAILSF_LISTTEXT);
  683.     if (MMSYSERR_NOERROR != mmr)
  684.     {
  685.         AppMsgBox(hwnd, MB_OK | MB_ICONEXCLAMATION,
  686.                     "mixerGetControlDetails(ctrlid=%.08lXh) on LISTTEXT failed on hmx=%.04Xh, mmr=%u!",
  687.                     pmxctrl->dwControlID, pmaci->hmx, mmr);
  688.         return (FALSE);
  689.     }
  690.  
  691.  
  692.     //
  693.     //
  694.     //
  695.     //
  696.     hcheck = GetDlgItem(hwnd, IDD_MACONTROL_GRP_UNIFORM);
  697.     GetWindowRect(hcheck, &rcU);
  698.  
  699.     InflateRect(&rcU, -10, -20);
  700.     ScreenToClient(hwnd, (LPPOINT)&rcU.left);
  701.     ScreenToClient(hwnd, (LPPOINT)&rcU.right);
  702.  
  703.     rcU.bottom = rcU.top + cycap;
  704.  
  705.     for (v = 0; v < cMultipleItems; v++)
  706.     {
  707.         hcheck = CreateWindow(szButton,
  708.                               pmxcd_lt[v].szName,
  709.                               FCB_DEF_STYLE,
  710.                               rcU.left, rcU.top,
  711.                               rcU.right - rcU.left,
  712.                               rcU.bottom - rcU.top,
  713.                               hwnd, (HMENU)(IDD_MACONTROL_UNIFORM_BASE + v),
  714.                               ghinst, NULL);
  715.  
  716.         rcU.top    += cycap + 4;
  717.         rcU.bottom += cycap + 4;
  718.     }
  719.  
  720.  
  721.     LocalFree((HLOCAL)pmxcd_lt);
  722.  
  723.  
  724.     //
  725.     //
  726.     //
  727.     SendMessage(hwnd,
  728.                 MM_MIXM_LINE_CHANGE,
  729.                 (WPARAM)pmaci->hmx,
  730.                 pmxl->dwLineID);
  731.  
  732.     SendMessage(hwnd,
  733.                 MM_MIXM_CONTROL_CHANGE,
  734.                 (WPARAM)pmaci->hmx,
  735.                 pmxctrl->dwControlID);
  736.  
  737.     return (TRUE);
  738. } // MixAppInitDialogList()
  739.  
  740.  
  741. //==========================================================================;
  742. //
  743. //
  744. //
  745. //
  746. //==========================================================================;
  747.  
  748. //--------------------------------------------------------------------------;
  749. //
  750. //  BOOL MixAppDlgProcControlList
  751. //
  752. //  Description:
  753. //
  754. //
  755. //  Arguments:
  756. //      HWND hwnd:
  757. //
  758. //      UINT uMsg:
  759. //
  760. //      WPARAM wParam:
  761. //
  762. //      LPARAM lParam:
  763. //
  764. //  Return (BOOL):
  765. //
  766. //  History:
  767. //      07/22/93
  768. //
  769. //--------------------------------------------------------------------------;
  770.  
  771. BOOL CALLBACK MixAppDlgProcControlList
  772. (
  773.     HWND                    hwnd,
  774.     UINT                    uMsg,
  775.     WPARAM                  wParam,
  776.     LPARAM                  lParam
  777. )
  778. {
  779.     LRESULT             lr;
  780.     HLOCAL              hl;
  781.     UINT                uId;
  782.  
  783.  
  784.     if (WM_COMMAND == uMsg)
  785.     {
  786.         uId = GET_WM_COMMAND_ID(wParam, lParam);
  787.         if (IDD_MACONTROL_GRP_MULTICHANNEL <= uId)
  788.         {
  789.             MixAppControlSetList(hwnd, GET_WM_COMMAND_HWND(wParam, lParam));
  790.             return (TRUE);
  791.         }
  792.     }
  793.  
  794.  
  795.     //
  796.     //
  797.     //
  798.     switch (uMsg)
  799.     {
  800.         case WM_INITDIALOG:
  801.             lr = HANDLE_WM_INITDIALOG(hwnd, wParam, lParam, MixAppInitDialogList);
  802.             if (FALSE == lr)
  803.             {
  804.                 EndDialog(hwnd, FALSE);
  805.             }
  806.             else
  807.             {
  808.                 ghdlgControl = hwnd;
  809.             }
  810.             return (TRUE);
  811.  
  812.  
  813.         case MM_MIXM_LINE_CHANGE:
  814.             MixAppLineChangeList(hwnd, (HMIXER)wParam, lParam);
  815.             return (TRUE);
  816.  
  817.         case MM_MIXM_CONTROL_CHANGE:
  818.             MixAppControlChangeList(hwnd, (HMIXER)wParam, lParam);
  819.             return (TRUE);
  820.  
  821.  
  822.         case WM_COMMAND:
  823.             uId = GET_WM_COMMAND_ID(wParam, lParam);
  824.             switch (uId)
  825.             {
  826.                 case IDCANCEL:
  827.                 case IDOK:
  828.                     hl = (HLOCAL)(UINT)GetWindowLong(hwnd, DWL_USER);
  829.                     LocalFree(hl);
  830.  
  831.                     EndDialog(hwnd, TRUE);
  832.                     ghdlgControl = NULL;
  833.                     break;
  834.             }
  835.             break;
  836.     }
  837.  
  838.     return (FALSE);
  839. } // MixAppDlgProcControlList()
  840.