home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lstbx2.zip / lbsnd.c < prev    next >
C/C++ Source or Header  |  1994-04-22  |  18KB  |  524 lines

  1. #pragma    title("List Box Control  --  Version 1.1 -- (LBSnd.C)")
  2. #pragma    subtitle("  MMPM/2 Support - Interface Definitions")
  3.  
  4. /* Program name: Listbox.Dll    Title: A List Box Replacement        */
  5. /*                                    */
  6. /* OS/2    Developer Magazine, Issue:  May    '94, page 12                    */
  7. /* Author:  Mark Benge       IBM Corp.                    */
  8. /*        Matt Smith       Prominare Inc.                */
  9. /* Description:     Replacement for OS/2 List Box,    first of a series.    */
  10. /*                                    */
  11. /* Program Requirements:  OS/2 2.x                    */
  12. /*              IBM C    Set++                    */
  13. /*              WATCOM C 386/9.0                */
  14. /*              Borland C++ for OS/2                */
  15. /*              OS/2 Toolkit                    */
  16. /*              MMPM/2 Toolkit                */
  17.  
  18. /* Copyright ╕ International Business Machines Corp. 1991-1994        */
  19. /* Copyright ╕ 1989-1994  Prominare Inc.  All Rights Reserved.        */
  20.  
  21. /************************************************************************/
  22. /************************************************************************/
  23. /*               DISCLAIMER OF WARRANTIES.            */
  24. /************************************************************************/
  25. /************************************************************************/
  26. /*     The following [enclosed]    code is    source code created by the    */
  27. /*     authors.     This source code is  provided to you solely        */
  28. /*     for the purpose of assisting you    in the development of your    */
  29. /*     applications.  The code is provided "AS IS", without        */
  30. /*     warranty    of any kind.  The authors shall    not be liable        */
  31. /*     for any damages arising out of your use of the source code,    */
  32. /*     even if they have been advised of the possibility of such    */
  33. /*     damages.     It is provided    purely for instructional and        */
  34. /*     illustrative purposes.                        */
  35. /************************************************************************/
  36. /************************************************************************/
  37.  
  38. #pragma    info(noext)
  39. #pragma    strings(readonly)
  40.  
  41. #define    INCL_DOS           /* Include OS/2 DOS Kernal        */
  42. #define    INCL_OS2MM           /* Include OS/2 MultiMedia Interface    */
  43. #define    INCL_WIN           /* Include OS/2 PM Windows Interface    */
  44.  
  45. static char *MODID = "@(#)lbsnd.c:1.00";
  46.  
  47. #include <os2.h>
  48. #include <os2me.h>
  49. #include <string.h>
  50.  
  51. /* This    module contains    the routines that handle the sound management    */
  52. /* for the list    box.                            */
  53. /*                                    */
  54. /* Equivalent command line invocation of each module using the        */
  55. /* IBM C Set++ Compiler    Version    2.0 is:                    */
  56. /*                                    */
  57. /*     Icc -G3e- -O+ -Rn -C -W3    -FoLBSnd LBSnd.C            */
  58.  
  59. /* Filename:   LBSnd.C                            */
  60.  
  61. /*  Version:   2.00                            */
  62. /*  Created:   1994-02-27                        */
  63. /*  Revised:   1994-04-21                        */
  64.  
  65. /* Routines:   static VOID ShowMCIError(HWND hWnd, ULONG ulError);    */
  66. /*           static VOID _System PlayWaveThread(ULONG    hSound);    */
  67. /*           ULONG EXPENTRY LoadWaveFile(HWND    hWnd, PSZ pszWaveFile);    */
  68. /*           VOID EXPENTRY UnloadWave(HWND hWnd, ULONG hSound);    */
  69. /*           VOID EXPENTRY PlayWave(ULONG hSound);            */
  70.  
  71.  
  72. /* --------------------------------------------------------------------    */
  73.  
  74. static VOID ShowMCIError(HWND hWnd, ULONG ulError);
  75.  
  76. #if defined(__IBMC__) || defined(__IBMCPP__)
  77.  
  78. static VOID _System PlayWaveThread(ULONG hSound);
  79.  
  80. #else
  81. #if defined(__WATCOMC__)
  82.  
  83. static VOID __syscall PlayWaveThread(ULONG hSound);
  84.  
  85. #else
  86. #if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
  87.  
  88. static VOID _syscall PlayWaveThread(ULONG hSound);
  89.  
  90. #endif
  91. #endif
  92. #endif
  93.  
  94. #if !defined(STACK_COMMITTED)
  95.  
  96. #define    STACK_COMMITTED    2UL
  97.  
  98. #endif
  99.  
  100. ULONG EXPENTRY LoadWaveFile(HWND hWnd, PSZ pszWaveFile);
  101. VOID EXPENTRY UnloadWave(HWND hWnd, ULONG hSound);
  102. VOID EXPENTRY PlayWave(ULONG hSound);
  103.  
  104. /************************************************************************/
  105. /*                                    */
  106. /*     Private Functions                        */
  107. /*                                    */
  108. /************************************************************************/
  109.  
  110. #pragma    subtitle("   MMPM/2 Support - mci Error Display Routine")
  111. #pragma    page ( )
  112.  
  113. /* --- ShowMCIError -----------------------------------    [ Private ] ---    */
  114. /*                                    */
  115. /*     This function is    used to    display    a mci* error message.        */
  116. /*                                    */
  117. /*     Upon Entry:                            */
  118. /*                                    */
  119. /*     HWND  hWnd;    =    Calling    Window Handle                */
  120. /*     ULONG ulError; =    mci Error Value                    */
  121. /*                                    */
  122. /*     Upon Exit:                            */
  123. /*                                    */
  124. /*     Nothing                                */
  125. /*                                    */
  126. /* --------------------------------------------------------------------    */
  127.  
  128. static VOID ShowMCIError(HWND hWnd, ULONG ulError)
  129.  
  130. {
  131. CHAR szMessage[128];           /* Error Message Buffer        */
  132.  
  133. switch ( mciGetErrorString(ulError, szMessage, 128) )
  134.    {
  135.    case    MCIERR_SUCCESS :
  136.        WinMessageBox(HWND_DESKTOP, hWnd,
  137.              szMessage,    "mci Error Message",
  138.              0UL, MB_OK    | MB_ICONHAND |    MB_MOVEABLE);
  139.        break;
  140.  
  141.    case    MCIERR_INVALID_DEVICE_ID :
  142.    case    MCIERR_OUTOFRANGE :
  143.    case    MCIERR_INVALID_BUFFER :
  144.    default :
  145.        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
  146.              "Unknown error!", "mci Error Message",
  147.              0UL, MB_OK    | MB_ICONHAND |    MB_MOVEABLE);
  148.        break;
  149.    }
  150. }
  151. #pragma    subtitle("   MMPM/2 Support - Control Window Procedure")
  152. #pragma    page ( )
  153.  
  154. /* --- PlayWaveThread ---------------------------------    [ Private ] ---    */
  155. /*                                    */
  156. /*     This function is    used to    play a loaded wave file    within a    */
  157. /*     separate    thread to ensure responsiveness.            */
  158. /*                                    */
  159. /*     Upon Entry:                            */
  160. /*                                    */
  161. /*     ULONG hSound; = Sound File Handle                */
  162. /*                                    */
  163. /*     Upon Exit:                            */
  164. /*                                    */
  165. /*     Nothing                                */
  166. /*                                    */
  167. /* --------------------------------------------------------------------    */
  168.  
  169. #if defined(__IBMC__) || defined(__IBMCPP__)
  170.  
  171. static VOID _System PlayWaveThread(ULONG hSound)
  172.  
  173. #else
  174. #if defined(__WATCOMC__)
  175.  
  176. static VOID __syscall PlayWaveThread(ULONG hSound)
  177.  
  178. #else
  179. #if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
  180.  
  181. static VOID _syscall PlayWaveThread(ULONG hSound)
  182.  
  183. #endif
  184. #endif
  185. #endif
  186.  
  187. {
  188. HAB          habThread;       /* Thread Anchor Block        */
  189. HMQ          hmqThread;       /* Thread Message Queue Handle    */
  190. MCI_GENERIC_PARMS mciGenericParms; /* Generic Parameters        */
  191. MCI_PLAY_PARMS      mciPlayParms;       /* Play Parameters            */
  192. MCI_SEEK_PARMS      mciSeekParms;       /* Seek Parameters            */
  193. ULONG          ulError;       /* Error Holder            */
  194.  
  195.                /* Register the thread with OS/2    PM        */
  196.  
  197. habThread = WinInitialize(0UL);
  198.  
  199.                /* Acquire the wave device first            */
  200.  
  201. mciGenericParms.hwndCallback = (HWND)NULL;
  202. if ( (ulError =    mciSendCommand((USHORT)hSound, MCI_ACQUIREDEVICE, MCI_WAIT,
  203.                    (PVOID)&mciGenericParms,    0UL)) == MCIERR_SUCCESS    )
  204.    {
  205.                /* Initialize the play parameters structure    */
  206.  
  207.    mciPlayParms.hwndCallback = (HWND)NULL;
  208.  
  209.                /* Try to play the loaded wave file        */
  210.  
  211.    if (    (ulError = mciSendCommand((USHORT)hSound, MCI_PLAY, MCI_WAIT,
  212.                    (PVOID)&mciPlayParms, 0UL)) != 0UL )
  213.        {
  214.                /* Error    occurred, create a message queue so as    */
  215.                /* to be    able to    display    the error message    */
  216.                /* within a message box                */
  217.  
  218.        hmqThread = WinCreateMsgQueue(habThread,    0L);
  219.        ShowMCIError(HWND_DESKTOP, ulError);
  220.        WinDestroyMsgQueue(hmqThread);
  221.  
  222.                /* Stop the attempted playing of    the wave file    */
  223.  
  224.        mciGenericParms.hwndCallback = (HWND)NULL;
  225.        mciSendCommand((USHORT)hSound, MCI_STOP,    MCI_WAIT,
  226.               (PVOID)&mciGenericParms, 0UL);
  227.        }
  228.    else
  229.        {
  230.                /* Initialize the seek parameters structure    */
  231.  
  232.        memset(&mciSeekParms, 0,    sizeof(MCI_SEEK_PARMS));
  233.  
  234.                /* Rewind the sound back    to the beginning to    */
  235.                /* allow    it to be played    from the beginning    */
  236.                /* a subsequent time                */
  237.  
  238.        mciSendCommand((USHORT)hSound, MCI_SEEK,    MCI_WAIT | MCI_TO_START,
  239.               (PVOID)&mciSeekParms, 0UL);
  240.        }
  241.    }
  242. else
  243.    {
  244.                /* Error    occurred, create a message queue so as    */
  245.                /* to be    able to    display    the error message    */
  246.                /* within a message box                */
  247.  
  248.    hmqThread = WinCreateMsgQueue(habThread, 0L);
  249.    ShowMCIError(HWND_DESKTOP, ulError);
  250.    WinDestroyMsgQueue(hmqThread);
  251.    }
  252.                /* De-register the thread with OS/2 PM since the    */
  253.                /* creation of the bitmap is complete        */
  254. WinTerminate(habThread);
  255.                /* Exit the thread                */
  256. DosExit(EXIT_THREAD, 0L);
  257. }
  258.  
  259. /************************************************************************/
  260. /************************************************************************/
  261. /*                                    */
  262. /************************************************************************/
  263. /************************************************************************/
  264. /*                                    */
  265. /*     Public Functions                            */
  266. /*                                    */
  267. /************************************************************************/
  268. /************************************************************************/
  269. /*                                    */
  270. /************************************************************************/
  271. /************************************************************************/
  272.  
  273. #pragma    subtitle("   MMPM/2 Support - Wave File Load Function")
  274. #pragma    page ( )
  275.  
  276. /* --- LoadWaveFile ------------------------------------ [ Public ] ---    */
  277. /*                                    */
  278. /*     This function is    used to    load a wave file specified and return    */
  279. /*     back to the caller a handle that    can be used to play the    file    */
  280. /*     as required.                            */
  281. /*                                    */
  282. /*     Upon Entry:                            */
  283. /*                                    */
  284. /*     HWND hWnd;     = Window Handle                */
  285. /*     PSZ  pszWaveFile; = Wave    File to    Use                */
  286. /*                                    */
  287. /*     Upon Exit:                            */
  288. /*                                    */
  289. /*     LoadWaveFile =  0 : Error Return                    */
  290. /*            = >0 : Wave    File Handle                */
  291. /*                                    */
  292. /* --------------------------------------------------------------------    */
  293.  
  294. ULONG EXPENTRY LoadWaveFile(HWND hWnd, PSZ pszWaveFile)
  295.  
  296. {
  297. BYTE              szMMPMBase[CCHMAXPATH];  /* MMPM/2 Base Path    */
  298. BYTE              szWavePath[CCHMAXPATH];  /* Wave File    Path    */
  299. FILESTATUS3          fsts;               /* File Status    */
  300. MCI_OPEN_PARMS          mciOpenParms;           /* Open Parameters    */
  301. MCI_SYSINFO_DEFAULTDEVICE mciSysInfoDefaultDevice; /* Default Device    */
  302. MCI_SYSINFO_PARMS      mciSysInfoParms;       /* Info Parameters    */
  303. MCI_SYSINFO_QUERY_NAME      mciSysInfoQueryName;       /* Query Name    */
  304. PSZ              pszMMPMBase;           /* Environment Ptr    */
  305. ULONG              ulError;           /* Error Holder    */
  306. register UINT n;           /* Index                */
  307.  
  308.                /* Check    to see if the wave file    name valid and    */
  309.                /* if it    isn't return with the null handle       */
  310.                /* to indicate the wave file was    not loaded    */
  311. if ( !pszWaveFile )
  312.    return(0UL);
  313. else
  314.    if (    !pszWaveFile[0]    )
  315.        return(0UL);
  316.                /* Initialize the system    information parameters    */
  317.                /* structure                    */
  318.  
  319. memset(&mciSysInfoParms,     0, sizeof(MCI_SYSINFO_PARMS));
  320. memset(&mciSysInfoDefaultDevice, 0, sizeof(MCI_SYSINFO_DEFAULTDEVICE));
  321.  
  322. mciSysInfoParms.ulItem         = MCI_SYSINFO_QUERY_DEFAULT;
  323. mciSysInfoParms.pSysInfoParm = &mciSysInfoDefaultDevice;
  324.  
  325. mciSysInfoDefaultDevice.usDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
  326.  
  327.                /* Get the system information for the wave    */
  328.                /* device to allow it to    be properly opended    */
  329.                /* with the desired wave    file            */
  330.  
  331. if ( (ulError =    mciSendCommand(0, MCI_SYSINFO, MCI_WAIT    | MCI_SYSINFO_ITEM,
  332.                    (PVOID)&mciSysInfoParms,    0UL)) == 0UL )
  333.    {
  334.                /* Initialize the system    information parameters    */
  335.                /* again, to get    more information about the    */
  336.                /* wave device                    */
  337.    memset(&mciSysInfoParms,    0, sizeof(MCI_SYSINFO_PARMS));
  338.    memset(&mciSysInfoQueryName,    0, sizeof(MCI_SYSINFO_QUERY_NAME));
  339.  
  340.    mciSysInfoParms.ulItem    = MCI_SYSINFO_QUERY_NAMES;
  341.    mciSysInfoParms.pSysInfoParm    = &mciSysInfoQueryName;
  342.  
  343.    memmove(&mciSysInfoQueryName.szInstallName,
  344.        &mciSysInfoDefaultDevice.szInstallName,
  345.        sizeof(mciSysInfoQueryName.szInstallName));
  346.  
  347.                /* Get the system information for the wave    */
  348.                /* device to allow it to    be properly opended    */
  349.                /* with the desired wave    file            */
  350.  
  351.    if (    (ulError = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
  352.                   (PVOID)&mciSysInfoParms, 0UL)) == 0UL    )
  353.        {
  354.                /* Check    to see that the    wave file specified    */
  355.                /* does actually    exist.    Also, find the true    */
  356.                /* location of the file since a fully qualified    */
  357.                /* filename is required.                */
  358.  
  359.        if (    !DosQueryPathInfo(pszWaveFile, FIL_STANDARD, (PBYTE)&fsts,
  360.                   sizeof(FILESTATUS3)) )
  361.  
  362.                /* Fully    qualified path give, use the filename    */
  363.                /* as is                        */
  364.  
  365.            strcpy(szWavePath, pszWaveFile);
  366.        else
  367.                /* Wave file probably in    the MMPM/2 SOUNDS    */
  368.                /* directory, find the location where MMPM/2 is    */
  369.                /* located by looking for the base environment    */
  370.                /* variable                    */
  371.  
  372.            if ( !DosScanEnv("MMBASE", &pszMMPMBase)    )
  373.            {
  374.  
  375.                /* Have found the base location for the MMPM/2,    */
  376.                /* parse    out the    path portion before trying to    */
  377.                /* construct the    wave file path.     First make    */
  378.                /* sure that any    trailing semi-colons are    */
  379.                /* removed.                    */
  380.  
  381.            if (    szMMPMBase[n = strlen(strcpy(szMMPMBase, pszMMPMBase)) - 1] == ';' )
  382.                szMMPMBase[n--] = 0;
  383.  
  384.                /* Next check to    see if a back-slash present at    */
  385.                /* the end of the path and if not the case, add    */
  386.                /* one                        */
  387.  
  388.            if (    szMMPMBase[n] != '\\' )
  389.                strcat(szMMPMBase, "\\");
  390.  
  391.                /* Complete the path and    search for the file    */
  392.  
  393.            if (    DosSearchPath(SEARCH_CUR_DIRECTORY | SEARCH_IGNORENETERRS,
  394.                       strcat(szMMPMBase, "SOUNDS"), pszWaveFile, szWavePath, CCHMAXPATH) )
  395.  
  396.                /* File not found, use the existing wave    file    */
  397.                /* name                        */
  398.  
  399.                strcpy(szWavePath, pszWaveFile);
  400.            }
  401.            else
  402.                /* MMBASE environment variable not found, use    */
  403.                /* the given wave file name            */
  404.  
  405.            strcpy(szWavePath, pszWaveFile);
  406.  
  407.                /* Initialize the open parameters structure    */
  408.  
  409.        memset(&mciOpenParms, 0,    sizeof(MCI_OPEN_PARMS));
  410.        mciOpenParms.hwndCallback = (HWND)NULL;
  411.        mciOpenParms.pszElementName = szWavePath;
  412.        mciOpenParms.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_WAVEFORM_AUDIO,
  413.                            mciSysInfoQueryName.usDeviceOrd);
  414.  
  415.                /* Open the wave    device                */
  416.  
  417.        if ( (ulError = mciSendCommand(0, MCI_OPEN,
  418.                       MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE | MCI_OPEN_ELEMENT,
  419.                       (PVOID)&mciOpenParms, 0UL)) == 0UL )
  420.  
  421.                /* Wave file successfully loaded, return    the    */
  422.                /* device ID as the handle for the wave file    */
  423.  
  424.            return((ULONG)mciOpenParms.usDeviceID);
  425.        else
  426.                /* Wave device could not    be opened, display    */
  427.                /* returned error                */
  428.  
  429.        ShowMCIError(hWnd, ulError);
  430.        }
  431.    else
  432.                /* Error    in retrieving information for the wave    */
  433.                /* device, display returned error        */
  434.  
  435.        ShowMCIError(hWnd, ulError);
  436.    }
  437. else
  438.                /* Error    in retrieving information to determine    */
  439.                /* the name of the wave device, display        */
  440.                /* returned error                */
  441.  
  442.    ShowMCIError(hWnd, ulError);
  443.  
  444.                /* Return null handle indicating    that the wave    */
  445.                /* file was not successfully loaded        */
  446. return(0UL);
  447. }
  448. #pragma    subtitle("   MMPM/2 Support - Wave File Unload Function")
  449. #pragma    page ( )
  450.  
  451. /* --- UnloadWaveFile ---------------------------------- [ Public ] ---    */
  452. /*                                    */
  453. /*     This function is    used to    unload a loaded    wave file and to    */
  454. /*     release the associated handle.                    */
  455. /*                                    */
  456. /*     Upon Entry:                            */
  457. /*                                    */
  458. /*     HWND  hWnd;   = Window Handle                    */
  459. /*     ULONG hSound; = Sound File Handle                */
  460. /*                                    */
  461. /*     Upon Exit:                            */
  462. /*                                    */
  463. /*     Nothing                                */
  464. /*                                    */
  465. /* --------------------------------------------------------------------    */
  466.  
  467. VOID EXPENTRY UnloadWave(HWND hWnd, ULONG hSound)
  468.  
  469. {
  470. MCI_GENERIC_PARMS mciGenericParms; /* Generic Parameters Structure    */
  471. ULONG          ulError;       /* Error Value            */
  472.  
  473.                /* Check    to make    sure that a valid handle has    */
  474.                /* passed.  A null handle indicates that    the    */
  475.                /* wave file was    not loaded.            */
  476. if ( hSound )
  477.    {
  478.                /* Initialize the generic parameters        */
  479.  
  480.    mciGenericParms.hwndCallback    = (HWND)NULL;
  481.  
  482.                /* Close    the wave file and the wave device    */
  483.  
  484.    if (    (ulError = mciSendCommand((USHORT)hSound, MCI_CLOSE, MCI_WAIT,
  485.                    (PVOID)&mciGenericParms, 0UL)) != 0UL )
  486.  
  487.                /* Error    in closing, display the    error value    */
  488.  
  489.        ShowMCIError(hWnd, ulError);
  490.    }
  491. }
  492. #pragma    subtitle("   MMPM/2 Support - Ansync Sound Play Procedure")
  493. #pragma    page ( )
  494.  
  495. /* --- PlayWave    ---------------------------------------- [ Public ] ---    */
  496. /*                                    */
  497. /*     This function is    used to    load and play a    wave file submitted.    */
  498. /*                                    */
  499. /*     Upon Entry:                            */
  500. /*                                    */
  501. /*     ULONG hSound; = Sound File Handle                */
  502. /*                                    */
  503. /*     Upon Exit:                            */
  504. /*                                    */
  505. /*     Nothing                                */
  506. /*                                    */
  507. /* --------------------------------------------------------------------    */
  508.  
  509. VOID EXPENTRY PlayWave(ULONG hSound)
  510.  
  511. {
  512. TID tid;               /* Thread ID                */
  513.  
  514.                /* Check    to make    sure that a valid handle has    */
  515.                /* passed.  A null handle indicates that    the    */
  516.                /* wave file was    not loaded.            */
  517. if ( hSound )
  518.                /* Start    the play thread    and pass the sound    */
  519.                /* handle as the    parameter block    to the thread    */
  520.  
  521.    DosCreateThread(&tid, (PFNTHREAD)PlayWaveThread,
  522.            hSound, STACK_COMMITTED, 16384UL);
  523. }
  524.