home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / lbmix04.zip / Source / LBMix.c < prev    next >
C/C++ Source or Header  |  2000-05-06  |  104KB  |  2,723 lines

  1. /* 
  2.  
  3. LBMix - A mixer for Crystal Semiconductor IOCTL90 by Lesha Bogdanow
  4. Copyright (C) 1999-2000  Lesha Bogdanow
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.  */
  21.  
  22. #include "LBMix.h"
  23. #include "ioctl90.h"
  24. #include "mixerapi.h"
  25. #include "PipeMix.h"
  26. #include "call32.h"
  27.  
  28. #define PIPE_WAIT 200        // Wait for pipe (ms)
  29. #define DEF_INFO_BUF_SIZE 1024    // Size for info buffer if driver does not return info
  30.  
  31. // Additional flags for mixerapi
  32. #define FLAG_MUTE 1
  33. #define FLAG_RELEASE 2
  34.  
  35. // User window messages parameters
  36. #define USER_INIT 0
  37. #define USER_QUERY 1
  38. #define USER_CHILDFONTCHANGE 2
  39. #define USER_CHILDBGNDCHANGE 3
  40. #define USER_CHILDFGNDCHANGE 4
  41. #define USER_RECREATE 5
  42.  
  43.  
  44. HAB   hab;                /* anchor block for the process */
  45. HMQ   hmq;            /* handle to the process' message queue */
  46. HWND  hwndMain=0;            /* handle to the main client window */
  47. HWND  hwndMainFrame=0;        /* handle to the main window frame */
  48.  
  49.  
  50. // Definitions for Controls structure
  51. #define FLAG_NONE    0    // Dummy
  52. #define FLAG_ONLYLEFT    1    // Only left control is used
  53. #define FLAG_STEREO    2    // Both is valid. 
  54. #define FLAG_MUTABLE    4    // Mute is valid
  55. #define FLAG_LOCKABLE    8    // Can be locked, lock is valid
  56. #define FLAG_MULTIPLE    0x10    // This input selector supports multiple selections
  57. #define FLAG_ONLYRIGHT    0x20    // Only right control is used
  58.  
  59. // Flags for .both
  60. #define BOTH_BOTH    1    // Set by main window checkbox
  61. #define BOTH_MONO    2    // Set from setup
  62.  
  63. #define NO_INPUT_SEL    0    /* Value to place into .sel field when control
  64.                    does not appear in input selector */
  65. enum CtlTypes{
  66.    TYPE_DEFAULT,
  67.    TYPE_SELECTOR,
  68.    TYPE_3D,
  69.    TYPE_TONE};
  70.  
  71. struct t_Controls{
  72.    int setfunc;        // IOCTL set function no
  73.    int qfunc;        // IOCTL query function no
  74.    int flags;        // Flags, see above
  75.    enum CtlTypes type;    // Control type
  76.    int sel;        // Value representing the control in input selector or NO_INPUT_SEL
  77.    HWND hwndGroup,hwndLeft,hwndRight,hwndMute,hwndBoth;    // Window handles of controls
  78.    HWND hwndLock,hwndLdesc,hwndRdesc,hwndRect;        // ...continued
  79.    int activeID,nameID,defnameID,monoID;        // Settings ctl IDs, default name string ID, mono ID
  80.    LONG FgColor,BgColor,SlLColor,SlRColor;        // Colors. For listbox: SlLColor/SlRColor = bgnd/fgnd.
  81.    int supported;                    // TRUE if supported
  82.    int active;                        // TRUE if active
  83.    unsigned char name[32];                // name
  84.    int left,right,mute,both,lock;            // Current values
  85.    } Controls[]={ 
  86. {1,0x11,FLAG_STEREO,TYPE_DEFAULT,NO_INPUT_SEL,            // Master
  87. 0,0,0,0,0,0,0,0,0,
  88. IDC_MASTACT,IDC_MASTNAME,IDS_MASTER,IDC_MASTMONO,
  89. -1,-1,-1,-1,
  90. 1,0,"",100,100,0,0,0},                    // Unactive on default
  91. {0x4D,0x6D,FLAG_STEREO|FLAG_MUTABLE|FLAG_LOCKABLE,TYPE_DEFAULT,NO_INPUT_SEL,    // DAC
  92. 0,0,0,0,0,0,0,0,0,
  93. IDC_DACACT,IDC_DACNAME,IDS_DAC,IDC_DACMONO,
  94. -1,-1,-1,-1,
  95. 1,1,"",100,100,0,0,0},
  96. {0x43,0x63,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_LINE,        // Line
  97. 0,0,0,0,0,0,0,0,0,
  98. IDC_LINEACT,IDC_LINENAME,IDS_LINE,IDC_LINEMONO,
  99. -1,-1,-1,-1,
  100. 1,1,"",100,100,0,0,0},
  101. {0x44,0x64,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_CD,        // CD
  102. 0,0,0,0,0,0,0,0,0,
  103. IDC_CDACT,IDC_CDNAME,IDS_CD,IDC_CDMONO,
  104. -1,-1,-1,-1,
  105. 1,1,"",100,100,0,0,0},
  106. {0x42,0x62,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_MIC,        // Mic
  107. 0,0,0,0,0,0,0,0,0,
  108. IDC_MICACT,IDC_MICNAME,IDS_MIC,IDC_MICMONO,
  109. -1,-1,-1,-1,
  110. 1,1,"",100,100,0,0,0},
  111. {0x41,0x61,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_PHONE,        // Phone
  112. 0,0,0,0,0,0,0,0,0,
  113. IDC_PHONEACT,IDC_PHONENAME,IDS_PHONE,IDC_PHONEMONO,
  114. -1,-1,-1,-1,
  115. 1,1,"",100,100,0,0,0},
  116. {0x45,0x65,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_VIDEO,        // Video
  117. 0,0,0,0,0,0,0,0,0,
  118. IDC_VIDEOACT,IDC_VIDEONAME,IDS_VIDEO,IDC_VIDEOMONO,
  119. -1,-1,-1,-1,
  120. 1,1,"",100,100,0,0,0},
  121. {0x46,0x66,FLAG_STEREO|FLAG_MUTABLE,TYPE_DEFAULT,I90SRC_AUX,        // Aux
  122. 0,0,0,0,0,0,0,0,0,
  123. IDC_AUXACT,IDC_AUXNAME,IDS_AUX,IDC_AUXMONO,
  124. -1,-1,-1,-1,
  125. 1,1,"",100,100,0,0,0},
  126. {0x40,0x60,FLAG_ONLYLEFT|FLAG_MUTABLE,TYPE_DEFAULT,NO_INPUT_SEL,    // MonoIn
  127. 0,0,0,0,0,0,0,0,0,
  128. IDC_MONOACT,IDC_MONONAME,IDS_MONOIN,0,
  129. -1,-1,-1,-1,
  130. 1,1,"",100,100,0,0,0},
  131. {0x4C,0x6C,FLAG_MUTABLE,TYPE_3D,NO_INPUT_SEL,                // 3D
  132. 0,0,0,0,0,0,0,0,0,
  133. IDC_3DACT,IDC_3DNAME,IDS_3D,0,
  134. -1,-1,-1,-1,
  135. 1,1,"",100,100,1,0,0},
  136. {0x4B,0x6B,FLAG_NONE,TYPE_TONE,NO_INPUT_SEL,                // Tone
  137. 0,0,0,0,0,0,0,0,0,
  138. IDC_TONEACT,IDC_TONENAME,IDS_TONE,0,
  139. -1,-1,-1,-1,
  140. 1,1,"",50,50,0,0,0},
  141. {0x4F,0x6F,FLAG_ONLYLEFT|FLAG_MUTABLE|FLAG_LOCKABLE,TYPE_DEFAULT,NO_INPUT_SEL,    // ADC
  142. 0,0,0,0,0,0,0,0,0,
  143. IDC_ADCACT,IDC_ADCNAME,IDS_ADC,0,
  144. -1,-1,-1,-1,
  145. 1,0,"",100,100,0,0,0},        // ADC is marked inactive initially
  146. {0x4E,0x6E,FLAG_LOCKABLE|FLAG_ONLYLEFT,TYPE_SELECTOR,NO_INPUT_SEL,    // Source (must be the last one)
  147. 0,0,0,0,0,0,0,0,0,
  148. IDC_SELACT,IDC_SELNAME,IDS_INPUTSEL,0,
  149. -1,-1,-1,-1,
  150. 1,1,"",100,0,0,0,0}
  151. };
  152. int NControls=13;        // Total number of controls
  153.  
  154. int    ApiLevel=0;            // ApiLevel
  155. int    RestoreState=FALSE;        // Restore mixer settings on startup
  156. int    AutoMini=FALSE;            // Minimize on losing focus
  157. int    ChildDlg=FALSE;            // True while displaying a child window
  158.  
  159. char *InfoBuf=NULL;
  160. size_t InfoBufSize=0;
  161.  
  162. #define MAX_APP_NAME_LEN 32
  163. CHAR    szIniApp[MAX_APP_NAME_LEN]="LBMix";
  164. int    UsingPipe=FALSE;
  165. int    PipeSupport=FALSE;        // Provide pipe API
  166. TID    PipeTID=0;            // TID for pipe server
  167. HPIPE    hPipe;                // Pipe handle for pipe server
  168. char    szPipeName[CCHMAXPATH]="\\PIPE\\MIXER";
  169. int    Changing=FALSE;        // Set to TRUE while setting sliders
  170. #define MAX_INST_NAME 64
  171. char    szInstName[MAX_INST_NAME+1]="";        // Instance name
  172. int    CellsInLine=DEF_CELLS_IN_LINE;
  173. int    AutoExit=FALSE;
  174. int    ShowMenu=TRUE;
  175. int    ShowTitlebar=TRUE;
  176. CHAR    szIconFile[CCHMAXPATH]="";
  177. HPOINTER hIcon=0;
  178. int    NarrowSliders=FALSE;
  179. int    NSWidth;            // Narrow slider width
  180. int    ShortSliders=FALSE;
  181.  
  182. char szLock[32];
  183. char szMute[32];
  184. char szOff[32];
  185. char szBoth[32];
  186. char szSp[32];
  187. char szCt[32];
  188. char szLF[32];
  189. char szHF[32];
  190.  
  191. PFNWP    OldButtonWndProc,OldStaticWndProc,OldListboxWndProc,OldSliderWndProc;
  192.  
  193. struct t_Batch {
  194.    struct t_Batch *next;
  195.    char name[32];
  196.    int leftop;            // -1 - decrease, 0 - set, 1 - increase
  197.    int leftval;
  198.    int rightop;
  199.    int rightval;
  200.    int mute;            // -1 - unmute, 0 - none, 1 - mute
  201.    int lock;            // -1 - unlock, 0 - none, 1 - lock
  202.    } *Batch=NULL;
  203.  
  204. const CHAR    szKeyWindowPos[]="WindowPos";
  205. const CHAR    szKeyRestore[]="RestoreState";
  206. const CHAR    szKeyAutoMini[]="AutoMinimize";
  207. const CHAR      szLeftSuf[]="Left";
  208. const CHAR      szRightSuf[]="Right";
  209. const CHAR      szMuteSuf[]="Mute";
  210. const CHAR      szBothSuf[]="Both";
  211. const CHAR      szLockSuf[]="Lock";
  212. const CHAR      szActiveSuf[]="Active";
  213. const CHAR      szNameSuf[]="Name";
  214. const CHAR      szForeGndSuf[]="FGndColor";
  215. const CHAR      szBackGndSuf[]="BGndColor";
  216. const CHAR      szSlLClrSuf[]="SlLColor";
  217. const CHAR      szSlRClrSuf[]="SlRColor";
  218. const CHAR      szCtlPref[]="Ctl";
  219. const CHAR      szKeyInstName[]="InstanceName";
  220. const CHAR      szKeyCellsInLine[]="CellsInLine";
  221. const CHAR      szKeyShowMenu[]="ShowMenu";
  222. const CHAR      szKeyShowTitlebar[]="ShowTitlebar";
  223. const CHAR      szKeyIconFile[]="IconFile";
  224. const CHAR      szKeyLockName[]="LockName";
  225. const CHAR      szKeyMuteName[]="MuteName";
  226. const CHAR      szKeyOffName[]="OffName";
  227. const CHAR      szKeyBothName[]="BothName";
  228. const CHAR      szKeyLFName[]="LFName";
  229. const CHAR      szKeyHFName[]="HFName";
  230. const CHAR      szKeySpName[]="SpName";
  231. const CHAR      szKeyCtName[]="CtName";
  232. const CHAR      szKeyNarrowSliders[]="NarrowSliders";
  233. const CHAR      szKeyShortSliders[]="ShortSliders";
  234.  
  235. int PipeCommand(char *Buff,ULONG Size) {
  236.    ULONG ulRC;
  237.    HFILE hFile;
  238.    ULONG A;
  239.    ULONG rc;
  240.  
  241.    rc=DosWaitNPipe(szPipeName,PIPE_WAIT);
  242.    if (rc) return rc;
  243.    rc=DosOpen(szPipeName,&hFile,&A,0,0,OPEN_ACTION_OPEN_IF_EXISTS,
  244.                 OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,NULL);
  245.    if (rc) return rc;
  246.    rc=DosWrite(hFile,Buff,strlen(Buff),&A);
  247.    if (rc) return rc;
  248.    rc=DosRead(hFile,Buff,Size,&A);        // This is WRONG
  249.    if (rc) return rc;
  250.    Buff[A]=0;
  251.    return DosClose(hFile);
  252.    }
  253.  
  254.  
  255. // Set Master volume/balance (0-0x7FFF) by calling PDD IOCTL
  256. static int MasterSetVB(unsigned short vol, unsigned short bal) {
  257.    MCI_TRACK_INFO TrackInfo;
  258.    MCI_AUDIO_CHANGE AudioChange;
  259.    MCI_AUDIO_CONTROL AudioCtl;
  260.    ULONG ulSize,ulRC;
  261.    void * _Seg16 pul16;                   // defines a 16:16 pointer
  262.    extern HFILE hDriver;
  263.  
  264.    TrackInfo.usMasterVolume=vol;
  265.    TrackInfo.usDitherPct=0;        // ???
  266.    TrackInfo.usMasterVolumeDelay=0;
  267.    TrackInfo.usMasterBalance=bal;
  268.    TrackInfo.usMasterBalanceDelay=0;
  269.    pul16=(void * _Seg16)FlatToSel((unsigned long)(&TrackInfo));
  270.    AudioChange.pvDevInfo=pul16;
  271.    AudioChange.prMoreInputs=NULL;
  272.    AudioChange.prMoreOutputs=NULL;
  273.    AudioChange.pvModeInfo=NULL;
  274.    AudioCtl.usIOCtlRequest=AUDIO_CHANGE;
  275.    pul16=(void * _Seg16)FlatToSel((unsigned long)(&AudioChange));
  276.    AudioCtl.pbRequestInfo=pul16;
  277.    AudioCtl.ulPosition=0;
  278.  
  279.    ulSize=sizeof(AudioCtl);
  280.    ulRC = DosDevIOCtl(hDriver,AUDIO_IOCTL_CAT,AUDIO_CONTROL,
  281.                          NULL,0,NULL,&AudioCtl,ulSize,&ulSize);
  282.    return ulRC;
  283.    }
  284.  
  285. // Calculate value for master volume/balance
  286. static unsigned short MasterVal(int v) {
  287.    unsigned short rc;
  288.  
  289.    if (v<0) v=0;
  290.    rc=(v<<15)/100;
  291.    if (rc>0x7FFF) rc=0x7FFF;
  292.    return rc;
  293.    }
  294.  
  295. // Set Master volume by calling PDD IOCTL
  296. static int MasterSet(MIXSTRUCT *MixStruct) {
  297.    int v,b;
  298.  
  299.    if (MixStruct->VolumeL>MixStruct->VolumeR) v=MixStruct->VolumeL;
  300.    else v=MixStruct->VolumeR;
  301.    b=(100+MixStruct->VolumeL-MixStruct->VolumeR)/2;    // Balance
  302.    return MasterSetVB(MasterVal(v),MasterVal(b));
  303.    }
  304.  
  305. int CallSet(int Fn,MIXSTRUCT *MixStruct) {
  306.    char Buff[32];
  307.    int rc;
  308.  
  309.    if (!Fn) {
  310.       mciSetSysValue(MSV_MASTERVOLUME,&(MixStruct->VolumeL));
  311.       sprintf(Buff,"MASTERAUDIO VOLUME %d",MixStruct->VolumeL);
  312.       return mciSendString(Buff,NULL,0,0,0);
  313.       }
  314.    if (!UsingPipe) {
  315.       if (Fn<0x20) return MasterSet(MixStruct);
  316.       else return mixerapiIOCTL90(Fn,MixStruct,sizeof(MIXSTRUCT));
  317.       }
  318.    sprintf(Buff,"%x %d %d %x",Fn,MixStruct->VolumeL,MixStruct->VolumeR,
  319.            MixStruct->Mute);
  320.    rc=PipeCommand(Buff,31);
  321.    if (rc) return rc;
  322. // Should check for REP_OK here. Though this return code is never checked
  323.    return 0;   
  324.    }
  325.  
  326. int CallQuery(int Fn,MIXSTRUCT *MixStruct) {
  327.    char Buff[32];
  328.    int rc;
  329.  
  330.    if (!Fn) {
  331.       mciQuerySysValue(MSV_MASTERVOLUME,&(MixStruct->VolumeL));
  332.       return 0;
  333.       }
  334.    if (!UsingPipe) {
  335.       if (Fn<0x20) return 0;
  336.       else return mixerapiIOCTL90(Fn,MixStruct,sizeof(MIXSTRUCT));
  337.       }
  338.    _itoa(Fn,Buff,16);
  339.    rc=PipeCommand(Buff,31);
  340.    if (rc) return rc;
  341.    rc=sscanf(Buff,"%x %d %d %x",&Fn,&MixStruct->VolumeL,&MixStruct->VolumeR,
  342.              &MixStruct->Mute);
  343.    if (rc!=4) return 1;
  344.    return 0;
  345.    }
  346.  
  347. void SetControl(int no) {
  348.    MIXSTRUCT MixStruct;
  349.  
  350.    if (Controls[no].supported&&Controls[no].active) {
  351.       MixStruct.VolumeL=Controls[no].left;
  352.       if (Controls[no].flags&FLAG_ONLYLEFT) MixStruct.VolumeR=0;
  353.       else MixStruct.VolumeR=Controls[no].right;
  354.       if (Controls[no].mute) MixStruct.Mute=FLAG_MUTE;
  355.       else MixStruct.Mute=0;
  356.       if (Controls[no].flags&FLAG_LOCKABLE) {
  357.          if (ApiLevel>1) {
  358.             if (!Controls[no].lock) MixStruct.Mute|=FLAG_RELEASE;
  359.             }
  360.          else Controls[no].lock=TRUE;
  361.          }
  362.       CallSet(Controls[no].setfunc,&MixStruct);
  363.       }
  364.    }
  365. void DisplayControl(int no) {
  366.    int EnabledL,i,j;
  367.    HWND hwndList;
  368.  
  369.    if (!(Controls[no].supported&&Controls[no].active)) return;
  370.    Changing=TRUE;
  371.    if (Controls[no].flags&FLAG_LOCKABLE) EnabledL=Controls[no].lock;
  372.    else EnabledL=TRUE;
  373.  
  374.    if (!(Controls[no].flags&FLAG_ONLYRIGHT)) {
  375.       WinEnableWindow(Controls[no].hwndLeft,EnabledL);
  376.       if (Controls[no].supported) {
  377.          if (Controls[no].type==TYPE_SELECTOR) {
  378.             hwndList=Controls[no].hwndLeft;
  379.             for (i=0,j=0;i<NControls;i++) if ((Controls[i].sel!=NO_INPUT_SEL)&&(Controls[i].supported)) {
  380.                if (Controls[i].sel&Controls[no].left)
  381.                   WinSendMsg(hwndList,LM_SELECTITEM,(MPARAM)j,(MPARAM)TRUE);
  382.                else
  383.                   WinSendMsg(hwndList,LM_SELECTITEM,(MPARAM)j,(MPARAM)FALSE);
  384.                j++;
  385.                }
  386.             }
  387.          else {
  388.             j=Controls[no].left;
  389.             if (ShortSliders) j/=2;
  390.             WinSendMsg(Controls[no].hwndLeft,
  391.                SLM_SETSLIDERINFO,MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  392.                SMA_INCREMENTVALUE), (MPARAM)j);
  393.             }
  394.          }
  395.       }
  396.    if (!(Controls[no].flags&FLAG_ONLYLEFT)) {
  397.       WinEnableWindow(Controls[no].hwndRight,EnabledL);
  398.       if (Controls[no].supported) {
  399.          j=Controls[no].right;
  400.          if (ShortSliders) j/=2;
  401.          WinSendMsg(Controls[no].hwndRight,
  402.             SLM_SETSLIDERINFO,MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  403.             SMA_INCREMENTVALUE), (MPARAM)j);
  404.          }
  405.       }
  406.    if (Controls[no].flags&FLAG_MUTABLE) {
  407.       WinEnableWindow(Controls[no].hwndMute,EnabledL);
  408.       if (Controls[no].supported) WinSendMsg(Controls[no].hwndMute,BM_SETCHECK,
  409.             (MPARAM)Controls[no].mute,0);
  410.       }
  411.    if (Controls[no].flags&FLAG_STEREO) {
  412.       if (Controls[no].supported) WinSendMsg(Controls[no].hwndBoth,BM_SETCHECK,
  413.             (MPARAM)Controls[no].both,0);
  414.       }
  415.    if (Controls[no].flags&FLAG_LOCKABLE) {
  416.       if ((ApiLevel<=1)&&(Controls[no].lock))
  417.          WinEnableWindow(Controls[no].hwndLock,FALSE);
  418.       else
  419.          WinEnableWindow(Controls[no].hwndLock,TRUE);
  420.       if (Controls[no].supported) WinSendMsg(Controls[no].hwndLock,BM_SETCHECK,
  421.             (MPARAM)Controls[no].lock,0);
  422.       }
  423.    Changing=FALSE;
  424.    return;
  425.    }
  426.  
  427. void QueryControl(int no) {
  428.    MIXSTRUCT MixStruct;
  429.  
  430.    if (Controls[no].supported) {
  431.       MixStruct.VolumeL=Controls[no].left;
  432.       MixStruct.VolumeR=Controls[no].right;
  433.       if (!CallQuery(Controls[no].qfunc,&MixStruct)) {
  434.          Controls[no].left=MixStruct.VolumeL;
  435.          Controls[no].right=MixStruct.VolumeR;
  436.          Controls[no].mute=(MixStruct.Mute&FLAG_MUTE);
  437.          if (Controls[no].flags&FLAG_LOCKABLE)
  438.             Controls[no].lock=!(MixStruct.Mute&FLAG_RELEASE);
  439.          }
  440.       }
  441.    return;
  442.    }
  443.  
  444. void SetControls() {
  445.    int i;
  446.  
  447.    for (i=0;i<NControls;i++) SetControl(i);
  448.    return;
  449.    }
  450. void DisplayControls() {
  451.    int i;
  452.  
  453.    for (i=0;i<NControls;i++) DisplayControl(i);
  454.    return;
  455.    }
  456.  
  457. void QueryControls() {
  458.    int i;
  459.  
  460.    for (i=0;i<NControls;i++) QueryControl(i);
  461.    return;
  462.    }
  463.  
  464. // Hide titlebar if it is disabled
  465. void HideTitle() {
  466.    SWP swp,swpFrame,swpMenu;
  467.    HWND hwndMenu;
  468.    int cy;
  469.  
  470.    if (ShowTitlebar) return;
  471.  
  472.    if (ShowMenu) {
  473.       hwndMenu=WinWindowFromID(hwndMainFrame,FID_MENU);
  474.       WinQueryWindowPos(hwndMenu,&swpMenu);
  475.       }
  476.  
  477.    WinQueryWindowPos(hwndMain,&swp);
  478.    WinQueryWindowPos(hwndMainFrame,&swpFrame);
  479.    cy=swpFrame.cy-2*swp.y;
  480.    if (ShowMenu) {
  481.       WinSetWindowPos(hwndMenu,HWND_TOP,swpMenu.x,
  482.                    swpFrame.cy-swp.y-swpMenu.cy,
  483.                    swpMenu.cx, swpMenu.cy,SWP_SIZE|SWP_MOVE|SWP_ZORDER);
  484.       cy-=swpMenu.cy;
  485.       }
  486.    WinSetWindowPos(hwndMain,HWND_TOP,swp.x,swp.y,swpFrame.cx-2*swp.x,
  487.                    cy,SWP_SIZE|SWP_MOVE|SWP_ZORDER);
  488.    }
  489.  
  490. void SetClipSiblings(HWND hwnd) {
  491.    ULONG ul;
  492.  
  493.    ul=WinQueryWindowULong(hwnd,QWL_STYLE);
  494.    ul|=WS_CLIPSIBLINGS;
  495.    WinSetWindowULong(hwnd,QWL_STYLE,ul);
  496.    return;
  497.    }
  498.  
  499. // Query control colors and store them into Controls array
  500. void QueryCtlColors() {
  501.    int i;
  502.  
  503.    for (i=0;i<NControls;i++) if (Controls[i].hwndRect) {
  504.       if (!WinQueryPresParam(Controls[i].hwndRect,PP_BACKGROUNDCOLOR,
  505.                             PP_BACKGROUNDCOLORINDEX,NULL,sizeof(LONG),
  506.                             &Controls[i].BgColor,QPF_ID2COLORINDEX))
  507.          Controls[i].BgColor=-1;
  508.       if (!WinQueryPresParam(Controls[i].hwndRect,PP_FOREGROUNDCOLOR,
  509.                                  PP_FOREGROUNDCOLORINDEX,NULL,sizeof(LONG),
  510.                                  &Controls[i].FgColor,QPF_ID2COLORINDEX))
  511.          Controls[i].FgColor=-1;
  512.       if (Controls[i].type==TYPE_SELECTOR) {
  513.          if (Controls[i].hwndLeft) {
  514.             if (!WinQueryPresParam(Controls[i].hwndLeft,PP_BACKGROUNDCOLOR,
  515.                                  PP_BACKGROUNDCOLORINDEX,NULL,sizeof(LONG),
  516.                                  &Controls[i].SlLColor,QPF_ID2COLORINDEX))
  517.                Controls[i].SlLColor=-1;
  518.             if (!WinQueryPresParam(Controls[i].hwndLeft,PP_FOREGROUNDCOLOR,
  519.                                  PP_FOREGROUNDCOLORINDEX,NULL,sizeof(LONG),
  520.                                  &Controls[i].SlRColor,QPF_ID2COLORINDEX))
  521.                Controls[i].SlRColor=-1;
  522.             }
  523.          }
  524.       else {
  525.          if (Controls[i].hwndLeft) {
  526.             if (!WinQueryPresParam(Controls[i].hwndLeft,PP_BUTTONBACKGROUNDCOLOR,
  527.                                  0,NULL,sizeof(LONG),
  528.                                  &Controls[i].SlLColor,0))
  529.                Controls[i].SlLColor=-1;
  530.             }
  531.          if (Controls[i].hwndRight) {
  532.             if (!WinQueryPresParam(Controls[i].hwndRight,PP_BUTTONBACKGROUNDCOLOR,
  533.                                  0,NULL,sizeof(LONG),
  534.                                  &Controls[i].SlRColor,0))
  535.                Controls[i].SlRColor=-1;
  536.             }
  537.          }
  538.       }
  539.    }
  540.  
  541. // Create the main window
  542. void MainCreate() {
  543.    ULONG ctlData= FCF_TASKLIST | FCF_DLGBORDER | FCF_AUTOICON | FCF_ACCELTABLE
  544.                   | FCF_ICON | FCF_TITLEBAR | FCF_SYSMENU;  
  545.    char szName[MESSAGELEN];
  546.  
  547.    if (hwndMainFrame) {
  548.       QueryCtlColors();
  549.       WinStoreWindowPos((char *)szIniApp,(char *)szKeyWindowPos,hwndMainFrame);
  550.       WinDestroyWindow(hwndMainFrame);
  551.       hwndMainFrame=0;
  552.       }
  553.    if (hIcon) {
  554.       WinFreeFileIcon(hIcon);
  555.       hIcon=0;
  556.       }
  557.  
  558.    WinLoadString(hab, 0, IDS_SWTITLE, MESSAGELEN, szName);
  559.    if (*szInstName) {
  560.       strncat(szName," - ",MESSAGELEN);
  561.       strncat(szName,szInstName,MESSAGELEN);
  562.       }
  563.    if (ShowMenu) ctlData|=FCF_MENU;
  564.    if (ShowTitlebar) ctlData|=FCF_MINBUTTON;
  565.    hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,0,
  566.             (PVOID)&ctlData,(PSZ)"MAIN",(PSZ)szName,0,
  567.                         (HMODULE)NULL,ID_MAIN,(PHWND)&hwndMain);
  568.    if (!ShowTitlebar) {
  569.       SetClipSiblings(WinWindowFromID(hwndMainFrame,FID_TITLEBAR));
  570.       SetClipSiblings(WinWindowFromID(hwndMainFrame,FID_SYSMENU));
  571.       }
  572.    if (*szIconFile) {
  573.       hIcon=WinLoadFileIcon(szIconFile,FALSE);
  574.       if (hIcon) WinSendMsg(hwndMainFrame,WM_SETICON,(MPARAM) hIcon,0);
  575.       }
  576.    return;
  577.    }
  578.  
  579. void ResizeMain(int x,int y) {
  580.    SWP swp;
  581.  
  582.    WinQueryWindowPos(hwndMainFrame,&swp);
  583.    WinSetWindowPos(hwndMainFrame,0,swp.x,swp.y+swp.cy-y,
  584.                    x,y,SWP_SIZE|SWP_MOVE);
  585.    }
  586.  
  587. // Return string width in points
  588. int StrWidth(HPS hps, char *str) {
  589.    POINTL aptlPoints[TXTBOX_COUNT];
  590.    int l,r;
  591.  
  592.    GpiQueryTextBox(hps,strlen(str),str,TXTBOX_COUNT,aptlPoints);
  593.    if (aptlPoints[TXTBOX_TOPRIGHT].x>aptlPoints[TXTBOX_BOTTOMRIGHT].x)
  594.       r=aptlPoints[TXTBOX_TOPRIGHT].x;
  595.    else r=aptlPoints[TXTBOX_BOTTOMRIGHT].x;
  596.    if (aptlPoints[TXTBOX_TOPLEFT].x<aptlPoints[TXTBOX_BOTTOMLEFT].x)
  597.       l=aptlPoints[TXTBOX_TOPLEFT].x;
  598.    else l=aptlPoints[TXTBOX_BOTTOMLEFT].x;
  599.    return r-l;
  600.    }
  601.  
  602. LONG RGBMix(LONG c1, LONG c2) {
  603.    LONG rc;
  604.  
  605.    rc=((c1&0xFF)+(c2&0xFF))>>1;
  606.    rc|=(((c1&0xFF00)+(c2&0xFF00))>>1)&0xFF00;
  607.    rc|=(((c1&0xFF0000)+(c2&0xFF0000))>>1)&0xFF0000;
  608.    return rc;
  609.    }
  610.  
  611. // Create the main window controls
  612. void MainWindow() {
  613.    int i,no,xcells,ycells,x,y,t,actc;
  614.    SLDCDATA sldcData;
  615.    SWP swp;
  616.    HPS      hps;
  617.    FONTMETRICS   fmMetrics;
  618.    PPRESPARAMS ppres;
  619.    LONG Dark,Light;
  620.  
  621. // Control layout flags
  622. #define CLF_LOCK 1
  623. #define CLF_MUTE 2
  624. #define CLF_OFF  4
  625. #define CLF_BOTH 8
  626. #define CLF_LDLF 0x10
  627. #define CLF_RDHF 0x20
  628. #define CLF_LISTS 0x40            // List - single sel
  629. #define CLF_LEFT 0x80
  630. #define CLF_RIGHT 0x100
  631. #define CLF_LDSP 0x200
  632. #define CLF_RDCT 0x400
  633. #define CLF_LISTM 0x800            // List - multi sel
  634.    struct t_CtlLay{            // Control layout structure
  635.       int no;                // Control no
  636.       int celly;            // y in cells upper = 1, lower = 2
  637.       int flags;
  638.       int checkx,checkw;        // Checkbox x, max width
  639.       int dscw;                // Description max width
  640.       int ldscx;
  641.       int rdscx;
  642.       int leftx;            // Or listbox
  643.       int rightx;
  644.       int boxw;
  645.       } *CtlLay;
  646.    int sliderw, listw;            /* Slider, listbox widths */
  647.    int sliderh,listh,checkh,boxh;    /* Cell slider, listbox, checkbox/
  648.                                            description, groupbox heights */
  649.    int locky,mutey,bothy,slidery;    /* Box, lock, mute/off/listbox,
  650.                                            both/description, slider y */
  651.    int spacex,spacey;            /* Inter-control spacing */
  652.    int cellspx,cellspy;            /* Inter-cell spacing */
  653.    int fieldx,fieldy;        /* Field left/right, top/bottom */
  654.    int interx,interb,intert;    /* Interior field left/right, top, bottom */
  655.  
  656.    int borderw,borderh;        /* Window border width/height */
  657.  
  658.  
  659.    borderw=WinQuerySysValue(HWND_DESKTOP,SV_CXDLGFRAME);
  660.    borderh=WinQuerySysValue(HWND_DESKTOP,SV_CYDLGFRAME);
  661.  
  662.    HideTitle();
  663.  
  664.    actc=0;
  665.    for (no=0;no<NControls;no++)    {            // Count active controls
  666.       if (Controls[no].supported&&Controls[no].active) actc++;
  667.       Controls[no].hwndGroup=0;
  668.       Controls[no].hwndLeft=0;
  669.       Controls[no].hwndRight=0;
  670.       Controls[no].hwndMute=0;
  671.       Controls[no].hwndBoth=0;
  672.       Controls[no].hwndLock=0;
  673.       Controls[no].hwndLdesc=0;
  674.       Controls[no].hwndRdesc=0;
  675.       Controls[no].hwndRect=0;
  676.       }
  677.    if (!actc) {
  678.       ResizeMain(EMPTY_W,EMPTY_H);
  679.       return;
  680.       }
  681.    CtlLay=malloc(actc*sizeof(struct t_CtlLay));
  682.    xcells=actc;
  683.    ycells=1;
  684.    if (xcells>CellsInLine) {
  685.       xcells=xcells/2+xcells%2;
  686.       ycells++;
  687.       }
  688.  
  689.    for (x=0,y=1,i=0,no=0;no<NControls;no++)        // Distribute controls
  690.       if (Controls[no].supported&&Controls[no].active) {
  691.          CtlLay[i].no=no;
  692.          CtlLay[i].celly=y;
  693.          i++;
  694.          x++;
  695.          if (x>=xcells) {
  696.             x=0;
  697.             y++;
  698.             }
  699.          }
  700.  
  701. /* Sizes common for all controls */
  702.     hps = WinGetPS(hwndMain);
  703.     GpiQueryFontMetrics (hps,sizeof (FONTMETRICS),&fmMetrics);
  704. #define FONTH (fmMetrics.lMaxBaselineExt)
  705. #define FONTW (fmMetrics.lAveCharWidth)
  706.  
  707.     if (NarrowSliders) sliderw=NSWidth;
  708.     else sliderw=SLIDER_W_S;
  709.     if (ShortSliders) sliderh=SLIDER_H_S;
  710.     else sliderh=SLIDER_H_N;
  711.  
  712.     listw=LIST_W_O+LIST_W_M*FONTW;
  713.  
  714.     checkh=FONTH+FONTH/CHECK_H_D;
  715.     if (checkh<CHECK_H_MIN) checkh=CHECK_H_MIN;
  716.  
  717.     spacex=SPACE_X_O+FONTW/SPACE_X_D;
  718.     spacey=SPACE_Y_O+FONTH/SPACE_Y_D;    
  719.  
  720.     cellspx=CELLSP_X_O+FONTW*CELLSP_X_M/CELLSP_X_D;
  721.     cellspy=CELLSP_Y_O+FONTH*CELLSP_Y_M/CELLSP_Y_D;
  722.  
  723.     fieldx=FIELD_X_O+FONTW*FIELD_X_M/FIELD_X_D;
  724.     fieldy=FIELD_Y_O+FONTH*FIELD_Y_M/FIELD_Y_D;
  725.  
  726.     interx=INTER_X_O+FONTW*INTER_X_M/INTER_X_D;
  727.     intert=INTER_T_O+FONTH*INTER_T_M/INTER_T_D;
  728.     interb=INTER_B_O+FONTH*INTER_B_M/INTER_B_D;
  729.  
  730.     locky=interb;
  731.     mutey=locky+spacey+checkh;
  732.     bothy=mutey+spacey+checkh;
  733.     slidery=bothy+spacey+checkh;
  734.     listh=3*spacey+2*checkh+sliderh;
  735.     boxh=slidery+sliderh+intert;
  736.  
  737.     for(i=0;i<actc;i++) {        // Calculate flags/control sizes
  738.  
  739.        t=0;                // Calculate flags
  740.        no=CtlLay[i].no;
  741.        if (Controls[no].flags&FLAG_LOCKABLE) t|=CLF_LOCK;
  742.        if (Controls[no].type==TYPE_SELECTOR) {
  743.           if (Controls[no].flags&FLAG_MULTIPLE) t|=CLF_LISTM;
  744.           else t|=CLF_LISTS;
  745.           }
  746.        else if ((Controls[no].type==TYPE_3D)||(Controls[no].type==TYPE_TONE)){ 
  747.           if (Controls[no].flags&FLAG_MUTABLE) t|=CLF_OFF;
  748.           if (!(Controls[no].flags&FLAG_ONLYRIGHT)) {
  749.              t|=CLF_LEFT;
  750.              if (Controls[no].type==TYPE_3D) t|=CLF_LDSP;
  751.              else t|=CLF_LDLF;
  752.              }
  753.           if (!(Controls[no].flags&FLAG_ONLYLEFT)) {
  754.              t|=CLF_RIGHT;
  755.              if (Controls[no].type==TYPE_3D) t|=CLF_RDCT;
  756.              else t|=CLF_RDHF;
  757.              }
  758.           }
  759.        else {            // default control type
  760.           if (Controls[no].flags&FLAG_MUTABLE) t|=CLF_MUTE;
  761.           if (!(Controls[no].both&BOTH_MONO)&&
  762.              (Controls[no].flags&FLAG_STEREO)) t|=CLF_BOTH;
  763.           if (!(Controls[no].flags&FLAG_ONLYRIGHT)) t|=CLF_LEFT;
  764.           if (!(Controls[no].both&BOTH_MONO)&&
  765.              !(Controls[no].flags&FLAG_ONLYLEFT))  t|=CLF_RIGHT;
  766.           }
  767.        CtlLay[i].flags=t;
  768.  
  769. // Calculate control sizes
  770.  
  771.       CtlLay[i].boxw=BOX_W_O+FONTW*BOX_W_M/BOX_W_D+StrWidth(hps,Controls[no].name);
  772.       if (t&CLF_LOCK)
  773.          CtlLay[i].checkw=StrWidth(hps,szLock);
  774.       else CtlLay[i].checkw=0;
  775.       if (t&CLF_OFF) {
  776.          x=StrWidth(hps,szOff);
  777.          if (x>CtlLay[i].checkw) CtlLay[i].checkw=x;
  778.          }
  779.       if (t&CLF_MUTE) {
  780.          x=StrWidth(hps,szMute);
  781.          if (x>CtlLay[i].checkw) CtlLay[i].checkw=x;
  782.          }
  783.       if (t&CLF_BOTH) {
  784.          x=StrWidth(hps,szBoth);
  785.          if (x>CtlLay[i].checkw) CtlLay[i].checkw=x;
  786.          }
  787.       CtlLay[i].checkw+=CHECK_W_O+FONTW*CHECK_W_M/CHECK_W_D;
  788.       if (t&CLF_LDLF) 
  789.          CtlLay[i].dscw=StrWidth(hps,szLF);
  790.       else CtlLay[i].dscw=0;
  791.       if (t&CLF_LDSP) {
  792.          x=StrWidth(hps,szSp);
  793.          if (x>CtlLay[i].dscw) CtlLay[i].dscw=x;
  794.          }
  795.       if (t&CLF_RDHF) {
  796.          x=StrWidth(hps,szHF);
  797.          if (x>CtlLay[i].dscw) CtlLay[i].dscw=x;
  798.          }
  799.       if (t&CLF_RDCT) {
  800.          x=StrWidth(hps,szCt);
  801.          if (x>CtlLay[i].dscw) CtlLay[i].dscw=x;
  802.          }
  803.       CtlLay[i].dscw+=DESC_W_O+FONTW*DESC_W_M/DESC_W_D;
  804.  
  805. // Calculate box size
  806.  
  807.       if ((t&(CLF_LOCK|CLF_MUTE|CLF_OFF|CLF_BOTH))
  808.          &&(CtlLay[i].checkw>CtlLay[i].boxw)) CtlLay[i].boxw=CtlLay[i].checkw;
  809.       if ((t&(CLF_LISTS|CLF_LISTM))&&(listw>CtlLay[i].boxw))
  810.             CtlLay[i].boxw=listw;
  811.       else {
  812.          if (t&(CLF_LDLF|CLF_LDSP|CLF_RDHF|CLF_RDCT)) {
  813.             if ((t&(CLF_LDLF|CLF_LDSP))&&(t&(CLF_RDHF|CLF_RDCT))) {
  814.                if ((2*CtlLay[i].dscw+spacex)>CtlLay[i].boxw)
  815.                   CtlLay[i].boxw=2*CtlLay[i].dscw+spacex;
  816.                }
  817.             else {
  818.                if (CtlLay[i].dscw>CtlLay[i].boxw)
  819.                   CtlLay[i].boxw=CtlLay[i].dscw;
  820.                }
  821.             }
  822.          if (t&(CLF_LEFT|CLF_RIGHT)) {
  823.             if ((t&CLF_LEFT)&&(t&CLF_RIGHT)) {
  824.                if ((2*sliderw+spacex)>CtlLay[i].boxw)
  825.                   CtlLay[i].boxw=2*sliderw+spacex;
  826.                }
  827.             else if (sliderw>CtlLay[i].boxw)
  828.                   CtlLay[i].boxw=sliderw;
  829.             }
  830.          }
  831.       CtlLay[i].boxw+=2*interx;
  832.  
  833. // Calculate controls x positions
  834.  
  835.       if (t&(CLF_LOCK|CLF_MUTE|CLF_OFF|CLF_BOTH)) {
  836.          CtlLay[i].checkx=(CtlLay[i].boxw-CtlLay[i].checkw)/2;
  837.          if (CtlLay[i].checkx<interx) CtlLay[i].checkx=interx;
  838.          }
  839.       if (t&(CLF_LISTS|CLF_LISTM)) {
  840.          CtlLay[i].leftx=(CtlLay[i].boxw-listw)/2;
  841.          if (CtlLay[i].leftx<interx) CtlLay[i].leftx=interx;
  842.          }
  843.       else {
  844.          if (t&(CLF_LDLF|CLF_LDSP|CLF_RDHF|CLF_RDCT)) {
  845.             if ((t&(CLF_LDLF|CLF_LDSP))&&(t&(CLF_RDHF|CLF_RDCT))) {
  846.                x=CtlLay[i].boxw/3;
  847.                CtlLay[i].ldscx=x-CtlLay[i].dscw/2;
  848.                CtlLay[i].rdscx=2*x-CtlLay[i].dscw/2;
  849.                if ((CtlLay[i].rdscx-CtlLay[i].ldscx-CtlLay[i].dscw)<spacex) {
  850.                   CtlLay[i].ldscx=(CtlLay[i].boxw-spacex)/2-CtlLay[i].dscw;
  851.                   CtlLay[i].rdscx=(CtlLay[i].boxw+spacex)/2;
  852.                   }
  853.                if (CtlLay[i].ldscx<interx) CtlLay[i].ldscx=interx;
  854.                if (CtlLay[i].rdscx>(CtlLay[i].boxw-interx-CtlLay[i].dscw))
  855.                    CtlLay[i].rdscx=CtlLay[i].boxw-interx-CtlLay[i].dscw;
  856.                }
  857.             else if (t&(CLF_LDLF|CLF_LDSP)) {
  858.                CtlLay[i].ldscx=(CtlLay[i].boxw-CtlLay[i].dscw)/2;
  859.                if (CtlLay[i].ldscx<interx) CtlLay[i].ldscx=interx;
  860.                }
  861.             else {
  862.                CtlLay[i].rdscx=(CtlLay[i].boxw-CtlLay[i].dscw)/2;
  863.                if (CtlLay[i].rdscx<interx) CtlLay[i].rdscx=interx;
  864.                }
  865.             }
  866.          if (t&(CLF_LEFT|CLF_RIGHT)) {
  867.             if ((t&CLF_LEFT)&&(t&CLF_RIGHT)) {
  868.                x=CtlLay[i].boxw/3;
  869.                CtlLay[i].leftx=x-sliderw/2;
  870.                CtlLay[i].rightx=2*x-sliderw/2;
  871.                if ((CtlLay[i].rightx-CtlLay[i].leftx-sliderw)<spacex) {
  872.                   CtlLay[i].leftx=(CtlLay[i].boxw-spacex)/2-sliderw;
  873.                   CtlLay[i].rightx=(CtlLay[i].boxw+spacex)/2;
  874.                   }
  875.                if (CtlLay[i].leftx<interx) CtlLay[i].leftx=interx;
  876.                if (CtlLay[i].rightx>(CtlLay[i].boxw-interx-sliderw))
  877.                    CtlLay[i].rightx=CtlLay[i].boxw-interx-sliderw;
  878.                }
  879.             else if (t&CLF_LEFT) {
  880.                CtlLay[i].leftx=(CtlLay[i].boxw-sliderw)/2;
  881.                if (CtlLay[i].leftx<interx) CtlLay[i].leftx=interx;
  882.                }
  883.             else {
  884.                CtlLay[i].rightx=(CtlLay[i].boxw-sliderw)/2;
  885.                if (CtlLay[i].rightx<interx) CtlLay[i].rightx=interx;
  886.                }
  887.             }
  888.          }
  889.       }       // big layout calculation loop
  890.  
  891. // Calculate/set window size
  892.    y=boxh*ycells+cellspy*(ycells-1)+2*fieldy+2*borderh;
  893.    if (ShowTitlebar) {
  894.       WinQueryWindowPos(WinWindowFromID(hwndMainFrame,FID_TITLEBAR),&swp);
  895.       y+=swp.cy;
  896.       }
  897.    if (ShowMenu) {
  898.       WinQueryWindowPos(WinWindowFromID(hwndMainFrame,FID_MENU),&swp);
  899.       y+=swp.cy;
  900.       }
  901.    x=0;
  902.    for (i=0;(i<actc)&&(CtlLay[i].celly==1);i++) {
  903.       if (x) x+=cellspx;
  904.       x+=CtlLay[i].boxw;
  905.       }
  906.    if (ycells>1) {
  907.       t=0;
  908.       for (;i<actc;i++) {
  909.          if (t) t+=cellspx;
  910.          t+=CtlLay[i].boxw;
  911.          }
  912.       if (t>x) x=t;
  913.       }
  914.    x+=2*fieldx+2*borderw;
  915.    ResizeMain(x,y);
  916.    WinReleasePS(hps);
  917.  
  918.    Changing=TRUE;
  919.  
  920.    x=fieldx;
  921.    y=(ycells-1)*(boxh+cellspy)+fieldy;
  922.    for(i=0;i<actc;i++) {        // Display controls
  923.       no=CtlLay[i].no;
  924.       if ((Controls[no].FgColor!=-1)||(Controls[no].BgColor!=-1)) {
  925.          if ((Controls[no].FgColor!=-1)&&(Controls[no].BgColor!=-1)) {
  926.             ppres=malloc(sizeof(ULONG)*7);
  927.             ppres->cb=sizeof(ULONG)*6;
  928.             ppres->aparam[0].id=PP_BACKGROUNDCOLOR;
  929.             ppres->aparam[0].cb=sizeof(LONG);
  930.             memcpy(&ppres->aparam[0].ab,&Controls[no].BgColor,sizeof(LONG));
  931.             ppres->aparam[1].id=PP_FOREGROUNDCOLOR;
  932.             ppres->aparam[1].cb=sizeof(LONG);
  933.             memcpy(&ppres->aparam[1].ab,&Controls[no].FgColor,sizeof(LONG));
  934.             }
  935.          else {
  936.             ppres=malloc(sizeof(ULONG)*4);
  937.             ppres->cb=sizeof(ULONG)*3;
  938.             ppres->aparam[0].cb=sizeof(LONG);
  939.             if (Controls[no].FgColor!=-1) {
  940.                ppres->aparam[0].id=PP_FOREGROUNDCOLOR;
  941.                memcpy(&ppres->aparam[0].ab,&Controls[no].FgColor,sizeof(LONG));
  942.                }
  943.             else {
  944.                ppres->aparam[0].id=PP_BACKGROUNDCOLOR;
  945.                memcpy(&ppres->aparam[0].ab,&Controls[no].BgColor,sizeof(LONG));
  946.                }
  947.             }
  948.          }
  949.       else ppres=NULL; 
  950.       Controls[no].hwndRect=WinCreateWindow(hwndMain,"CONTROL",NULL,
  951.                        WS_VISIBLE,x,y,CtlLay[i].boxw,boxh,
  952.                        hwndMain,HWND_TOP,0,NULL,ppres);
  953.       if (ppres) free(ppres);
  954.       Controls[no].hwndGroup=WinCreateWindow(Controls[no].hwndRect,WC_STATIC,Controls[no].name,
  955.                        WS_VISIBLE|SS_GROUPBOX,0,0,CtlLay[i].boxw,boxh,
  956.                        Controls[no].hwndRect,HWND_TOP,0,NULL,NULL);
  957.       OldStaticWndProc=WinSubclassWindow(Controls[no].hwndGroup,StaticWndProc);
  958.       if (CtlLay[i].flags&CLF_LOCK) {
  959.          Controls[no].hwndLock=WinCreateWindow(Controls[no].hwndRect,WC_BUTTON,szLock,
  960.                        WS_VISIBLE|BS_AUTOCHECKBOX|WS_TABSTOP,
  961.                        CtlLay[i].checkx,locky,CtlLay[i].checkw,checkh,
  962.                        Controls[no].hwndRect,HWND_TOP,IDC_LOCK|no,NULL,NULL);
  963.          OldButtonWndProc=WinSubclassWindow(Controls[no].hwndLock,ButtonWndProc);
  964.          }
  965.       if (CtlLay[i].flags&(CLF_LISTS|CLF_LISTM)) {
  966.          t=WS_VISIBLE|WS_TABSTOP;
  967.          if (CtlLay[i].flags&CLF_LISTM) t|=LS_MULTIPLESEL;
  968.          if (Controls[no].SlLColor!=-1) {
  969.             Light=RGBMix(Controls[no].SlLColor,RGB_WHITE);
  970.             Dark=RGBMix(Controls[no].SlLColor,RGB_BLACK);
  971.             if (Controls[no].SlRColor!=-1) {
  972.                ppres=malloc(sizeof(ULONG)*13);
  973.                ppres->cb=sizeof(ULONG)*12;
  974.                ppres->aparam[3].id=PP_FOREGROUNDCOLOR;
  975.                ppres->aparam[3].cb=sizeof(LONG);
  976.                memcpy(&ppres->aparam[3].ab,&Controls[no].SlRColor,sizeof(LONG));
  977.                }
  978.             else {
  979.                ppres=malloc(sizeof(ULONG)*10);
  980.                ppres->cb=sizeof(ULONG)*9;
  981.                }
  982.             ppres->aparam[0].id=PP_BACKGROUNDCOLOR;
  983.             ppres->aparam[0].cb=sizeof(LONG);
  984.             memcpy(&ppres->aparam[0].ab,&Controls[no].SlLColor,sizeof(LONG));
  985.             ppres->aparam[1].id=PP_BORDERLIGHTCOLOR;
  986.             ppres->aparam[1].cb=sizeof(LONG);
  987.             memcpy(&ppres->aparam[1].ab,&Light,sizeof(LONG));
  988.             ppres->aparam[2].id=PP_BORDERDARKCOLOR;
  989.             ppres->aparam[2].cb=sizeof(LONG);
  990.             memcpy(&ppres->aparam[2].ab,&Dark,sizeof(LONG));
  991.             }
  992.          else if (Controls[no].SlRColor!=-1) {
  993.                ppres=malloc(sizeof(ULONG)*4);
  994.                ppres->cb=sizeof(ULONG)*3;
  995.                ppres->aparam[0].id=PP_FOREGROUNDCOLOR;
  996.                ppres->aparam[0].cb=sizeof(LONG);
  997.                memcpy(&ppres->aparam[0].ab,&Controls[no].SlRColor,sizeof(LONG));
  998.                }
  999.          else ppres=NULL;
  1000.          Controls[no].hwndLeft=WinCreateWindow(Controls[no].hwndRect,WC_LISTBOX,NULL,
  1001.                        t,CtlLay[i].leftx,mutey,listw,listh,
  1002.                        Controls[no].hwndRect,HWND_TOP,IDC_LIST|no,NULL,ppres);
  1003.          OldListboxWndProc=WinSubclassWindow(Controls[no].hwndLeft,ListboxWndProc);
  1004.          if (ppres) free(ppres);
  1005.          for (i=0;i<NControls;i++)
  1006.             if ((Controls[i].sel!=NO_INPUT_SEL)&&(Controls[i].supported))
  1007.                 WinSendMsg(Controls[no].hwndLeft,LM_INSERTITEM,MPFROMSHORT(LIT_END),
  1008.                            MPFROMP((PSZ)Controls[i].name));
  1009.          }
  1010.       else {
  1011.          if (CtlLay[i].flags&CLF_OFF) {
  1012.             Controls[no].hwndMute=WinCreateWindow(Controls[no].hwndRect,WC_BUTTON,szOff,
  1013.                        WS_VISIBLE|BS_AUTOCHECKBOX|WS_TABSTOP,
  1014.                        CtlLay[i].checkx,mutey,CtlLay[i].checkw,checkh,
  1015.                        Controls[no].hwndRect,HWND_TOP,IDC_MUTE|no,NULL,NULL);
  1016.             OldButtonWndProc=WinSubclassWindow(Controls[no].hwndMute,ButtonWndProc);
  1017.             }
  1018.          else if (CtlLay[i].flags&CLF_MUTE) {
  1019.             Controls[no].hwndMute=WinCreateWindow(Controls[no].hwndRect,WC_BUTTON,szMute,
  1020.                        WS_VISIBLE|BS_AUTOCHECKBOX|WS_TABSTOP,
  1021.                        CtlLay[i].checkx,mutey,CtlLay[i].checkw,checkh,
  1022.                        Controls[no].hwndRect,HWND_TOP,IDC_MUTE|no,NULL,NULL);
  1023.             OldButtonWndProc=WinSubclassWindow(Controls[no].hwndMute,ButtonWndProc);
  1024.             }
  1025.          if (CtlLay[i].flags&CLF_BOTH) {
  1026.             Controls[no].hwndBoth=WinCreateWindow(Controls[no].hwndRect,WC_BUTTON,szBoth,
  1027.                        WS_VISIBLE|BS_AUTOCHECKBOX|WS_TABSTOP,
  1028.                        CtlLay[i].checkx,bothy,CtlLay[i].checkw,checkh,
  1029.                        Controls[no].hwndRect,HWND_TOP,IDC_BOTH|no,NULL,NULL);
  1030.             OldButtonWndProc=WinSubclassWindow(Controls[no].hwndBoth,ButtonWndProc);
  1031.             }
  1032.          else {
  1033.             if (CtlLay[i].flags&CLF_LDSP) {
  1034.                Controls[no].hwndLdesc=WinCreateWindow(Controls[no].hwndRect,WC_STATIC,szSp,
  1035.                        WS_VISIBLE | SS_TEXT | DT_VCENTER | DT_CENTER,
  1036.                        CtlLay[i].ldscx,bothy,CtlLay[i].dscw,checkh,
  1037.                        Controls[no].hwndRect,HWND_TOP,0,&sldcData,NULL);
  1038.                OldStaticWndProc=WinSubclassWindow(Controls[no].hwndLdesc,StaticWndProc);
  1039.                }
  1040.             else if (CtlLay[i].flags&CLF_LDLF) {
  1041.                Controls[no].hwndLdesc=WinCreateWindow(Controls[no].hwndRect,WC_STATIC,szLF,
  1042.                        WS_VISIBLE | SS_TEXT | DT_VCENTER | DT_CENTER,
  1043.                        CtlLay[i].ldscx,bothy,CtlLay[i].dscw,checkh,
  1044.                        Controls[no].hwndRect,HWND_TOP,0,&sldcData,NULL);
  1045.                OldStaticWndProc=WinSubclassWindow(Controls[no].hwndLdesc,StaticWndProc);
  1046.                }
  1047.             if (CtlLay[i].flags&CLF_RDCT) {
  1048.                Controls[no].hwndRdesc=WinCreateWindow(Controls[no].hwndRect,WC_STATIC,szCt,
  1049.                        WS_VISIBLE | SS_TEXT | DT_VCENTER | DT_CENTER,
  1050.                        CtlLay[i].rdscx,bothy,CtlLay[i].dscw,checkh,
  1051.                        Controls[no].hwndRect,HWND_TOP,0,&sldcData,NULL);
  1052.                OldStaticWndProc=WinSubclassWindow(Controls[no].hwndRdesc,StaticWndProc);
  1053.                }
  1054.             else if (CtlLay[i].flags&CLF_RDHF) {
  1055.                Controls[no].hwndRdesc=WinCreateWindow(Controls[no].hwndRect,WC_STATIC,szHF,
  1056.                        WS_VISIBLE | SS_TEXT | DT_VCENTER | DT_CENTER,
  1057.                        CtlLay[i].rdscx,bothy,CtlLay[i].dscw,checkh,
  1058.                        Controls[no].hwndRect,HWND_TOP,0,&sldcData,NULL);
  1059.                OldStaticWndProc=WinSubclassWindow(Controls[no].hwndRdesc,StaticWndProc);
  1060.                }
  1061.             }
  1062.  
  1063.  
  1064.          sldcData.cbSize=sizeof(SLDCDATA);
  1065.          if (ShortSliders) sldcData.usScale1Increments=51;
  1066.          else sldcData.usScale1Increments=101;
  1067.          sldcData.usScale1Spacing=0;
  1068.          t=WS_VISIBLE | SLS_VERTICAL | SLS_SNAPTOINCREMENT |
  1069.                        SLS_PRIMARYSCALE1 | WS_TABSTOP;
  1070.          if (NarrowSliders) t|= SLS_OWNERDRAW;
  1071.          if (CtlLay[i].flags&CLF_LEFT) {
  1072.             if (Controls[no].SlLColor!=-1) {
  1073.                Light=RGBMix(Controls[no].SlLColor,RGB_WHITE);
  1074.                Dark=RGBMix(Controls[no].SlLColor,RGB_BLACK);
  1075.                ppres=malloc(sizeof(ULONG)*10);
  1076.                ppres->cb=sizeof(ULONG)*9;
  1077.                ppres->aparam[0].id=PP_BUTTONBACKGROUNDCOLOR;
  1078.                ppres->aparam[0].cb=sizeof(LONG);
  1079.                memcpy(&ppres->aparam[0].ab,&Controls[no].SlLColor,sizeof(LONG));
  1080.                ppres->aparam[1].id=PP_BORDERLIGHTCOLOR;
  1081.                ppres->aparam[1].cb=sizeof(LONG);
  1082.                memcpy(&ppres->aparam[1].ab,&Light,sizeof(LONG));
  1083.                ppres->aparam[2].id=PP_BORDERDARKCOLOR;
  1084.                ppres->aparam[2].cb=sizeof(LONG);
  1085.                memcpy(&ppres->aparam[2].ab,&Dark,sizeof(LONG));
  1086.                }
  1087.             else ppres=NULL;
  1088.             Controls[no].hwndLeft=WinCreateWindow(Controls[no].hwndRect,WC_SLIDER,NULL,t,
  1089.                        CtlLay[i].leftx,slidery,sliderw,sliderh,
  1090.                        Controls[no].hwndRect,HWND_TOP,IDC_LEFT|no,&sldcData,ppres);
  1091.             OldSliderWndProc=WinSubclassWindow(Controls[no].hwndLeft,SliderWndProc);
  1092.             if (ppres) free(ppres);
  1093.             }
  1094.          if (CtlLay[i].flags&CLF_RIGHT) {
  1095.             if (Controls[no].SlRColor!=-1) {
  1096.                Light=RGBMix(Controls[no].SlRColor,RGB_WHITE);
  1097.                Dark=RGBMix(Controls[no].SlRColor,RGB_BLACK);
  1098.                ppres=malloc(sizeof(ULONG)*10);
  1099.                ppres->cb=sizeof(ULONG)*9;
  1100.                ppres->aparam[0].id=PP_BUTTONBACKGROUNDCOLOR;
  1101.                ppres->aparam[0].cb=sizeof(LONG);
  1102.                memcpy(&ppres->aparam[0].ab,&Controls[no].SlRColor,sizeof(LONG));
  1103.                ppres->aparam[1].id=PP_BORDERLIGHTCOLOR;
  1104.                ppres->aparam[1].cb=sizeof(LONG);
  1105.                memcpy(&ppres->aparam[1].ab,&Light,sizeof(LONG));
  1106.                ppres->aparam[2].id=PP_BORDERDARKCOLOR;
  1107.                ppres->aparam[2].cb=sizeof(LONG);
  1108.                memcpy(&ppres->aparam[2].ab,&Dark,sizeof(LONG));
  1109.                }
  1110.             else ppres=NULL;
  1111.             Controls[no].hwndRight=WinCreateWindow(Controls[no].hwndRect,WC_SLIDER,NULL,t,
  1112.                        CtlLay[i].rightx,slidery,sliderw,sliderh,
  1113.                        Controls[no].hwndRect,HWND_TOP,IDC_RIGHT|no,&sldcData,ppres);
  1114.             OldSliderWndProc=WinSubclassWindow(Controls[no].hwndRight,SliderWndProc);
  1115.             if (ppres) free(ppres);
  1116.             }
  1117.          }
  1118.       x+=CtlLay[i].boxw+cellspx;
  1119.       if ((i+1)<actc) {
  1120.          if (CtlLay[i].celly!=CtlLay[i+1].celly) {
  1121.             x=fieldx;
  1122.             y-=boxh+cellspy;
  1123.             }
  1124.          }
  1125.       }
  1126.    Changing=FALSE;
  1127.    free(CtlLay);
  1128.    DisplayControls();
  1129.    return;
  1130.    }
  1131.  
  1132.  
  1133. // Open device, query available controls and set up Controls structure
  1134. // return TRUE if Ok.
  1135. int ApiInit() {
  1136.    unsigned char ApiMap[256];
  1137.    int i;
  1138.    MIXSTRUCT MixStruct;
  1139.    MIXMSGBUF MixMsgBuf;
  1140.    ULONG Level;
  1141.    char Buff[PIPE_BUF_MAX+1];
  1142.    char *tp;
  1143.  
  1144.    if (!UsingPipe) {
  1145.       if (mixerapiInit(MyCallBack)) UsingPipe=TRUE;    // Try pipe API
  1146.       else {
  1147.          if (!mixerapiIOCTL90(GETAPIMAP,ApiMap,256)) {
  1148.             for (i=0;i<NControls;i++)
  1149.                if ((Controls[i].setfunc>=0x20)&&(!(ApiMap[Controls[i].setfunc]&&ApiMap[Controls[i].qfunc]))) {
  1150.                   Controls[i].supported=0;
  1151.                   Controls[i].active=0;
  1152.                   }
  1153.             }
  1154.          if (!mixerapiIOCTL90(APILEVELQUERY,&Level,sizeof(ULONG))) ApiLevel=Level;
  1155.          }
  1156.       }
  1157.  
  1158.    if (UsingPipe) {
  1159.       strcpy(Buff,"80");        // Api Level
  1160.       if (PipeCommand(Buff,PIPE_BUF_MAX)) return 0;
  1161.       ApiLevel=atoi(Buff+3);
  1162.       }
  1163.  
  1164. // Check if query functions work
  1165.    for (i=0;i<NControls;i++) if (Controls[i].supported) {
  1166.        if (CallQuery(Controls[i].qfunc,&MixStruct)) {
  1167.             Controls[i].supported=0;
  1168.             Controls[i].active=0;
  1169.             }
  1170.        else {
  1171.             if (Controls[i].type==TYPE_SELECTOR) {
  1172.                if (MixStruct.Mute&4) Controls[i].flags|=FLAG_MULTIPLE;
  1173.                }
  1174.             else if (Controls[i].type==TYPE_TONE) {
  1175.                if (!(MixStruct.Mute&1)) Controls[i].flags|=FLAG_ONLYRIGHT;
  1176.                if (!(MixStruct.Mute&2)) Controls[i].flags|=FLAG_ONLYLEFT;
  1177.                }
  1178.             else if (Controls[i].type==TYPE_3D) {
  1179.                if (!(MixStruct.Mute&2)) Controls[i].flags|=FLAG_ONLYRIGHT;
  1180.                if (!(MixStruct.Mute&4)) Controls[i].flags|=FLAG_ONLYLEFT;
  1181.                }
  1182.             }
  1183.        }
  1184.    for (i=0;i<NControls;i++) if (Controls[i].supported) break; 
  1185.    if (i==NControls) return 0;    // No controls are available 
  1186. /* If API Level >1 then default for lockables is "active" */
  1187.    if (ApiLevel>1) for (i=0;i<<NControls;i++) {
  1188.       if ((Controls[i].supported)&&(Controls[i].flags&FLAG_LOCKABLE))
  1189.          Controls[i].active=TRUE;
  1190.       }
  1191.  
  1192.    if (!UsingPipe) {
  1193.       if (ApiMap[MSGBUF]) {
  1194.          MixMsgBuf.pBuffer=0;
  1195.          MixMsgBuf.ulSize=0;
  1196.          MixMsgBuf.fClear=FALSE;
  1197.          if (!mixerapiIOCTL90(MSGBUF,&MixMsgBuf,sizeof(MIXMSGBUF))) {
  1198.             InfoBufSize=MixMsgBuf.ulSize;
  1199.             InfoBuf=malloc(InfoBufSize);
  1200.             MixMsgBuf.pBuffer=(ULONG)InfoBuf;
  1201.             MixMsgBuf.ulSize=InfoBufSize;
  1202.             MixMsgBuf.fClear=FALSE;
  1203.             if (mixerapiIOCTL90(MSGBUF,&MixMsgBuf,sizeof(MIXMSGBUF))) {
  1204.                free(InfoBuf);
  1205.                InfoBuf=NULL;
  1206.                }
  1207.             else InfoBuf[MixMsgBuf.ulSize]=0;
  1208.             }
  1209.          }
  1210.       }
  1211.    else { 
  1212.       strcpy(Buff,"83");
  1213.       if (!PipeCommand(Buff,PIPE_BUF_MAX)) {
  1214.          tp=strchr(Buff,' ');
  1215.          if (tp) {
  1216.             if (*tp) tp++;
  1217.             if (*tp) {
  1218.                InfoBufSize=strlen(tp)+1;
  1219.                InfoBuf=malloc(InfoBufSize);
  1220.                strcpy(InfoBuf,tp);
  1221.                }
  1222.             }
  1223.          }
  1224.       }
  1225.  
  1226.    if (!InfoBuf) {
  1227.       InfoBufSize=DEF_INFO_BUF_SIZE;
  1228.       InfoBuf=malloc(InfoBufSize);
  1229.       InfoBuf[0]=0;
  1230.       }
  1231.    if (!InfoBuf[0]) {
  1232.       strcpy(InfoBuf,"Driver does not return info.");
  1233.       strcat(InfoBuf,"\nAPI Level: ");
  1234.       _itoa(ApiLevel,InfoBuf+strlen(InfoBuf),10);
  1235.       strcat(InfoBuf,"\nMixer state change callback is ");
  1236.       if (!ApiMap[CALLBACKREG]) strcat(InfoBuf,"not ");
  1237.       strcat(InfoBuf,"supported.");
  1238.       strcat(InfoBuf,"\nSupported controls:");
  1239.       for (i=0;i<NControls;i++) 
  1240.          if ((Controls[i].supported)&&(Controls[i].setfunc>=0x20)) {
  1241.             strcat(InfoBuf,"\n");
  1242.             strcat(InfoBuf,Controls[i].name);
  1243.             }
  1244.       strcat(InfoBuf,"\n");
  1245.       }
  1246.  
  1247.    return 1;
  1248.    }
  1249.  
  1250. void ApiClose() {
  1251.    if (!UsingPipe) mixerapiDeInit();
  1252.    }
  1253.  
  1254. // Set controls names to defaults
  1255. void NameInit() {
  1256.    int i;
  1257.  
  1258.    for (i=0;i<NControls;i++)
  1259.       WinLoadString(hab, 0, Controls[i].defnameID, 31, Controls[i].name);
  1260.    }
  1261.  
  1262. void LoadProfile() {
  1263.    unsigned char tname[32];
  1264.    char Buff[32];
  1265.    int i;
  1266.    unsigned char *SuffPos;
  1267.  
  1268.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyRestore,NULL,Buff,32))
  1269.       RestoreState=atoi(Buff);
  1270.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyAutoMini,NULL,Buff,32))
  1271.       AutoMini=atoi(Buff);
  1272.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1273.               (char *)szKeyInstName,NULL,szInstName,MAX_INST_NAME);
  1274.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyCellsInLine,NULL,Buff,32))
  1275.       CellsInLine=atoi(Buff);
  1276.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyShowMenu,NULL,Buff,32))
  1277.       ShowMenu=atoi(Buff);
  1278.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyShowTitlebar,NULL,Buff,32))
  1279.       ShowTitlebar=atoi(Buff);
  1280.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1281.               (char *)szKeyIconFile,NULL,szIconFile,CCHMAXPATH);
  1282.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1283.               (char *)szKeyLockName,NULL,szLock,32);
  1284.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1285.               (char *)szKeyOffName,NULL,szOff,32);
  1286.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1287.               (char *)szKeyMuteName,NULL,szMute,32);
  1288.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1289.               (char *)szKeyBothName,NULL,szBoth,32);
  1290.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1291.               (char *)szKeyLFName,NULL,szLF,32);
  1292.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1293.               (char *)szKeyHFName,NULL,szHF,32);
  1294.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1295.               (char *)szKeySpName,NULL,szSp,32);
  1296.    PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1297.               (char *)szKeyCtName,NULL,szCt,32);
  1298.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1299.                              (char *)szKeyNarrowSliders,NULL,Buff,32))
  1300.       NarrowSliders=atoi(Buff);
  1301.    if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1302.                              (char *)szKeyShortSliders,NULL,Buff,32))
  1303.       ShortSliders=atoi(Buff);
  1304.  
  1305.    for (i=0;i<NControls;i++) {
  1306.       strcpy(tname,szCtlPref);
  1307.       _itoa(Controls[i].setfunc,tname+strlen(tname),16);
  1308.       SuffPos=tname+strlen(tname);
  1309.  
  1310.       strcpy(SuffPos,szLeftSuf);
  1311.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1312.          Controls[i].left=atoi(Buff);
  1313.       strcpy(SuffPos,szRightSuf);
  1314.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1315.          Controls[i].right=atoi(Buff);
  1316.       strcpy(SuffPos,szMuteSuf);
  1317.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1318.          Controls[i].mute=atoi(Buff);
  1319.       strcpy(SuffPos,szBothSuf);
  1320.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1321.          Controls[i].both=atoi(Buff);
  1322.       if (ApiLevel>1) {
  1323.          strcpy(SuffPos,szLockSuf);
  1324.          if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1325.             Controls[i].lock=atoi(Buff);
  1326.          }
  1327.       strcpy(SuffPos,szActiveSuf);
  1328.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1329.          Controls[i].active=atoi(Buff);
  1330.       strcpy(SuffPos,szNameSuf);
  1331.       PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Controls[i].name,32);
  1332.       strcpy(SuffPos,szBackGndSuf);
  1333.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1334.          Controls[i].BgColor=atoi(Buff);
  1335.       strcpy(SuffPos,szForeGndSuf);
  1336.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1337.          Controls[i].FgColor=atoi(Buff);
  1338.       strcpy(SuffPos,szSlLClrSuf);
  1339.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1340.          Controls[i].SlLColor=atoi(Buff);
  1341.       strcpy(SuffPos,szSlRClrSuf);
  1342.       if (PrfQueryProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL,Buff,32))
  1343.          Controls[i].SlRColor=atoi(Buff);
  1344.       }
  1345.    return;
  1346.    }
  1347.  
  1348. void SaveProfile() {
  1349.    unsigned char tname[32];
  1350.    char Buff[32];
  1351.    int i;
  1352.    unsigned char *SuffPos;
  1353.  
  1354.    _itoa(RestoreState,Buff,10);
  1355.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyRestore,Buff);
  1356.    _itoa(AutoMini,Buff,10);
  1357.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyAutoMini,Buff);
  1358.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,
  1359.                          (char *)szKeyInstName,szInstName);
  1360.    _itoa(CellsInLine,Buff,10);
  1361.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyCellsInLine,Buff);
  1362.    _itoa(ShowMenu,Buff,10);
  1363.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyShowMenu,Buff);
  1364.    _itoa(ShowTitlebar,Buff,10);
  1365.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyShowTitlebar,Buff);
  1366.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyIconFile,szIconFile);
  1367.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyLockName,szLock);
  1368.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyOffName,szOff);
  1369.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyMuteName,szMute);
  1370.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyBothName,szBoth);
  1371.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyHFName,szHF);
  1372.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyLFName,szLF);
  1373.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeySpName,szSp);
  1374.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyCtName,szCt);
  1375.    _itoa(NarrowSliders,Buff,10);
  1376.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyNarrowSliders,Buff);
  1377.    _itoa(ShortSliders,Buff,10);
  1378.    PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,(char *)szKeyShortSliders,Buff);
  1379.  
  1380.    for (i=0;i<NControls;i++) if (Controls[i].supported) {
  1381.       strcpy(tname,szCtlPref);
  1382.       _itoa(Controls[i].setfunc,tname+strlen(tname),16);
  1383.       SuffPos=tname+strlen(tname);
  1384.  
  1385.       if (!(Controls[i].flags&FLAG_ONLYRIGHT)) {
  1386.          strcpy(SuffPos,szLeftSuf);
  1387.          _itoa(Controls[i].left,Buff,10);
  1388.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1389.          }
  1390.       if (!(Controls[i].flags&FLAG_ONLYLEFT)) {
  1391.          strcpy(SuffPos,szRightSuf);
  1392.          _itoa(Controls[i].right,Buff,10);
  1393.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1394.          }
  1395.       if (Controls[i].flags&FLAG_MUTABLE) {
  1396.          strcpy(SuffPos,szMuteSuf);
  1397.          _itoa(Controls[i].mute,Buff,10);
  1398.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1399.          }
  1400.       if (Controls[i].flags&FLAG_STEREO) {
  1401.          strcpy(SuffPos,szBothSuf);
  1402.          _itoa(Controls[i].both,Buff,10);
  1403.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1404.          }
  1405.       if (Controls[i].flags&FLAG_LOCKABLE) {
  1406.          strcpy(SuffPos,szLockSuf);
  1407.          _itoa(Controls[i].lock,Buff,10);
  1408.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1409.          }
  1410.       strcpy(SuffPos,szActiveSuf);
  1411.       _itoa(Controls[i].active,Buff,10);
  1412.       PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1413.       strcpy(SuffPos,szNameSuf);
  1414.       PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Controls[i].name);
  1415.       strcpy(SuffPos,szBackGndSuf);
  1416.       if (Controls[i].BgColor!=-1) {
  1417.          _ltoa(Controls[i].BgColor,Buff,10);
  1418.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1419.          }
  1420.       else 
  1421.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL);
  1422.       strcpy(SuffPos,szForeGndSuf);
  1423.       if (Controls[i].FgColor!=-1) {
  1424.          _ltoa(Controls[i].FgColor,Buff,10);
  1425.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1426.          }
  1427.       else 
  1428.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL);
  1429.       strcpy(SuffPos,szSlLClrSuf);
  1430.       if (Controls[i].SlLColor!=-1) {
  1431.          _ltoa(Controls[i].SlLColor,Buff,10);
  1432.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1433.          }
  1434.       else 
  1435.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL);
  1436.       strcpy(SuffPos,szSlRClrSuf);
  1437.       if (Controls[i].SlRColor!=-1) {
  1438.          _ltoa(Controls[i].SlRColor,Buff,10);
  1439.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,Buff);
  1440.          }
  1441.       else 
  1442.          PrfWriteProfileString(HINI_USERPROFILE,(char *)szIniApp,tname,NULL);
  1443.       }
  1444.    return;
  1445.    }
  1446.  
  1447. int ParseParms(int argc, char *argv[]) {
  1448.    int i;
  1449.    int PDDMaster;
  1450.    char *tp;
  1451.    struct t_Batch *BLast=NULL;
  1452.  
  1453.    PDDMaster=FALSE;
  1454.    for (i=1;i<argc;i++) {
  1455.      if (!stricmp(argv[i],"-i"))  {
  1456.         i++;
  1457.         if (i==argc) return FALSE;        // Syntax error
  1458.         strncpy(szIniApp,argv[i],MAX_APP_NAME_LEN-1);
  1459.         }
  1460.      else if (!stricmp(argv[i],"-d"))  {
  1461.         i++;
  1462.         if (i==argc) return FALSE;        // Syntax error
  1463.         strcpy(szPddName,"\\DEV\\");
  1464.         strncpy(szPddName+5,argv[i],8);
  1465.         strupr(szPddName);
  1466.         }
  1467.      else if (!stricmp(argv[i],"-p"))
  1468.         UsingPipe=TRUE;
  1469.      else if (!stricmp(argv[i],"-pn"))  {
  1470.         i++;
  1471.         if (i==argc) return FALSE;        // Syntax error
  1472.         strncpy(szPipeName,argv[i],CCHMAXPATH-1);
  1473.         }
  1474.      else if (!stricmp(argv[i],"-mv")) PDDMaster=TRUE;
  1475.      else if (!stricmp(argv[i],"-x")) AutoExit=TRUE;
  1476.      else if (!stricmp(argv[i],"-ps")) PipeSupport=TRUE;
  1477.      else if (!stricmp(argv[i],"-nsw"))  {
  1478.         i++;
  1479.         if (i==argc) return FALSE;        // Syntax error
  1480.         NSWidth=atoi(argv[i]);
  1481.         }
  1482.      else {                    // Batch command
  1483.         strupr(argv[i]);
  1484.         tp=strchr(argv[i],':');
  1485.         if (!tp) return FALSE;            // Syntax error
  1486.         if ((tp==argv[i])||(!tp[1])) return FALSE;    // Syntax error
  1487.         if (!BLast) {
  1488.            Batch=malloc(sizeof(struct t_Batch));
  1489.            BLast=Batch;
  1490.            }
  1491.         else {
  1492.            BLast->next=malloc(sizeof(struct t_Batch));
  1493.            BLast=BLast->next;
  1494.            }
  1495.         BLast->next=NULL;
  1496.         *tp=0;
  1497.         strncpy(BLast->name,argv[i],31);
  1498.         BLast->name[31]=0;
  1499.         tp++;
  1500.         BLast->leftop=1;
  1501.         BLast->leftval=0;
  1502.         BLast->rightop=1;
  1503.         BLast->rightval=0;
  1504.         BLast->mute=0;
  1505.         BLast->lock=0;
  1506.         if (*tp) {
  1507.            if (*tp!=':') {
  1508.               if (*tp=='+') {
  1509.                  BLast->leftop=1;
  1510.                  tp++;
  1511.                  }
  1512.               else if (*tp=='-') {
  1513.                  BLast->leftop=-1;
  1514.                  tp++;
  1515.                  }
  1516.               else BLast->leftop=0;
  1517.               BLast->leftval=atoi(tp);
  1518.               tp=strchr(tp,':');
  1519.               }
  1520.            if (tp) {
  1521.               tp++;
  1522.               if (*tp) {
  1523.                  if (*tp!=':') {
  1524.                     if (*tp=='+') {
  1525.                        BLast->rightop=1;
  1526.                        tp++;
  1527.                        }
  1528.                     else if (*tp=='-') {
  1529.                        BLast->rightop=-1;
  1530.                        tp++;
  1531.                        }
  1532.                     else BLast->rightop=0;
  1533.                     BLast->rightval=atoi(tp);
  1534.                     }
  1535.                  while (tp) {
  1536.                     tp=strchr(tp,':');
  1537.                     if (tp) {
  1538.                        tp++;
  1539.                        if (!memcmp(tp,"+M",2)) BLast->mute=1;
  1540.                        else if (!memcmp(tp,"-M",2)) BLast->mute=-1;
  1541.                        else if (!memcmp(tp,"+L",2)) BLast->lock=1;
  1542.                        else if (!memcmp(tp,"-L",2)) BLast->lock=-1;
  1543.                        else return FALSE;         // Syntax error
  1544.                        }
  1545.                     }
  1546.                  }
  1547.               }
  1548.            }
  1549.         }
  1550.      }
  1551.  
  1552.    if (!PDDMaster) for (i=0;i<NControls;i++) if (Controls[i].qfunc<0x20) {
  1553.       Controls[i].qfunc=0;
  1554.       Controls[i].setfunc=0;
  1555.       Controls[i].flags&=~FLAG_STEREO;
  1556.       Controls[i].flags|=FLAG_ONLYLEFT;
  1557.       }
  1558.    return TRUE;
  1559.    }
  1560.  
  1561. // Process the batch commands
  1562. int DoBatch() {
  1563.    struct t_Batch *BLast,*BNext;
  1564.    int i;
  1565.    char tbuff[32];
  1566.  
  1567.    BLast=Batch;
  1568.    while (BLast) {
  1569. /*      fprintf(stderr,"Batch cmd: Name: %s, left: %d:%d, right: %d:%d, mute: %d, lock: %d\n",
  1570.               BLast->name,BLast->leftop,BLast->leftval,BLast->rightop,BLast->rightval,
  1571.               BLast->mute,BLast->lock); */
  1572.       for(i=0;i<NControls;i++) if (Controls[i].supported) {
  1573.          strcpy(tbuff,Controls[i].name);
  1574.          strupr(tbuff);
  1575.          if (!memcmp(BLast->name,tbuff,strlen(BLast->name))) break;
  1576.          }
  1577.       if (i==NControls) return FALSE;
  1578.       if (!(Controls[i].flags&FLAG_ONLYRIGHT)) {
  1579.          if (BLast->leftop==0) Controls[i].left=BLast->leftval;
  1580.          else if (BLast->leftop<0) Controls[i].left-=BLast->leftval;
  1581.          else Controls[i].left+=BLast->leftval;
  1582.          if (Controls[i].left<0) Controls[i].left=0;
  1583.          if (Controls[i].left>100) Controls[i].left=100;
  1584.          if (!(Controls[i].flags&FLAG_ONLYLEFT)&&(Controls[i].both))
  1585.             Controls[i].right=Controls[i].left;
  1586.          }
  1587.       if (!(Controls[i].flags&FLAG_ONLYLEFT)) {
  1588.          if (BLast->rightop==0) Controls[i].right=BLast->rightval;
  1589.          else if (BLast->rightop<0) Controls[i].right-=BLast->rightval;
  1590.          else Controls[i].right+=BLast->rightval;
  1591.          if (Controls[i].right<0) Controls[i].right=0;
  1592.          if (Controls[i].right>100) Controls[i].right=100;
  1593.          if (!(Controls[i].flags&FLAG_ONLYLEFT)&&(Controls[i].both))
  1594.             Controls[i].left=Controls[i].right;
  1595.          }
  1596.       if (Controls[i].flags&FLAG_MUTABLE) {
  1597.          if (BLast->mute<0) Controls[i].mute=FALSE;
  1598.          else if (BLast->mute>0) Controls[i].mute=TRUE;
  1599.          }
  1600.       if (Controls[i].flags&FLAG_LOCKABLE) {
  1601.          if (BLast->lock<0) Controls[i].lock=FALSE;
  1602.          else if (BLast->lock>0) Controls[i].lock=TRUE;
  1603.          }
  1604.       SetControl(i);
  1605.       BNext=BLast->next;
  1606.       free(BLast);
  1607.       BLast=BNext;
  1608.       }
  1609.    return TRUE;
  1610.    }
  1611.  
  1612.  
  1613. // Pipe server - process command
  1614. int ProcessCmd(char *Buff, int tokens, int cmd, int p1, int p2, int p3) {
  1615.    int i,right,mute;
  1616.  
  1617.    if ((cmd==0x01)||((cmd&0xF0)==0x40)) {        // Set command
  1618.       if (tokens<2) p1=100;    // VolumeL
  1619.       if (tokens<3) p2=p1;    // VolumeR
  1620.       if (tokens<4) p3=0;    // Mute
  1621.       for (i=0;i<NControls;i++) 
  1622.           if ((Controls[i].setfunc==cmd)&&(Controls[i].supported)) {
  1623.              Controls[i].left=p1;
  1624.              Controls[i].right=p2;
  1625.              Controls[i].mute=(p3&FLAG_MUTE);
  1626.              if (Controls[i].flags&FLAG_LOCKABLE)
  1627.                 Controls[i].lock=!(p3&FLAG_RELEASE);
  1628.              SetControl(i);
  1629.              WinPostMsg( hwndMain, WM_USER, (MPARAM)USER_QUERY,(MPARAM)0 );
  1630.              strcat(Buff,REP_OK);
  1631.              return TRUE;
  1632.              }
  1633.       }
  1634.    else if ((cmd==0x11)||((cmd&0xF0)==0x60)) {        // Query command
  1635.       for (i=0;i<NControls;i++) 
  1636.           if ((Controls[i].qfunc==cmd)&&(Controls[i].supported)) {
  1637.  
  1638.              if (Controls[i].flags&FLAG_ONLYLEFT) right=0;
  1639.              else right=Controls[i].right;
  1640.              if ((Controls[i].mute)&&(Controls[i].flags&FLAG_MUTABLE))
  1641.                 mute=FLAG_MUTE;
  1642.              else mute=0;
  1643.              if ((Controls[i].flags&FLAG_LOCKABLE)&&(!Controls[i].lock))
  1644.                 mute|=FLAG_RELEASE;
  1645.              if (Controls[i].type==TYPE_3D) {
  1646.                 if (!(Controls[i].flags&FLAG_ONLYRIGHT)) mute|=2;
  1647.                 if (!(Controls[i].flags&FLAG_ONLYLEFT)) mute|=4;
  1648.                 }
  1649.              else if (Controls[i].type==TYPE_TONE) {
  1650.                 if (!(Controls[i].flags&FLAG_ONLYRIGHT)) mute|=1;
  1651.                 if (!(Controls[i].flags&FLAG_ONLYLEFT)) mute|=2;
  1652.                 }
  1653.              else if (Controls[i].type==TYPE_SELECTOR) {
  1654.                 if (!(Controls[i].flags&FLAG_MULTIPLE)) mute|=4;
  1655.                 }
  1656.              sprintf(Buff+strlen(Buff),"%d %d %x",
  1657.                      Controls[i].left,Controls[i].right,mute);
  1658.              return TRUE;
  1659.              }
  1660.       }
  1661.    strcat(Buff,REP_UNSUPPORTED);
  1662.    return TRUE;
  1663.    }
  1664.  
  1665. VOID APIENTRY PipeServer(ULONG Dummy) {
  1666.    char Buff[PIPE_BUF_MAX+1];
  1667.    ULONG cbActual;
  1668.    int cmd,p1,p2,p3,tokens;
  1669.    char *tp;
  1670.  
  1671.  
  1672.    while(1) {
  1673.       DosConnectNPipe(hPipe);
  1674.       DosRead(hPipe,Buff,PIPE_BUF_MAX,&cbActual);
  1675.       Buff[cbActual]=0;
  1676.       tp=Buff;
  1677.       while ((*tp>=0x20)||(*tp==9)) {
  1678.          if (*tp==9) *tp=0x20;
  1679.          tp++;
  1680.          }
  1681.       *tp=0;
  1682.       tokens=0;
  1683.       tp=Buff;
  1684.       while (*tp==0x20) tp++;
  1685.       if (*tp) {
  1686.          tokens++;
  1687.          cmd=strtol(tp,&tp,16);
  1688.          if (tp) while (*tp==0x20) tp++;
  1689.          if (!*tp) tp=NULL;
  1690.          if (tp) {
  1691.             tokens++;
  1692.             p1=strtol(tp,&tp,10);
  1693.             if (tp) while (*tp==0x20) tp++;
  1694.             if (!*tp) tp=NULL;
  1695.             if (tp) {
  1696.                tokens++;
  1697.                p2=strtol(tp,&tp,10);
  1698.                if (tp) while (*tp==0x20) tp++;
  1699.                if (!*tp) tp=NULL;
  1700.                if (tp) {
  1701.                   tokens++;
  1702.                   p3=strtol(tp,NULL,16);
  1703.                   }
  1704.                }
  1705.             }
  1706.          }
  1707.       if (tokens) {
  1708.          if (cmd>0xF) _itoa(cmd,Buff,16);
  1709.          else {
  1710.             Buff[0]='0';
  1711.             _itoa(cmd,Buff+1,16);
  1712.             }
  1713.          strcat(Buff," ");
  1714.          if (cmd==0x80) _itoa(ApiLevel,Buff+strlen(Buff),10);    // API level
  1715.          else if (cmd==0x83) {                    // Message buffer
  1716.             if (InfoBuf) strncat(Buff,InfoBuf,PIPE_BUF_MAX);
  1717.             }
  1718.          else ProcessCmd(Buff,tokens,cmd,p1,p2,p3);
  1719.          DosWrite(hPipe,Buff,strlen(Buff),&cbActual);
  1720.          }
  1721.       DosResetBuffer(hPipe);
  1722.       DosDisConnectNPipe(hPipe);
  1723.       }   
  1724.    }
  1725.  
  1726. int PipeSupInit() {
  1727.    if ((UsingPipe)||(!PipeSupport)) return TRUE;
  1728.    if(DosCreateNPipe((char *)szPipeName,&hPipe,NP_ACCESS_DUPLEX,
  1729.                      NP_WAIT|NP_TYPE_BYTE|NP_READMODE_BYTE|1,PIPE_BUF_MAX,
  1730.                      PIPE_BUF_MAX,0)) return FALSE;
  1731.    DosCreateThread(&PipeTID,PipeServer,0,0,8192);   
  1732.    return TRUE;
  1733.    }
  1734.  
  1735.  
  1736. INT main(int argc, char *argv[])
  1737. {
  1738.    QMSG qmsg;                          /* message structure */
  1739.  
  1740.    hab = WinInitialize(0);
  1741.    if(!hab)  {
  1742.        DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
  1743.        return(RETURN_ERROR);
  1744.    }
  1745.    hmq = WinCreateMsgQueue(hab, 0);
  1746.    if(!hmq)  {
  1747.        DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
  1748.        WinTerminate(hab);
  1749.        return(RETURN_ERROR);
  1750.    }
  1751.    if(!Init()) {
  1752.        MessageBox(HWND_DESKTOP, IDMSG_INITFAILED, "Error !",
  1753.                MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
  1754.        DosExit(EXIT_PROCESS, RETURN_ERROR);
  1755.        }
  1756.    if(!ParseParms(argc,argv)) {
  1757.        MessageBox(HWND_DESKTOP, IDMSG_SYNTAXERROR, "Error !",
  1758.                MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
  1759.        DosExit(EXIT_PROCESS, RETURN_ERROR);
  1760.        }
  1761.    NameInit();
  1762.    if(!ApiInit()) {
  1763.        MessageBox(HWND_DESKTOP, IDMSG_APIINITFAILED, "Error !",
  1764.                MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
  1765.        DosExit(EXIT_PROCESS, RETURN_ERROR);
  1766.        }
  1767.    LoadProfile();
  1768.    if (RestoreState) SetControls();
  1769.    else QueryControls();
  1770.    if (!DoBatch()) {
  1771.       MessageBox(HWND_DESKTOP, IDMSG_BADCTLNAME, "Error !",
  1772.                MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
  1773.       DosExit(EXIT_PROCESS, RETURN_ERROR);
  1774.       }
  1775.   if (!PipeSupInit()) {
  1776.       MessageBox(HWND_DESKTOP, IDMSG_PIPECREAT, "Error !",
  1777.                MB_OK | MB_ERROR | MB_MOVEABLE, TRUE);
  1778.       DosExit(EXIT_PROCESS, RETURN_ERROR);
  1779.       }
  1780.    MainCreate();
  1781.    if (!AutoExit) {
  1782.       while(WinGetMsg(hmq, (PQMSG)&qmsg, 0L, 0L, 0L))
  1783.              WinDispatchMsg(hmq, (PQMSG)&qmsg);
  1784.       SaveProfile();
  1785.       }
  1786.    ApiClose();
  1787.    if (InfoBuf) free(InfoBuf);
  1788.    DosExit(EXIT_PROCESS, RETURN_SUCCESS);
  1789.    return 0;
  1790. }                                   /* main() */
  1791.  
  1792. BOOL Init(VOID) {
  1793.    int w;
  1794.  
  1795.    if(DosExitList(EXLST_ADD, ExitProc)) return FALSE;
  1796.  
  1797.    if(!WinRegisterClass(hab,(PSZ)"MAIN",(PFNWP)MainWndProc,CS_SIZEREDRAW,0))
  1798.       return FALSE;
  1799.    if(!WinRegisterClass(hab,(PSZ)"CONTROL",(PFNWP)ControlWndProc,0,0))
  1800.       return FALSE;
  1801.  
  1802.    WinLoadString(hab, 0, IDS_LOCK, 32, szLock);
  1803.    WinLoadString(hab, 0, IDS_OFF, 32, szOff);
  1804.    WinLoadString(hab, 0, IDS_MUTE, 32, szMute);
  1805.    WinLoadString(hab, 0, IDS_BOTH, 32, szBoth);
  1806.    WinLoadString(hab, 0, IDS_SP, 32, szSp);
  1807.    WinLoadString(hab, 0, IDS_LF, 32, szLF);
  1808.    WinLoadString(hab, 0, IDS_CT, 32, szCt);
  1809.    WinLoadString(hab, 0, IDS_HF, 32, szHF);
  1810.  
  1811.    w=WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
  1812.    if (w<=640) NSWidth=SLIDER_W_N640;
  1813.    else if (w<=800) NSWidth=SLIDER_W_N800;
  1814.    else if (w<=1024) NSWidth=SLIDER_W_N1024;
  1815.    else if (w<=1152) NSWidth=SLIDER_W_N1152;
  1816.    else if (w<=1280) NSWidth=SLIDER_W_N1280;
  1817.    else NSWidth=SLIDER_W_N1600;
  1818.  
  1819.    return TRUE;
  1820. }                              /* Init() */
  1821.  
  1822. VOID APIENTRY ExitProc(ULONG usTermCode) {
  1823.    if (PipeTID) {
  1824.       DosKillThread(PipeTID);
  1825.       DosClose(hPipe);
  1826.       }
  1827.    if (hwndMainFrame) WinDestroyWindow(hwndMainFrame);
  1828.    if (hIcon) WinFreeFileIcon(hIcon);
  1829.    WinDestroyMsgQueue(hmq);
  1830.    WinTerminate(hab);
  1831.    DosExitList(EXLST_EXIT, (PFNEXITLIST)0L);    /* termination complete */
  1832.    return;
  1833.    }
  1834. LONG MessageBox(HWND hwndOwner, LONG IdMsg, PSZ pszMsg, LONG fsStyle,
  1835.              BOOL bBeep)
  1836. {
  1837.     CHAR szText[MESSAGELEN];
  1838.     LONG usRet;
  1839.  
  1840.     if(!WinLoadMessage(hab, (HMODULE)NULL, IdMsg, MESSAGELEN, (PSZ)szText)) {
  1841.     WinAlarm(HWND_DESKTOP, WA_ERROR);
  1842.     return RETURN_ERROR;
  1843.         }
  1844.     if(bBeep) WinAlarm(HWND_DESKTOP, WA_ERROR);
  1845.  
  1846.     usRet = WinMessageBox(HWND_DESKTOP,
  1847.              hwndOwner,
  1848.              szText,
  1849.              (PSZ)pszMsg,
  1850.              IDM_MSGBOX,
  1851.              fsStyle);
  1852.     return usRet;
  1853. }                            /* MessageBox() */
  1854.  
  1855.  
  1856. void MainControl(HWND hwnd,MPARAM mp1) {
  1857.    int i,j,k,val;
  1858.  
  1859.    if ((!Changing)&&((SHORT2FROMMP(mp1)==BN_CLICKED)||
  1860.        (SHORT2FROMMP(mp1)==LN_SELECT)||(SHORT2FROMMP(mp1)==SLN_CHANGE)||
  1861.        (SHORT2FROMMP(mp1)==SLN_SLIDERTRACK))) {
  1862.       i=LOUSHORT(mp1)&0xFF;    // Control no
  1863.       switch (LOUSHORT(mp1)&0xFF00) {
  1864.          case IDC_LIST:
  1865.             Controls[i].left=0;
  1866.             val=LIT_FIRST;
  1867.             while(1) {
  1868.                val=(int)WinSendMsg(Controls[i].hwndLeft,
  1869.                         LM_QUERYSELECTION,(MPARAM)val,(MPARAM)NULL);
  1870.                if (val==LIT_NONE) break;
  1871.                for (k=0,j=0;k<NControls;k++) if ((Controls[k].sel!=NO_INPUT_SEL)&&(Controls[k].supported)) {
  1872.                   if (j==val) {
  1873.                      Controls[i].left|=Controls[k].sel;
  1874.                      break;
  1875.                      }
  1876.                   else j++;
  1877.                   }
  1878.                if (!(Controls[i].flags&FLAG_MULTIPLE)) break;
  1879.                };
  1880.             break;
  1881.          case IDC_LEFT: 
  1882.             Controls[i].left=(int)WinSendMsg(Controls[i].hwndLeft,
  1883.                  SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  1884.                  SMA_INCREMENTVALUE),(MPARAM)NULL);
  1885.             if (ShortSliders) Controls[i].left*=2;
  1886.             if ((Controls[i].flags&FLAG_STEREO)&&Controls[i].both)
  1887.                 Controls[i].right=Controls[i].left;
  1888.             break;
  1889.          case IDC_RIGHT: 
  1890.             Controls[i].right=(int)WinSendMsg(Controls[i].hwndRight,
  1891.                     SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  1892.                     SMA_INCREMENTVALUE),(MPARAM)NULL);
  1893.             if (ShortSliders) Controls[i].right*=2;
  1894.             if ((Controls[i].flags&FLAG_STEREO)&&Controls[i].both)
  1895.                 Controls[i].left=Controls[i].right;
  1896.             break;
  1897.          case IDC_MUTE:
  1898.             Controls[i].mute=(int)WinSendMsg(Controls[i].hwndMute,
  1899.                                                     BM_QUERYCHECK,0,0);
  1900.             break;
  1901.          case IDC_BOTH:
  1902.             Controls[i].both=(int)WinSendMsg(Controls[i].hwndBoth,
  1903.                                                     BM_QUERYCHECK,0,0);
  1904.             if ((Controls[i].both)&&(Controls[i].right!=Controls[i].left)) {
  1905.                 Controls[i].left=(Controls[i].left+Controls[i].right)/2;
  1906.                 Controls[i].right=Controls[i].left;
  1907.                 }
  1908.          case IDC_LOCK:
  1909.             Controls[i].lock=(int)WinSendMsg(Controls[i].hwndLock,
  1910.                                                     BM_QUERYCHECK,0,0);
  1911.             break;
  1912.          default:
  1913.             return;
  1914.          }
  1915.       SetControl(i);
  1916.       QueryControl(i);
  1917.       DisplayControl(i);
  1918.       }
  1919.    return;
  1920.    }
  1921.  
  1922. void Minimize() {
  1923.    SWP swpCurrent;
  1924.  
  1925.    WinQueryWindowPos(hwndMainFrame,&swpCurrent);
  1926.    if (!(swpCurrent.fl&SWP_MINIMIZE))
  1927.       WinSetWindowPos(hwndMainFrame,0,swpCurrent.x,swpCurrent.y,
  1928.                    swpCurrent.cx,swpCurrent.cy,
  1929.                    SWP_MINIMIZE|SWP_SIZE|SWP_MOVE);
  1930.    return;
  1931.    }
  1932.  
  1933. void MainCommand(HWND hwnd,MPARAM mp1) {
  1934.  
  1935.    switch(LOUSHORT(mp1)) {
  1936.       case IDC_SETTINGS:
  1937.          ChildDlg=TRUE;
  1938.          WinDlgBox(HWND_DESKTOP, hwndMain, (PFNWP)SettingsDlgProc,
  1939.                    (HMODULE) NULL, IDD_SETTINGS, NULL);
  1940.          ChildDlg=FALSE;
  1941.          MainCreate();
  1942.          break;
  1943.       case IDC_ABOUT:
  1944.          ChildDlg=TRUE;
  1945.          WinDlgBox(HWND_DESKTOP, hwndMain, (PFNWP)AboutDlgProc,
  1946.             (HMODULE) NULL, IDD_ABOUT, NULL);
  1947.          ChildDlg=FALSE;
  1948.          break;
  1949.       case IDC_INFO:
  1950.          ChildDlg=TRUE;
  1951.          WinDlgBox(HWND_DESKTOP, hwndMain, (PFNWP)InfoDlgProc,
  1952.             (HMODULE) NULL, IDD_INFO, NULL);
  1953.          ChildDlg=FALSE;
  1954.          break;
  1955.       case IDC_EXIT:
  1956.          WinPostMsg( hwndMain, WM_CLOSE, (MPARAM)0,(MPARAM)0 );
  1957.          break;
  1958.       case IDC_MOVE:
  1959.          WinSendMsg(hwndMainFrame, WM_TRACKFRAME, MPFROMSHORT( TF_MOVE | TF_SETPOINTERPOS ),
  1960.                      0);
  1961.          break;
  1962.       case IDC_MINIMIZE:
  1963.          Minimize();
  1964.          break;
  1965.       }
  1966.    return;
  1967.    }
  1968.  
  1969. MRESULT EXPENTRY MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1970. {
  1971.    SWP swpCurrent;
  1972.    HPS      hps;                /* Handle for painting         */
  1973.    RECTL  rect;                /* Rectangle struct for painting */
  1974.    LONG lColor;
  1975.    MRESULT rc;
  1976.    static HWND hwndMenu;
  1977.    POINTL point;
  1978.    char *FName;
  1979.  
  1980.      switch (msg) {
  1981.        case WM_CREATE:
  1982.           WinPostMsg( hwnd, WM_USER, (MPARAM)USER_INIT,(MPARAM)0 );
  1983.        break;
  1984.        case WM_USER:
  1985.           switch ((int)mp1) {
  1986.              case USER_INIT:
  1987.                 hwndMenu=WinLoadMenu(hwndMain,0,ID_POPUP);   
  1988.                 lColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_DIALOGBACKGROUND,0);
  1989.                 WinSetPresParam(hwndMain,PP_BACKGROUNDCOLOR,sizeof(lColor),&lColor);
  1990.                 if (!WinRestoreWindowPos((char *)szIniApp,(char *)szKeyWindowPos,
  1991.                                           hwndMainFrame)) {
  1992.                   WinQueryTaskSizePos(hab,0,&swpCurrent);
  1993.                   WinSetWindowPos(hwndMainFrame,0,swpCurrent.x,swpCurrent.y,
  1994.                                   swpCurrent.cx,swpCurrent.cy,SWP_SIZE|SWP_MOVE);
  1995.                    }
  1996.                 WinSetWindowPos(hwndMainFrame,0,0,0,0,0,SWP_SHOW | SWP_ACTIVATE);
  1997.                 MainWindow();
  1998.                 break;
  1999.              case USER_QUERY:
  2000.                 QueryControls();
  2001.                 DisplayControls();
  2002.                 break;
  2003.              case USER_CHILDFONTCHANGE:
  2004.                 FName=malloc(256);
  2005.                 if (WinQueryPresParam((HWND)mp2,PP_FONTNAMESIZE,0,NULL,256,
  2006.                                    FName,0))
  2007.                    WinSetPresParam(hwnd,PP_FONTNAMESIZE,strlen(FName)+1,FName);
  2008.                 else 
  2009.                    WinRemovePresParam(hwnd,PP_FONTNAMESIZE);
  2010.                 free(FName);
  2011.                 break;
  2012.              case USER_RECREATE:
  2013.                 MainCreate();
  2014.                 break;
  2015.              }
  2016.           break;
  2017.        case WM_CLOSE:
  2018.           QueryCtlColors();
  2019.           ChildDlg=TRUE;    // To prevent temporary minimization
  2020.           WinStoreWindowPos((char *)szIniApp,(char *)szKeyWindowPos,hwndMainFrame);
  2021.           WinPostMsg( hwndMain, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  2022.           break;
  2023.        case WM_PRESPARAMCHANGED:
  2024.           if ((ULONG)mp1==PP_FONTNAMESIZE) MainCreate();
  2025.           else {
  2026.              WinQueryWindowRect(hwndMain,&rect);
  2027.              WinInvalidateRect(hwndMain,&rect,TRUE);
  2028.              }
  2029.           break;
  2030.        case WM_PAINT:
  2031.           hps = WinBeginPaint(hwnd, 0L,NULL);
  2032.           GpiCreateLogColorTable(hps,0,LCOLF_RGB,0,0,NULL);
  2033.           if (!WinQueryPresParam(hwndMain,PP_BACKGROUNDCOLOR,
  2034.                                  PP_BACKGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2035.                                  &lColor,QPF_ID2COLORINDEX))
  2036.              lColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_WINDOW,0);
  2037.           WinQueryWindowRect(hwndMain,&rect);
  2038.           WinFillRect(hps, (PRECTL)&rect, lColor);
  2039.           WinEndPaint(hps);
  2040.           break;
  2041.        case WM_BUTTON2CLICK:
  2042.           WinQueryPointerPos(HWND_DESKTOP, &point);
  2043.           WinMapWindowPoints(HWND_DESKTOP,hwndMain,&point,1);
  2044.           WinPopupMenu(hwndMain,hwnd,hwndMenu,point.x, point.y,0,
  2045.                       PU_VCONSTRAIN | PU_HCONSTRAIN | PU_MOUSEBUTTON1);
  2046.           break;          
  2047.       case WM_BUTTON1MOTIONSTART:
  2048.       case WM_BUTTON2MOTIONSTART:
  2049.          WinSendMsg( hwndMainFrame, WM_TRACKFRAME, MPFROMSHORT( TF_MOVE | TF_SETPOINTERPOS ),
  2050.                      0);
  2051.          break;
  2052.       case WM_BUTTON1DBLCLK:
  2053.          Minimize();
  2054.          break;
  2055.        case WM_COMMAND:
  2056.        case WM_SYSCOMMAND:
  2057.           MainCommand(hwnd,mp1);
  2058.           break;
  2059.        case WM_CONTROL:
  2060.           MainControl(hwnd,mp1);
  2061.           break;
  2062.        case WM_SIZE:
  2063.       rc=WinDefWindowProc(hwnd, msg, mp1, mp2);
  2064.           HideTitle();
  2065.           return rc;
  2066.        case WM_ACTIVATE:
  2067.           if ((!SHORT1FROMMP(mp1))&&(AutoMini)&&(!ChildDlg)) Minimize();
  2068.           if (SHORT1FROMMP(mp1))
  2069.              WinPostMsg( hwndMain, WM_USER, (MPARAM)USER_QUERY,(MPARAM)0 );
  2070.        default:    
  2071.       return WinDefWindowProc(hwnd, msg, mp1, mp2);
  2072.        }
  2073.    return (MRESULT)0L;
  2074. }
  2075.  
  2076. int PPChange=FALSE;
  2077. MRESULT EXPENTRY ControlWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2078. {
  2079.    HPS      hps;                /* Handle for painting         */
  2080.    RECTL  rect;                /* Rectangle struct for painting */
  2081.    MRESULT rc;
  2082.    LONG lColor;
  2083.  
  2084.      switch (msg) {
  2085.        case WM_BUTTON2CLICK:
  2086.        case WM_BUTTON1MOTIONSTART:
  2087.        case WM_BUTTON2MOTIONSTART:
  2088.        case WM_CONTROL:
  2089.           return WinSendMsg(hwndMain,msg, mp1, mp2);
  2090.           break;
  2091.  
  2092.        case WM_USER:
  2093.           PPChange=TRUE;
  2094.           if ((int)mp1==USER_CHILDBGNDCHANGE) {
  2095.              if (WinQueryPresParam((HWND)mp2,PP_BACKGROUNDCOLOR,
  2096.                                  PP_BACKGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2097.                                  &lColor,QPF_ID2COLORINDEX))
  2098.                 WinSetPresParam(hwnd,PP_BACKGROUNDCOLOR,sizeof(lColor),&lColor);
  2099.              else {
  2100.                 WinRemovePresParam(hwnd,PP_BACKGROUNDCOLOR);
  2101.                 WinRemovePresParam(hwnd,PP_BACKGROUNDCOLORINDEX);
  2102.                 }
  2103.              }
  2104.           else if ((int)mp1==USER_CHILDFGNDCHANGE) {
  2105.              if (WinQueryPresParam((HWND)mp2,PP_FOREGROUNDCOLOR,
  2106.                                  PP_FOREGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2107.                                  &lColor,QPF_ID2COLORINDEX))
  2108.                 WinSetPresParam(hwnd,PP_FOREGROUNDCOLOR,sizeof(lColor),&lColor);
  2109.              else {
  2110.                 WinRemovePresParam(hwnd,PP_FOREGROUNDCOLOR);
  2111.                 WinRemovePresParam(hwnd,PP_FOREGROUNDCOLORINDEX);
  2112.                 }
  2113.              }
  2114.           PPChange=FALSE;
  2115.           break;
  2116.        case WM_PRESPARAMCHANGED:
  2117.           if ((ULONG)mp1==PP_FONTNAMESIZE)    // Must POST
  2118.              WinPostMsg(hwndMain,WM_USER,(MPARAM)USER_CHILDFONTCHANGE,(MPARAM)hwnd);
  2119.           else {
  2120.              WinQueryWindowRect(hwndMain,&rect);
  2121.              WinInvalidateRect(hwndMain,&rect,TRUE);
  2122.              }
  2123.           break;
  2124.        case WM_PAINT:
  2125.           hps = WinBeginPaint(hwnd, 0L,NULL);
  2126.           GpiCreateLogColorTable(hps,0,LCOLF_RGB,0,0,NULL);
  2127.           if (!WinQueryPresParam(hwnd,PP_BACKGROUNDCOLOR,
  2128.                                  PP_BACKGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2129.                                  &lColor,QPF_ID2COLORINDEX))
  2130.              lColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_WINDOW,0);
  2131.           WinQueryWindowRect(hwnd,&rect);
  2132.           WinFillRect(hps, (PRECTL)&rect, lColor);
  2133.           WinEndPaint(hps);
  2134.           break;
  2135.       case WM_DRAWITEM:
  2136.          if (((LOUSHORT(mp1)&0xFF00)==IDC_LEFT)||
  2137.             ((LOUSHORT(mp1)&0xFF00)==IDC_RIGHT)) {
  2138.             if (((POWNERITEM)mp2)->idItem ==SDA_BACKGROUND)
  2139.                return (MRESULT)TRUE;
  2140.             if (((POWNERITEM)mp2)->idItem==SDA_SLIDERARM) {
  2141.                RECTL  rect;
  2142.                POINTL pnt;
  2143.                HPS hps;
  2144.                HWND hwndSl;
  2145.  
  2146.                hwndSl=WinWindowFromID(hwnd,LOUSHORT(mp1));
  2147.                rect=((POWNERITEM)mp2)->rclItem;
  2148.                hps=((POWNERITEM)mp2)->hps;
  2149.  
  2150.                GpiCreateLogColorTable(hps,0,LCOLF_RGB,0,0,NULL);
  2151.                if (!WinQueryPresParam(hwndSl,PP_BUTTONBACKGROUNDCOLOR,
  2152.                                  0,NULL,sizeof(lColor),
  2153.                                  &lColor,0))
  2154.                   lColor=WinQuerySysColor(HWND_DESKTOP,SYSCLR_BUTTONMIDDLE,0);
  2155.                GpiSetColor(hps,lColor);
  2156.                pnt.x=rect.xLeft+6;
  2157.                pnt.y=rect.yTop-2;
  2158.                GpiMove(hps,&pnt);
  2159.                pnt.x=rect.xRight-7;
  2160.                pnt.y=rect.yBottom+2;
  2161.                GpiBox(hps,DRO_FILL,&pnt,1,1);
  2162.                if (!WinQueryPresParam(hwndSl,PP_BORDERLIGHTCOLOR,
  2163.                                  0,NULL,sizeof(lColor),
  2164.                                  &lColor,0))
  2165.                   lColor=RGB_WHITE;
  2166.                GpiSetColor(hps,lColor);
  2167.                pnt.x=rect.xLeft+6;
  2168.                pnt.y=rect.yTop;
  2169.                GpiMove(hps,&pnt);
  2170.                pnt.x=rect.xLeft;
  2171.                pnt.y=rect.yBottom;
  2172.                GpiBox(hps,DRO_FILL,&pnt,1,1);
  2173.                pnt.x=rect.xRight-5;
  2174.                pnt.y=rect.yTop-2;
  2175.                GpiBox(hps,DRO_FILL,&pnt,1,1);
  2176.                if (!WinQueryPresParam(hwndSl,PP_BORDERDARKCOLOR,
  2177.                                  0,NULL,sizeof(lColor),
  2178.                                  &lColor,0))
  2179.                   lColor=0x808080;
  2180.                GpiSetColor(hps,lColor);
  2181.                pnt.x=rect.xRight;
  2182.                pnt.y=rect.yBottom;
  2183.                GpiMove(hps,&pnt);
  2184.                pnt.x=rect.xRight-6;
  2185.                pnt.y=rect.yTop;
  2186.                GpiBox(hps,DRO_FILL,&pnt,1,1);
  2187.                pnt.x=rect.xLeft+6;
  2188.                pnt.y=rect.yBottom+2;
  2189.                GpiBox(hps,DRO_FILL,&pnt,1,1);
  2190.                return (MRESULT)TRUE;
  2191.                }
  2192.             }
  2193.          break;
  2194.        default:    
  2195.       return WinDefWindowProc(hwnd, msg, mp1, mp2);
  2196.        }
  2197.    return (MRESULT)0L;
  2198. }
  2199.  
  2200. void SubClassWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  2201.  
  2202.    if ((msg==WM_PRESPARAMCHANGED)&&(!PPChange)) {
  2203.       if ((ULONG)mp1==PP_FONTNAMESIZE)
  2204.              WinPostMsg(hwndMain,WM_USER,(MPARAM)USER_CHILDFONTCHANGE,(MPARAM)hwnd);
  2205.       else if ((ULONG)mp1==PP_BACKGROUNDCOLOR)
  2206.              WinPostMsg(WinQueryWindow(hwnd,QW_PARENT),WM_USER,
  2207.                         (MPARAM)USER_CHILDBGNDCHANGE,(MPARAM)hwnd);
  2208.       else if ((ULONG)mp1==PP_FOREGROUNDCOLOR)
  2209.              WinPostMsg(WinQueryWindow(hwnd,QW_PARENT),WM_USER,
  2210.                         (MPARAM)USER_CHILDFGNDCHANGE,(MPARAM)hwnd);
  2211.       }
  2212.    }
  2213. MRESULT EXPENTRY ButtonWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  2214.    SubClassWndProc(hwnd, msg, mp1, mp2);
  2215.    if ((msg==WM_BUTTON2CLICK)||(msg==WM_BUTTON2MOTIONSTART))
  2216.       return WinSendMsg(hwndMain,msg, mp1, mp2);
  2217.    return OldButtonWndProc(hwnd, msg, mp1, mp2);
  2218.    }
  2219. MRESULT EXPENTRY StaticWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  2220.    SubClassWndProc(hwnd, msg, mp1, mp2);
  2221.    return OldStaticWndProc(hwnd, msg, mp1, mp2);
  2222.    }
  2223. MRESULT EXPENTRY ListboxWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  2224.    LONG lColor,lColor1;
  2225.  
  2226.    if ((msg==WM_PRESPARAMCHANGED)&&((ULONG)mp1==PP_BACKGROUNDCOLOR)) {
  2227.       if (!WinQueryPresParam(hwnd,PP_BACKGROUNDCOLOR,
  2228.                                  PP_BACKGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2229.                                  &lColor,QPF_ID2COLORINDEX)) lColor=-1;
  2230.       if (lColor==-1) {
  2231.          WinRemovePresParam(hwnd,PP_BORDERLIGHTCOLOR);
  2232.          WinRemovePresParam(hwnd,PP_BORDERDARKCOLOR);
  2233.          }
  2234.       else {
  2235.          lColor1=RGBMix(lColor,RGB_WHITE);
  2236.          WinSetPresParam(hwnd,PP_BORDERLIGHTCOLOR,sizeof(lColor1),&lColor1);
  2237.          lColor1=RGBMix(lColor,RGB_BLACK);
  2238.          WinSetPresParam(hwnd,PP_BORDERDARKCOLOR,sizeof(lColor1),&lColor1);
  2239.          }
  2240.       }
  2241.    else if ((msg!=WM_PRESPARAMCHANGED)||((ULONG)mp1!=PP_FOREGROUNDCOLOR))
  2242.       SubClassWndProc(hwnd, msg, mp1, mp2);
  2243.    if ((msg==WM_BUTTON2CLICK)||(msg==WM_BUTTON2MOTIONSTART))
  2244.       return WinSendMsg(hwndMain,msg, mp1, mp2);
  2245.    return OldListboxWndProc(hwnd, msg, mp1, mp2);
  2246.    }
  2247. MRESULT EXPENTRY SliderWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  2248.    LONG lColor,lColor1;
  2249.    RECTL  rect;                /* Rectangle struct for painting */
  2250.  
  2251.    if ((msg==WM_PRESPARAMCHANGED)&&((ULONG)mp1==PP_FOREGROUNDCOLOR)) {
  2252.       if (WinQueryPresParam(hwnd,PP_FOREGROUNDCOLOR,
  2253.                                  PP_FOREGROUNDCOLORINDEX,NULL,sizeof(lColor),
  2254.                                  &lColor,QPF_ID2COLORINDEX|QPF_NOINHERIT)) {
  2255.          WinSetPresParam(hwnd,PP_BUTTONBACKGROUNDCOLOR,sizeof(lColor),&lColor);
  2256.          lColor1=RGBMix(lColor,RGB_WHITE);
  2257.          WinSetPresParam(hwnd,PP_BORDERLIGHTCOLOR,sizeof(lColor1),&lColor1);
  2258.          lColor1=RGBMix(lColor,RGB_BLACK);
  2259.          WinSetPresParam(hwnd,PP_BORDERDARKCOLOR,sizeof(lColor1),&lColor1);
  2260.          WinPostMsg(hwndMain,WM_USER,(MPARAM)USER_RECREATE,(MPARAM)0);
  2261.          }
  2262.       }
  2263.    else SubClassWndProc(hwnd, msg, mp1, mp2);
  2264.    return OldSliderWndProc(hwnd, msg, mp1, mp2);
  2265.    }
  2266.  
  2267. int MyCallBack() {
  2268.    WinPostMsg(hwndMain, WM_USER, (MPARAM)USER_QUERY,(MPARAM)0 );
  2269.    return;
  2270.    }
  2271.  
  2272. /************************************************************************\
  2273. |            Small dialogs                                               |
  2274. \************************************************************************/
  2275.  
  2276. MRESULT EXPENTRY AboutDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2277. {
  2278.    CHAR    szTitle[MESSAGELEN];
  2279.    MRESULT sRC;
  2280.  
  2281.      switch (msg) {
  2282.        case WM_INITDLG:
  2283.           WinLoadString(hab, 0, IDS_TITLE, MESSAGELEN, szTitle);
  2284.           WinSetWindowText(WinWindowFromID(hwnd,IDC_ABOUTAPP),szTitle);
  2285.        break;
  2286.        case WM_COMMAND:
  2287.           if (LOUSHORT(mp1)==IDC_OK) WinDismissDlg(hwnd, TRUE);
  2288.           break;
  2289.        default:    
  2290.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2291.       return sRC;
  2292.        }
  2293.    return (MRESULT)0L;
  2294. }
  2295.  
  2296. MRESULT EXPENTRY InfoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2297. {
  2298.    MRESULT sRC;
  2299.    IPT iptOffset;
  2300.    HWND hwndMLE;
  2301.  
  2302.      switch (msg) {
  2303.        case WM_INITDLG:
  2304.           {
  2305.           char tbuf[80];
  2306.           char tbuf1[10];
  2307.  
  2308.           hwndMLE=WinWindowFromID(hwnd,IDC_INFOMLE);
  2309.           WinSendMsg(hwndMLE, MLM_DISABLEREFRESH, NULL, NULL);
  2310.           WinSendMsg(hwndMLE, MLM_SETSEL, MPFROMSHORT(NULL),
  2311.                      (MPARAM) WinSendMsg(hwndMLE, MLM_QUERYTEXTLENGTH,NULL, NULL));
  2312.           WinSendMsg(hwndMLE, MLM_CLEAR, NULL, NULL);
  2313.           WinSendMsg(hwndMLE, MLM_SETIMPORTEXPORT,
  2314.                        MPFROMP((PBYTE)InfoBuf),(MPARAM)strlen(InfoBuf));
  2315.           iptOffset=0;
  2316.           WinSendMsg(hwndMLE, MLM_IMPORT, MPFROMP(&iptOffset),
  2317.                           (MPARAM)strlen(InfoBuf));
  2318.           WinSendMsg(hwndMLE, MLM_ENABLEREFRESH, NULL, NULL);
  2319.           if (UsingPipe) {
  2320.              WinLoadString(hab, 0, IDS_USINGPIPE, 79, tbuf);
  2321.              strncat(tbuf,szPipeName,79);
  2322.              }
  2323.           else {
  2324.              WinLoadString(hab, 0, IDS_USINGDRV, 79, tbuf);
  2325.              strncat(tbuf,szPddName+5,79);
  2326.              }
  2327.           if (strlen(tbuf)<50) {
  2328.              WinLoadString(hab, 0, IDS_APILEVEL, 79-strlen(tbuf), tbuf+strlen(tbuf));
  2329.              _itoa(ApiLevel,tbuf1,10);
  2330.              strncat(tbuf,tbuf1,79);
  2331.              }
  2332.           WinSetWindowText(WinWindowFromID(hwnd,IDC_INFODRV),tbuf);
  2333.        break;
  2334.           }
  2335.        case WM_COMMAND:
  2336.           if (LOUSHORT(mp1)==IDC_OK) WinDismissDlg(hwnd, TRUE);
  2337.           break;
  2338.        default:    
  2339.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2340.       return sRC;
  2341.        }
  2342.    return (MRESULT)0L;
  2343. }
  2344.  
  2345.  
  2346. /************************************************************************\
  2347. |                   Settings dialogs                                     |
  2348. \************************************************************************/
  2349.  
  2350. static HWND hwndControls1,hwndControls2,hwndOther,hwndLayout;
  2351.  
  2352. static     CHAR        Drive[]={0,0,0};
  2353. /*********************************************************************
  2354.  *
  2355.  *  Name:   OpenFileDialog
  2356.  *
  2357.  *  Purpose: open the standard file open dialog as file extention
  2358.  *         and return the filename
  2359.  *
  2360.  *  Usage:   called when the user needs to supply a name for
  2361.  *         the file to be opened
  2362.  *
  2363.  *  Method:  calls the standard file open dialog to get the
  2364.  *         file name.
  2365.  *
  2366.  *  Parameters: HWD hwnd     Handle of the owner window.
  2367.  *        PSZ szTitle     Title of open dialog.
  2368.  *        PSZ pszFileExt     File extention. (for example : *.txt)
  2369.  *        PSZ pszFullPath     PSZ for returning the file name.
  2370.  *
  2371.  *  Returns: TRUE if successful in getting a file name, FALSE
  2372.  *        if not in pushing CANCEL
  2373.  *         PSZ pszFullPath pointer to filename (full path)
  2374.  *
  2375.  **********************************************************************/
  2376. BOOL OpenFileDialog(HWND hwndOwner,
  2377.             PSZ szTitle,
  2378.             PSZ szFileExt,
  2379.             PSZ szFullPath,PSZ szOkButton)
  2380. {
  2381.    static   PSZ           ppszdefaultdrivelist[] = {NULL};
  2382.  
  2383.         FILEDLG    fdg;          /* file dialog structure         */
  2384.  
  2385.    fdg.cbSize = sizeof(FILEDLG);      /* Size of FILEDLG.             */
  2386.    fdg.pszTitle = szTitle;          /* String to display in title bar. */
  2387.    fdg.pszOKButton = szOkButton;      /* String to display in OK button. */
  2388.    fdg.ulUser = 0L;              /* User defined field.         */
  2389.    fdg.fl = FDS_HELPBUTTON |          /* FDS flags.                 */
  2390.         FDS_CENTER |
  2391.         FDS_OPEN_DIALOG;
  2392.    fdg.pfnDlgProc = (PFNWP)NULL;
  2393.    fdg.lReturn = 0L;              /* Result code from dialog dismissal. */
  2394.    fdg.lSRC = 0L;              /* System return code.      */
  2395.    fdg.hMod = 0;              /* Custom file dialog template. */
  2396.    fdg.usDlgId = 0;              /* Custom file dialog ID.      */
  2397.    fdg.x = 0;                  /* X coordinate of the dialog.  */
  2398.    fdg.y = 0;                  /* Y coordinate of the dialog.  */
  2399.  
  2400.    /* set selected fully qualified path */
  2401.    strcpy( fdg.szFullFile, szFileExt);
  2402.  
  2403.    fdg.pszIType = 0L;              /* Pointer to string containing   */
  2404.                       /*   Initial EA type filter.        */
  2405.    fdg.papszITypeList = 0L;          /* Pointer to table of pointers   */
  2406.                       /*  that point to null terminated */
  2407.    if (!Drive[0])              /*  Type strings.            */
  2408.        fdg.pszIDrive = 0L;          /* Pointer to string containing   */
  2409.    else                      /*  initial drive.            */
  2410.        fdg.pszIDrive = Drive;
  2411.  
  2412.    fdg.papszIDriveList = (PAPSZ)ppszdefaultdrivelist;
  2413.                       /* Pointer to table of pointers   */
  2414.                       /*  that point to null terminated */
  2415.                       /*  Drive strings.            */
  2416.    fdg.sEAType = 0;              /* Selected file's EA Type.       */
  2417.    fdg.papszFQFilename = 0;          /* Pointer to table of pointers   */
  2418.                       /*  point to null terminated        */
  2419.                       /*  FQFname strings.            */
  2420.    fdg.ulFQFCount = 0;              /* Numbers of file selected.        */
  2421.  
  2422.    /* get the file */
  2423.  
  2424.    if (!WinFileDlg(HWND_DESKTOP, hwndOwner, (PFILEDLG)&fdg))
  2425.       return FALSE;
  2426.  
  2427.    if (fdg.lReturn == DID_CANCEL)
  2428.       return FALSE;
  2429.  
  2430.    /* copy file name into file name buffer */
  2431.  
  2432.    strcpy(szFullPath, fdg.szFullFile);
  2433. /*   strcpy(szFileExt, fdg.szFullFile); */
  2434.    strncpy(Drive,fdg.szFullFile,2);        /* Always Contains Drive letter */
  2435.  
  2436.    return TRUE;
  2437. } /* End of OpenFileDialog */
  2438.  
  2439. void SettingsInit(HWND hwnd) {
  2440.    int i;
  2441.    char Buff[32];
  2442.    HWND hwndBook;
  2443.    ULONG ulPageId;
  2444.    PAGEINFO pginfo;
  2445.    PDLGTEMPLATE pDlgt;   
  2446.  
  2447.    hwndBook=WinWindowFromID(hwnd,IDC_NOTEBOOK);
  2448.  
  2449.    ulPageId = (ULONG)WinSendMsg(hwndBook,BKM_INSERTPAGE, NULL,
  2450.         MPFROM2SHORT((BKA_AUTOPAGESIZE | BKA_MAJOR | BKA_STATUSTEXTON),
  2451.         BKA_LAST));
  2452.    WinLoadString(hab, 0, IDS_ACTIVECTLS, 31, Buff);
  2453.    WinSendMsg(hwndBook,BKM_SETTABTEXT, MPFROMLONG(ulPageId),MPFROMP(Buff));
  2454.    WinLoadString(hab, 0, IDS_PAGE12, 31, Buff);
  2455.    WinSendMsg(hwndBook,BKM_SETSTATUSLINETEXT, MPFROMLONG(ulPageId),MPFROMP(Buff));
  2456.    DosGetResource(0,RT_DIALOG,IDD_CONTROLS1,(PPVOID)&pDlgt);
  2457.    hwndControls1=WinCreateDlg(hwnd,hwndBook,ControlsDlgProc,pDlgt,NULL);
  2458.    DosFreeResource((PVOID)pDlgt);
  2459.    WinSendMsg(hwndBook,BKM_SETPAGEWINDOWHWND,MPFROMLONG(ulPageId),
  2460.               MPFROMHWND(hwndControls1));
  2461.  
  2462.    ulPageId = (ULONG)WinSendMsg(hwndBook,BKM_INSERTPAGE, NULL,
  2463.         MPFROM2SHORT((BKA_AUTOPAGESIZE | BKA_STATUSTEXTON),
  2464.         BKA_LAST));
  2465.    WinLoadString(hab, 0, IDS_PAGE22, 31, Buff);
  2466.    WinSendMsg(hwndBook,BKM_SETSTATUSLINETEXT, MPFROMLONG(ulPageId),MPFROMP(Buff));
  2467.    DosGetResource(0,RT_DIALOG,IDD_CONTROLS2,(PPVOID)&pDlgt);
  2468.    hwndControls2=WinCreateDlg(hwnd,hwndBook,ControlsDlgProc,pDlgt,NULL);
  2469.    DosFreeResource((PVOID)pDlgt);
  2470.    WinSendMsg(hwndBook,BKM_SETPAGEWINDOWHWND,MPFROMLONG(ulPageId),
  2471.               MPFROMHWND(hwndControls2));
  2472.   
  2473.    ulPageId = (ULONG)WinSendMsg(hwndBook,BKM_INSERTPAGE, NULL,
  2474.         MPFROM2SHORT((BKA_AUTOPAGESIZE | BKA_MAJOR),
  2475.         BKA_LAST));
  2476.    WinLoadString(hab, 0, IDS_LAYOUT, 31, Buff);
  2477.    WinSendMsg(hwndBook,BKM_SETTABTEXT, MPFROMLONG(ulPageId),MPFROMP(Buff));
  2478.    DosGetResource(0,RT_DIALOG,IDD_LAYOUT,(PPVOID)&pDlgt);
  2479.    hwndLayout=WinCreateDlg(hwnd,hwndBook,LayoutDlgProc,pDlgt,NULL);
  2480.    DosFreeResource((PVOID)&pDlgt);
  2481.    WinSendMsg(hwndBook,BKM_SETPAGEWINDOWHWND,MPFROMLONG(ulPageId),
  2482.               MPFROMHWND(hwndLayout));
  2483.  
  2484.    ulPageId = (ULONG)WinSendMsg(hwndBook,BKM_INSERTPAGE, NULL,
  2485.         MPFROM2SHORT((BKA_AUTOPAGESIZE | BKA_MAJOR),
  2486.         BKA_LAST));
  2487.    WinLoadString(hab, 0, IDS_OTHER, 31, Buff);
  2488.    WinSendMsg(hwndBook,BKM_SETTABTEXT, MPFROMLONG(ulPageId),MPFROMP(Buff));
  2489.    DosGetResource(0,RT_DIALOG,IDD_OTHER,(PPVOID)&pDlgt);
  2490.    hwndOther=WinCreateDlg(hwnd,hwndBook,OtherDlgProc,pDlgt,NULL);
  2491.    DosFreeResource((PVOID)&pDlgt);
  2492.    WinSendMsg(hwndBook,BKM_SETPAGEWINDOWHWND,MPFROMLONG(ulPageId),
  2493.               MPFROMHWND(hwndOther));
  2494.  
  2495.    return;
  2496.    }
  2497.  
  2498. void SettingsCommand(HWND hwnd,MPARAM mp1) {
  2499.    int i;
  2500.    char Buff[32];
  2501.    unsigned int OldBase;
  2502.    HWND hwndCtl;
  2503.  
  2504.    switch(LOUSHORT(mp1)) {
  2505.       case IDC_CANCEL:
  2506.          WinDismissDlg(hwnd, FALSE);
  2507.          break;
  2508.       case IDC_DEFAULTS:
  2509.          WinSendDlgItemMsg(hwndLayout, IDC_SHOWMENU,BM_SETCHECK,(MPARAM)TRUE,(MPARAM)0);
  2510.          WinSendDlgItemMsg(hwndLayout, IDC_SHOWTITL,BM_SETCHECK,(MPARAM)TRUE,(MPARAM)0);
  2511.          WinSendDlgItemMsg(hwndLayout, IDC_NARROWSL,BM_SETCHECK,(MPARAM)FALSE,(MPARAM)0);
  2512.          WinSendDlgItemMsg(hwndLayout, IDC_SHORTSL,BM_SETCHECK,(MPARAM)FALSE,(MPARAM)0);
  2513.          WinLoadString(hab, 0, IDS_LOCK, 32, Buff);
  2514.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_LOCKNAME),Buff);
  2515.          WinLoadString(hab, 0, IDS_OFF, 32, Buff);
  2516.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_OFFNAME),Buff);
  2517.          WinLoadString(hab, 0, IDS_MUTE, 32, Buff);
  2518.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_MUTENAME),Buff);
  2519.          WinLoadString(hab, 0, IDS_BOTH, 32, Buff);
  2520.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_BOTHNAME),Buff);
  2521.          WinLoadString(hab, 0, IDS_SP, 32, Buff);
  2522.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_SPNAME),Buff);
  2523.          WinLoadString(hab, 0, IDS_LF, 32, Buff);
  2524.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_LFNAME),Buff);
  2525.          WinLoadString(hab, 0, IDS_CT, 32, Buff);
  2526.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_CTNAME),Buff);
  2527.          WinLoadString(hab, 0, IDS_HF, 32, Buff);
  2528.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_HFNAME),Buff);
  2529.          _itoa(DEF_CELLS_IN_LINE,Buff,10);
  2530.          WinSetWindowText(WinWindowFromID(hwndLayout,IDC_MAXCTLS),Buff);
  2531.          WinSendDlgItemMsg(hwndOther, IDC_RESTORE,BM_SETCHECK,(MPARAM)FALSE,0);
  2532.          WinSendDlgItemMsg(hwndOther, IDC_AUTOMINI,BM_SETCHECK,(MPARAM)FALSE,0);
  2533.          WinSetWindowText(WinWindowFromID(hwndOther,IDC_INSTNAME),"");
  2534.          WinSetWindowText(WinWindowFromID(hwndOther,IDC_ICONFILE),"");
  2535.          for (i=0;i<NControls;i++) {
  2536.             if (WinWindowFromID(hwndControls1,Controls[i].nameID))
  2537.                hwndCtl=hwndControls1;
  2538.             else hwndCtl=hwndControls2;
  2539.             if ((ApiLevel>1)||(!(Controls[i].flags&FLAG_LOCKABLE)))
  2540.                WinSendDlgItemMsg(hwndCtl,Controls[i].activeID,BM_SETCHECK,
  2541.                                  (MPARAM)TRUE,0);
  2542.             else WinSendDlgItemMsg(hwndCtl,Controls[i].activeID,
  2543.                                    BM_SETCHECK,(MPARAM)TRUE,0);
  2544.             WinLoadString(hab, 0, Controls[i].defnameID, 31, Buff);
  2545.             WinSetWindowText(WinWindowFromID(hwndCtl,Controls[i].nameID),
  2546.                              Buff);
  2547.             if (Controls[i].flags&FLAG_STEREO)
  2548.                WinSendDlgItemMsg(hwndCtl,Controls[i].monoID,
  2549.                                    BM_SETCHECK,(MPARAM)FALSE,0);
  2550.             } 
  2551.          break;
  2552.       case IDC_OK:
  2553.          RestoreState=(int)WinSendDlgItemMsg(hwndOther,IDC_RESTORE,
  2554.                                              BM_QUERYCHECK,0,0);
  2555.          AutoMini=(int)WinSendDlgItemMsg(hwndOther,IDC_AUTOMINI,BM_QUERYCHECK,
  2556.                                          0,0);
  2557.          WinQueryWindowText(WinWindowFromID(hwndOther,IDC_INSTNAME),
  2558.                             MAX_INST_NAME,szInstName);
  2559.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_MAXCTLS),32,Buff);
  2560.          i=atoi(Buff);
  2561.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_LOCKNAME),32,szLock);
  2562.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_MUTENAME),32,szMute);
  2563.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_OFFNAME),32,szOff);
  2564.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_BOTHNAME),32,szBoth);
  2565.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_SPNAME),32,szSp);
  2566.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_CTNAME),32,szCt);
  2567.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_LFNAME),32,szLF);
  2568.          WinQueryWindowText(WinWindowFromID(hwndLayout,IDC_HFNAME),32,szHF);
  2569.          ShowMenu=(int)WinSendDlgItemMsg(hwndLayout,IDC_SHOWMENU,
  2570.                                              BM_QUERYCHECK,0,0);
  2571.          ShowTitlebar=(int)WinSendDlgItemMsg(hwndLayout,IDC_SHOWTITL,
  2572.                                              BM_QUERYCHECK,0,0);
  2573.          NarrowSliders=(int)WinSendDlgItemMsg(hwndLayout,IDC_NARROWSL,
  2574.                                              BM_QUERYCHECK,0,0);
  2575.          ShortSliders=(int)WinSendDlgItemMsg(hwndLayout,IDC_SHORTSL,
  2576.                                              BM_QUERYCHECK,0,0);
  2577.          WinQueryWindowText(WinWindowFromID(hwndOther,IDC_ICONFILE),CCHMAXPATH,szIconFile);
  2578.          if ((i>=MIN_CELLS_IN_LINE)&&(i<=MAX_CELLS_IN_LINE)) CellsInLine=i;
  2579.          for(i=0;i<NControls;i++) if (Controls[i].supported) {
  2580.             if (WinWindowFromID(hwndControls1,Controls[i].nameID))
  2581.                hwndCtl=hwndControls1;
  2582.             else hwndCtl=hwndControls2;
  2583.             Controls[i].active=(int)WinSendDlgItemMsg(hwndCtl,
  2584.                                     Controls[i].activeID,BM_QUERYCHECK,0,0);
  2585.             WinQueryWindowText(WinWindowFromID(hwndCtl,Controls[i].nameID),
  2586.                                32,Controls[i].name);
  2587.             if (Controls[i].flags&FLAG_STEREO) {
  2588.                if (WinSendDlgItemMsg(hwndCtl,
  2589.                                     Controls[i].monoID,BM_QUERYCHECK,0,0))
  2590.                   Controls[i].both|=BOTH_MONO;
  2591.                else Controls[i].both&=~BOTH_MONO;
  2592.                }
  2593.  
  2594.             }
  2595.          SaveProfile();
  2596.          WinDismissDlg(hwnd, FALSE);
  2597.          break;
  2598.       }
  2599.    return;
  2600.    }
  2601.  
  2602. MRESULT EXPENTRY SettingsDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2603. {
  2604.    MRESULT sRC;
  2605.  
  2606.      switch (msg) {
  2607.        case WM_INITDLG:
  2608.           SettingsInit(hwnd);
  2609.        break;
  2610.        case WM_CLOSE:
  2611.           WinDismissDlg(hwnd, FALSE);
  2612.           break;
  2613.        case WM_COMMAND:
  2614.           SettingsCommand(hwnd,mp1);
  2615.           break;
  2616.        default:    
  2617.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2618.       return sRC;
  2619.        }
  2620.    return (MRESULT)0L;
  2621. }
  2622.  
  2623. MRESULT EXPENTRY ControlsDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2624. {
  2625.    MRESULT sRC;
  2626.    int i;
  2627.  
  2628.      switch (msg) {
  2629.        case WM_INITDLG:
  2630.           for(i=0;i<NControls;i++) if (WinWindowFromID(hwnd,Controls[i].nameID)) {
  2631.              WinSendDlgItemMsg(hwnd,Controls[i].activeID,BM_SETCHECK,(MPARAM)Controls[i].active,0);
  2632.              WinSetWindowText(WinWindowFromID(hwnd,Controls[i].nameID),Controls[i].name);
  2633.              if (Controls[i].flags&FLAG_STEREO)
  2634.                 WinSendDlgItemMsg(hwnd,Controls[i].monoID,BM_SETCHECK,(MPARAM)(Controls[i].both&BOTH_MONO),0);
  2635.              if (Controls[i].supported) {
  2636.                 WinEnableWindow(WinWindowFromID(hwnd,Controls[i].activeID),TRUE);
  2637.                 WinEnableWindow(WinWindowFromID(hwnd,Controls[i].nameID),TRUE);
  2638.                 if (Controls[i].flags&FLAG_STEREO)
  2639.                    WinEnableWindow(WinWindowFromID(hwnd,Controls[i].monoID),TRUE);
  2640.                 }
  2641.              }
  2642.        break;
  2643.        case WM_CLOSE:
  2644.           WinDismissDlg(hwnd, FALSE);
  2645.           break;
  2646.        default:    
  2647.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2648.       return sRC;
  2649.        }
  2650.    return (MRESULT)0L;
  2651. }
  2652.  
  2653. MRESULT EXPENTRY LayoutDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2654. {
  2655.    MRESULT sRC;
  2656.    char Buff[16];
  2657.  
  2658.      switch (msg) {
  2659.        case WM_INITDLG:
  2660.  
  2661.           WinSetWindowText(WinWindowFromID(hwnd,IDC_LOCKNAME),szLock);
  2662.           WinSetWindowText(WinWindowFromID(hwnd,IDC_OFFNAME),szOff);
  2663.           WinSetWindowText(WinWindowFromID(hwnd,IDC_MUTENAME),szMute);
  2664.           WinSetWindowText(WinWindowFromID(hwnd,IDC_BOTHNAME),szBoth);
  2665.           WinSetWindowText(WinWindowFromID(hwnd,IDC_LFNAME),szLF);
  2666.           WinSetWindowText(WinWindowFromID(hwnd,IDC_HFNAME),szHF);
  2667.           WinSetWindowText(WinWindowFromID(hwnd,IDC_CTNAME),szCt);
  2668.           WinSetWindowText(WinWindowFromID(hwnd,IDC_SPNAME),szSp);
  2669.           _itoa(CellsInLine,Buff,10);
  2670.           WinSetWindowText(WinWindowFromID(hwnd,IDC_MAXCTLS),Buff);
  2671.           WinSendDlgItemMsg(hwnd, IDC_SHOWMENU,BM_SETCHECK,(MPARAM)ShowMenu,0);
  2672.           WinSendDlgItemMsg(hwnd, IDC_SHOWTITL,BM_SETCHECK,(MPARAM)ShowTitlebar,0);
  2673.           WinSendDlgItemMsg(hwnd, IDC_NARROWSL,BM_SETCHECK,(MPARAM)NarrowSliders,0);
  2674.           WinSendDlgItemMsg(hwnd, IDC_SHORTSL,BM_SETCHECK,(MPARAM)ShortSliders,0);
  2675.        break;
  2676.        case WM_CLOSE:
  2677.           WinDismissDlg(hwnd, FALSE);
  2678.           break;
  2679.        default:    
  2680.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2681.       return sRC;
  2682.        }
  2683.    return (MRESULT)0L;
  2684. }
  2685.  
  2686.  
  2687. const char szExt[]="*.ico;*.exe;*.dll";
  2688. MRESULT EXPENTRY OtherDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  2689. {
  2690.    MRESULT sRC;
  2691.    char Buff[16];
  2692.  
  2693.      switch (msg) {
  2694.        case WM_INITDLG:
  2695.           WinSendDlgItemMsg(hwnd, IDC_RESTORE,BM_SETCHECK,(MPARAM)RestoreState,0);
  2696.           WinSendDlgItemMsg(hwnd, IDC_AUTOMINI,BM_SETCHECK,(MPARAM)AutoMini,0);
  2697.           WinSendMsg(WinWindowFromID(hwnd,IDC_INSTNAME),EM_SETTEXTLIMIT,(MPARAM)MAX_INST_NAME,0);
  2698.           WinSetWindowText(WinWindowFromID(hwnd,IDC_INSTNAME),szInstName);
  2699.           WinSendMsg(WinWindowFromID(hwnd,IDC_ICONFILE),EM_SETTEXTLIMIT,(MPARAM)CCHMAXPATH,0);
  2700.           WinSetWindowText(WinWindowFromID(hwnd,IDC_ICONFILE),szIconFile);
  2701.        break;
  2702.        case WM_CLOSE:
  2703.           WinDismissDlg(hwnd, FALSE);
  2704.           break;
  2705.        case WM_COMMAND:
  2706.           if(LOUSHORT(mp1)==IDC_ICONLOC) {
  2707.              char szTit[MESSAGELEN];
  2708.  
  2709.              WinLoadString(hab, 0, IDS_SELECTICON, MESSAGELEN, szTit);
  2710.              WinLoadString(hab, 0, IDS_OK, 15, Buff);
  2711.              if (OpenFileDialog(WinQueryWindow(hwnd,QW_PARENT),szTit,
  2712.                                 (char *)szExt,szIconFile,Buff)) {
  2713.                 WinSetWindowText(WinWindowFromID(hwnd,IDC_ICONFILE),szIconFile);
  2714.                 }
  2715.              }
  2716.           break;
  2717.        default:    
  2718.       sRC = WinDefDlgProc(hwnd, msg, mp1, mp2);
  2719.       return sRC;
  2720.        }
  2721.    return (MRESULT)0L;
  2722. }
  2723.