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

  1. #pragma    title("List Box Replacement  --  Version 1.1 -- (SndMgr.C)")
  2. #pragma    subtitle("   Sound Manager - 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.  
  17. /* Copyright ╕ International Business Machines Corp. 1991-1994        */
  18. /* Copyright ╕ 1989-1994  Prominare Inc.  All Rights Reserved.        */
  19.  
  20. /************************************************************************/
  21. /************************************************************************/
  22. /*               DISCLAIMER OF WARRANTIES.            */
  23. /************************************************************************/
  24. /************************************************************************/
  25. /*     The following [enclosed]    code is    source code created by the    */
  26. /*     authors.     This source code is  provided to you solely        */
  27. /*     for the purpose of assisting you    in the development of your    */
  28. /*     applications.  The code is provided "AS IS", without        */
  29. /*     warranty    of any kind.  The authors shall    not be liable        */
  30. /*     for any damages arising out of your use of the source code,    */
  31. /*     even if they have been advised of the possibility of such    */
  32. /*     damages.     It is provided    purely for instructional and        */
  33. /*     illustrative purposes.                        */
  34. /************************************************************************/
  35. /************************************************************************/
  36.  
  37. #pragma    info(noext)
  38. #pragma    strings(readonly)
  39.  
  40. #define    INCL_DOS           /* Include OS/2 DOS Kernal        */
  41. #define    INCL_GPI           /* Include OS/2 PM GPI Interface    */
  42. #define    INCL_WIN           /* Include OS/2 PM Windows Interface    */
  43.  
  44. #include <os2.h>
  45. #include <setjmp.h>
  46. #include <string.h>
  47.  
  48. #include "listbox.h"
  49.  
  50. /* This    module contains    the routines that handle the sound management    */
  51. /* for the list    box.                            */
  52. /*                                    */
  53. /* Equivalent command line invocation of each module using the        */
  54. /* IBM C Set++ Compiler    Version    2.0 is:                    */
  55. /*                                    */
  56. /*     Icc -G3e- -O+ -Rn -C -W3    -FoSndMgr SndMgr.C            */
  57.  
  58. /* Filename:   SndMgr.C                            */
  59.  
  60. /*  Version:   1.1                            */
  61. /*  Created:   1994-02-27                        */
  62. /*  Revised:   1994-04-23                        */
  63.  
  64. /* Routines:   VOID LoadSoundSupport(PLISTBOXWIN plbw);            */
  65. /*           VOID PlaySound(PLISTBOXWIN plbw,    ULONG ulSound);        */
  66. /*           VOID UnloadSoundSupport(PLISTBOXWIN plbw);        */
  67. /*           VOID SetControlDataSounds(PLISTBOXWIN plbw, ULONG cItems,*/
  68. /*                     ULONG cSounds,    PBYTE pb);    */
  69. /*           VOID SetControlDataSounds(PLISTBOXWIN plbw,        */
  70. /*                     ULONG cItems, ULONG cSounds    */
  71. /*                     PBYTE pb);            */
  72. /*           MRESULT EXPENTRY    mrSoundHandler(HWND hWnd, ULONG    msg,    */
  73. /*                           MPARAM mp1, MPARAM mp2);    */
  74.  
  75.  
  76. /* --------------------------------------------------------------------    */
  77.  
  78. /* Sound List Box messages                        */
  79. /*                                    */
  80. /*     LMXM_SETSOUNDEVENT      0x0396UL                */
  81. /*     LMXM_QUERYSOUNDEVENT      0x0397UL                */
  82.  
  83. extern jmp_buf jBuf;           /* Jump Buffer            */
  84.  
  85. /************************************************************************/
  86. /*                                    */
  87. /* Module Prototype Definitions                        */
  88. /*                                    */
  89. /************************************************************************/
  90.  
  91. APIRET APIENTRY    ListBoxExceptionHandler(PEXCEPTIONREPORTRECORD pxcptrepr,
  92.                     PEXCEPTIONREGISTRATIONRECORD pxcptregr,
  93.                     PCONTEXTRECORD pcr, PVOID sysinfo);
  94.  
  95. #pragma    subtitle("   Sound Manager - Sound Support Loading Function")
  96. #pragma    page( )
  97.  
  98. /* --- LoadSoundSupport    -------------------------------- [ Public ] ---    */
  99. /*                                    */
  100. /*     This function is    used to    dynamically load the sound support DLL    */
  101. /*     that will allow the associating of sounds with the listbox.    */
  102. /*                                    */
  103. /*     Upon Entry:                            */
  104. /*                                    */
  105. /*     PLISTBOXWIN plbw; = List    Box Internal Data Pointer        */
  106. /*                                    */
  107. /*     Upon Exit:                            */
  108. /*                                    */
  109. /*     Nothing                                */
  110. /*                                    */
  111. /* --------------------------------------------------------------------    */
  112.  
  113. VOID LoadSoundSupport(PLISTBOXWIN plbw)
  114.  
  115. {
  116. CHAR szFile[CCHMAXPATH];       /* Failing Component    Filename    */
  117.  
  118.                /* Try loading the sound    support    DLL.  If MMPM/2    */
  119.                /* has been loaded, the DLL will    be successfully    */
  120.                /* loaded.  The routines    within depend on the    */
  121.                /* handle being either zero (0) which indicates    */
  122.                /* sound    support    is not found or    a non-zero    */
  123.                /* indicating that the soupport DLL was found    */
  124.                /* and loaded and that sounds can be associated    */
  125.                /* with list box    events and played.        */
  126.  
  127. if ( DosLoadModule(szFile, CCHMAXPATHCOMP, "LBSnd", &plbw->hmodSnd) )
  128.  
  129.                /* Sound    support    DLL could not be loaded.  The    */
  130.                /* value    within the szFile variable will    contain    */
  131.                /* the failing component.  Set the module handle    */
  132.                /* to zero to indicate that sound events    are    */
  133.                /* not to use MMPM/2 wave files.            */
  134.    plbw->hmodSnd = 0UL;
  135. else
  136.                /* Try loading the LoadWaveFile function    entry    */
  137.                /* point                        */
  138.  
  139.    if (    DosQueryProcAddr(plbw->hmodSnd,    ORD_LOADWAVEFILE, NULL,
  140.              (PFN *)(PVOID)&plbw->pfnLoadWaveFile) )
  141.        {
  142.                /* Ordinal not found within the DLL, release the    */
  143.                /* sound    support    DLL and    clear the module handle    */
  144.                /* to indicate sound events cannot be used    */
  145.  
  146.        DosFreeModule(plbw->hmodSnd);
  147.        plbw->hmodSnd = 0UL;
  148.        }
  149.    else
  150.                /* Try loading the UnloadWave function entry    */
  151.                /* point                        */
  152.  
  153.        if ( DosQueryProcAddr(plbw->hmodSnd, ORD_UNLOADWAVE, NULL,
  154.                  (PFN *)(PVOID)&plbw->pfnUnloadWave) )
  155.        {
  156.                /* Ordinal not found within the DLL, release the    */
  157.                /* sound    support    DLL and    clear the module handle    */
  158.                /* to indicate sound events cannot be used    */
  159.  
  160.        DosFreeModule(plbw->hmodSnd);
  161.        plbw->hmodSnd = 0UL;
  162.        }
  163.        else
  164.                /* Try loading the PlayWav function entry point    */
  165.  
  166.        if (    DosQueryProcAddr(plbw->hmodSnd,    ORD_PLAYWAVE, NULL,
  167.                  (PFN *)(PVOID)&plbw->pfnPlayWave) )
  168.            {
  169.                /* Ordinal not found within the DLL, release the    */
  170.                /* sound    support    DLL and    clear the module handle    */
  171.                /* to indicate sound events cannot be used    */
  172.  
  173.            DosFreeModule(plbw->hmodSnd);
  174.            plbw->hmodSnd = 0UL;
  175.            }
  176. }
  177. #pragma    subtitle("   Sound Manager - Sound Player Function")
  178. #pragma    page( )
  179.  
  180. /* --- PlaySound --------------------------------------- [ Public ] ---    */
  181. /*                                    */
  182. /*     This function is    used to    play the associated sound if one is    */
  183. /*     defined for an event and    the sound support is present.        */
  184. /*                                    */
  185. /*     Upon Entry:                            */
  186. /*                                    */
  187. /*     PLISTBOXWIN plbw;    = List Box Internal    Data Pointer        */
  188. /*     ULONG       ulSound; = Sound Event                */
  189. /*                                    */
  190. /*     Upon Exit:                            */
  191. /*                                    */
  192. /*     Nothing                                */
  193. /*                                    */
  194. /* --------------------------------------------------------------------    */
  195.  
  196. VOID PlaySound(PLISTBOXWIN plbw, ULONG ulSound)
  197.  
  198. {
  199.                /* Check    to see if the sound file was loaded    */
  200.                /* before trying    to unload it.  When the    handle    */
  201.                /* for the sound    module is 0, then the sound    */
  202.                /* support DLL was not loaded.            */
  203. if ( plbw->hmodSnd )
  204.    switch ( ulSound )
  205.        {
  206.                /* Defining the single click wave file        */
  207.  
  208.        case LSND_SINGLECLICK :
  209.        if (    plbw->ulSClkWAV    )
  210.            plbw->pfnPlayWave(plbw->ulSClkWAV);
  211.        break;
  212.                /* Defining the double click wave file        */
  213.  
  214.        case LSND_DOUBLECLICK :
  215.        if (    plbw->ulDClkWAV    )
  216.            plbw->pfnPlayWave(plbw->ulDClkWAV);
  217.        break;
  218.        }
  219. }
  220. #pragma    subtitle("   Sound Manager - Sound Support Unload Procedure")
  221. #pragma    page( )
  222.  
  223. /* --- UnloadSoundSupport ------------------------------ [ Public ] ---    */
  224. /*                                    */
  225. /*     This function is    used to    release    the loaded sound support DLL.    */
  226. /*                                    */
  227. /*     Upon Entry:                            */
  228. /*                                    */
  229. /*     PLISTBOXWIN plbw; = List    Box Internal Data Pointer        */
  230. /*                                    */
  231. /*     Upon Exit:                            */
  232. /*                                    */
  233. /*     Nothing                                */
  234. /*                                    */
  235. /* --------------------------------------------------------------------    */
  236.  
  237. VOID UnloadSoundSupport(PLISTBOXWIN plbw)
  238.  
  239. {
  240.                /* Check    to see if the sound file was loaded    */
  241.                /* before trying    to unload it.  When the    handle    */
  242.                /* for the sound    module is 0, then the sound    */
  243.                /* support DLL was not loaded.            */
  244. if ( plbw->hmodSnd )
  245.    {
  246.                /* See if the single click wave file was    loaded    */
  247.                /* and if so, close the .WAV file        */
  248.    if (    plbw->ulSClkWAV    )
  249.        plbw->pfnUnloadWave(plbw->hWnd, plbw->ulSClkWAV);
  250.  
  251.                /* See if the double click wave file was    loaded    */
  252.                /* and if so, close the .WAV file        */
  253.  
  254.    if (    plbw->ulDClkWAV    )
  255.        plbw->pfnUnloadWave(plbw->hWnd, plbw->ulDClkWAV);
  256.  
  257.                /* Release the sound support DLL            */
  258.  
  259.    DosFreeModule(plbw->hmodSnd);
  260.    }
  261. }
  262. #pragma    subtitle("   List Manager - List Box Control Data Procedure")
  263. #pragma    page( )
  264.  
  265. /* --- SetControlDataSounds ---------------------------- [ Public ] ---    */
  266. /*                                    */
  267. /*     This function is    used to    decode the control data    that may form    */
  268. /*     part the    of the WM_CREATE message.  The control data is        */
  269. /*     designed    to allow the user to specify a list of wave files that    */
  270. /*     are to be used with the single and double click events.    The    */
  271. /*     first holder is for the single click wave file and the second    */
  272. /*     holder is for the double    click wave file.  If a preceeding wave    */
  273. /*     is not specified, the NULL byte is still    defined    for the    holder.    */
  274. /*     Therefore if the    first holder is    empty and the second holder    */
  275. /*     defines a wave file, the    following would    be the format of the    */
  276. /*     resultant data:                            */
  277. /*                                    */
  278. /*     \0Filename.Wav\0                            */
  279. /*                                    */
  280. /*     The design also allows for only the necessary items to be    */
  281. /*     specified.  For example,    if only    the single click event is    */
  282. /*     to be associated    with a wave file, then only it needs to    be    */
  283. /*     defined within the list and the list count will be 1.  If no    */
  284. /*     items are to be defined within the list,    then a count of    0 is    */
  285. /*     also valid.                            */
  286. /*                                    */
  287. /*     Upon Entry:                            */
  288. /*                                    */
  289. /*     PLISTBOXWIN plbw;    = List Box Internal    Data Pointer        */
  290. /*     ULONG       cItems;  = Items in Control Data List        */
  291. /*     ULONG       cSounds; = Items in Sounds Control Data List        */
  292. /*     PBYTE       pb;        = Control Data Wave    List Pointer        */
  293. /*                                    */
  294. /*     Upon Exit:                            */
  295. /*                                    */
  296. /*     Nothing                                */
  297. /*                                    */
  298. /* --------------------------------------------------------------------    */
  299.  
  300. VOID SetControlDataSounds(PLISTBOXWIN plbw, ULONG cItems, ULONG    cSounds,
  301.               PBYTE    pb)
  302.  
  303. {
  304. HHEAPMEM hHeap;               /* Heap Handle            */
  305. register INT i;               /* Loop Counter            */
  306. register UINT n;           /* Length Holder            */
  307. EXCEPTIONREGISTRATIONRECORD xcptregr;       /* Exception    Record        */
  308.  
  309. if ( !cItems &&    !cSounds )
  310.    return;
  311.                /* Register exception handler that is used for    */
  312.                /* the lazy pointer validation tests        */
  313.  
  314. xcptregr.prev_structure      = NULL;
  315. xcptregr.ExceptionHandler = &ListBoxExceptionHandler;
  316.  
  317. DosSetExceptionHandler(&xcptregr);
  318.  
  319.                /* Set the jump buffer and check    to see if an    */
  320.                /* exception has    occurred in which case ignore    */
  321.                /* the decoding of the control data and return    */
  322. if ( setjmp(jBuf) )
  323.    {
  324.                /* Remove the exception handle since the    lazy    */
  325.                /* pointer evaluation is    done            */
  326.  
  327.    DosUnsetExceptionHandler(&xcptregr);
  328.    return;
  329.    }
  330.  
  331. if ( cItems )
  332.    {
  333.                /* Starting off the list    box from scratch,    */
  334.                /* create the new heap that is to be used for    */
  335.                /* list box.  Allocate the memory needed    for the    */
  336.                /* control information and save the heap    handle    */
  337.                /* within it.                    */
  338.  
  339.    plbw->plc = (PLISTCOL)HeapMalloc(hHeap = HeapAlloc(8192UL, 4096UL), sizeof(LISTCOL));
  340.  
  341.                /* Allocate memory for the initial start    of the    */
  342.                /* list.     The list is allocated in groups of 8,    */
  343.                /* hence    whenever the list total    is a multiple    */
  344.                /* of 8,    the current list is full and needs to    */
  345.                /* be expanded.                    */
  346.  
  347.    plbw->plc[0].apli = (PLISTITEM *)HeapMalloc(plbw->plc[0].hHeap = hHeap,
  348.                            ((cItems    / CBLK_LIST) + 1UL) * CBLK_LIST    * sizeof(PLISTITEM));
  349.  
  350.                /* Set the text of the item being inserted at    */
  351.                /* the end of the list box list and check to see    */
  352.                /* if the item is wider than the    rest in    which    */
  353.                /* case the maximum item    width should be    updated    */
  354.  
  355.    for ( i = 0;    i < cItems; i++    )
  356.        {
  357.        if ( (lSetItemText(plbw->plc[0].hHeap, plbw->hWnd, plbw->plc[0].apli[i],
  358.               pb) >    plbw->cxItem) && (plbw->flStyle    & LS_HORZSCROLL) )
  359.        plbw->cxItem    = plbw->plc[0].apli[i]->cxItem;
  360.        pb += strlen(pb)    + 1;
  361.        }
  362.    }
  363.  
  364. if ( cSounds )
  365.    {
  366.                /* Check    to see if the single click holder a    */
  367.                /* NULL byte which indicates that the single    */
  368.                /* click    event is to be non-associated with a    */
  369.                /* wave file.  When a value is present, get the    */
  370.                /* name of the wave file    and save it internally    */
  371.                /* while    also opening the wave file for usage by    */
  372.                /* the list box control.                */
  373.    if (    pb[0] )
  374.        {
  375.        plbw->ulSClkWAV = plbw->pfnLoadWaveFile(plbw->hWnd,
  376.                            memcpy(plbw->szSClkWAV,
  377.                            pb, n = strlen(pb)));
  378.        pb += n + 1;
  379.        }
  380.    else
  381.        ++pb;
  382.                /* Check    to see if the double click holder a    */
  383.                /* NULL byte which indicates that the double    */
  384.                /* click    event is to be non-associated with a    */
  385.                /* wave file.  When a value is present, get the    */
  386.                /* name of the wave file    and save it internally    */
  387.                /* while    also opening the wave file for usage by    */
  388.                /* the list box control.                */
  389.  
  390.    if (    (cSounds == 2) && pb[0]    )
  391.        plbw->ulDClkWAV = plbw->pfnLoadWaveFile(plbw->hWnd,
  392.                            strcpy(plbw->szDClkWAV,
  393.                               pb));
  394.    }
  395.                /* Remove the exception handle since the    lazy    */
  396.                /* pointer evaluation is    done            */
  397.  
  398. DosUnsetExceptionHandler(&xcptregr);
  399. }
  400. #pragma    subtitle("   Sound Manager - Extended Sound Messages Handler")
  401. #pragma    page( )
  402.  
  403. /* --- mrSoundHandler ---------------------------------- [ Public ] ---    */
  404. /*                                    */
  405. /*     This function is    used to    process    the extended sound messages    */
  406. /*     for the list box    control    window.                    */
  407. /*                                    */
  408. /*     Upon Entry:                            */
  409. /*                                    */
  410. /*     HWND   hWnd; = Window Handle                    */
  411. /*     ULONG  msg;  = PM Message                    */
  412. /*     MPARAM mp1;  = Message Parameter    1                */
  413. /*     MPARAM mp2;  = Message Parameter    2                */
  414. /*                                    */
  415. /*     Upon Exit:                            */
  416. /*                                    */
  417. /*     mrSoundHandler =    Message    Handling Result                */
  418. /*                                    */
  419. /* --------------------------------------------------------------------    */
  420.  
  421. MRESULT    EXPENTRY mrSoundHandler(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  422.  
  423. {
  424. PLISTBOXWIN  plbw;           /* List Box Internal    Data Pointer    */
  425. PSZ         psz;           /* String Pointer            */
  426. ULONG         ul;           /* String Length            */
  427. EXCEPTIONREGISTRATIONRECORD xcptregr;       /* Exception    Record        */
  428.  
  429. plbw = (PLISTBOXWIN)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  430.  
  431. switch ( msg )
  432.    {
  433.  
  434.    /*********************************************************************/
  435.    /*  Extended    message:   LMXM_SETSOUNDEVENT                */
  436.    /*               mp1 = MPFROMLONG(ulSoundEvent);        */
  437.    /*               mp2 = MPFROMP(pszWaveFileName);        */
  438.    /*********************************************************************/
  439.  
  440.    case    LMXM_SETSOUNDEVENT :
  441.        if ( (LONGFROMMP(mp1) > 0L) && PVOIDFROMMP(mp2) && plbw->hmodSnd    )
  442.        {
  443.                /* Register exception handler that is used for    */
  444.                /* the lazy pointer validation tests        */
  445.  
  446.        xcptregr.prev_structure   = NULL;
  447.        xcptregr.ExceptionHandler = &ListBoxExceptionHandler;
  448.  
  449.        DosSetExceptionHandler(&xcptregr);
  450.  
  451.        if (    setjmp(jBuf) )
  452.            {
  453.                /* Remove the exception handle since the    lazy    */
  454.                /* pointer evaluation is    done            */
  455.  
  456.            DosUnsetExceptionHandler(&xcptregr);
  457.            return(MRFROMLONG(TRUE));
  458.            }
  459.                /* Determine which event    is having the wave file    */
  460.                /* defined                    */
  461.  
  462.        switch ( LONGFROMMP(mp1) )
  463.            {
  464.                /* Defining the single click wave file        */
  465.  
  466.            case LSND_SINGLECLICK :
  467.            if (    stricmp(plbw->szSClkWAV, (PSZ)PVOIDFROMMP(mp2))    )
  468.                {
  469.                if ( plbw->ulSClkWAV )
  470.                plbw->pfnUnloadWave(plbw->hWnd, plbw->ulSClkWAV);
  471.                plbw->ulSClkWAV = plbw->pfnLoadWaveFile(plbw->hWnd,
  472.                                    strcpy(plbw->szSClkWAV,
  473.                                       (PSZ)PVOIDFROMMP(mp2)));
  474.                }
  475.            break;
  476.  
  477.                /* Defining the double click wave file        */
  478.  
  479.            case LSND_DOUBLECLICK :
  480.            if (    stricmp(plbw->szDClkWAV, (PSZ)PVOIDFROMMP(mp2))    )
  481.                {
  482.                if ( plbw->ulDClkWAV )
  483.                plbw->pfnUnloadWave(plbw->hWnd, plbw->ulDClkWAV);
  484.                plbw->ulDClkWAV = plbw->pfnLoadWaveFile(plbw->hWnd,
  485.                                    strcpy(plbw->szDClkWAV,
  486.                                       (PSZ)PVOIDFROMMP(mp2)));
  487.                }
  488.            break;
  489.  
  490.            default :
  491.                /* Remove the exception handle since the    lazy    */
  492.                /* pointer evaluation is    done            */
  493.  
  494.            DosUnsetExceptionHandler(&xcptregr);
  495.            return(MRFROMLONG(TRUE));
  496.            }
  497.                /* Remove the exception handle since the    lazy    */
  498.                /* pointer evaluation is    done            */
  499.  
  500.        DosUnsetExceptionHandler(&xcptregr);
  501.        }
  502.        else
  503.        return(MRFROMLONG(TRUE));
  504.        break;
  505.  
  506.    /*********************************************************************/
  507.    /*  Extended    message:   LMXM_QUERYSOUNDEVENT                */
  508.    /*               mp1 = MPFROMLONG(ulSoundEvent);        */
  509.    /*               mp2 = MPFROMP(pszWaveFileName);        */
  510.    /*********************************************************************/
  511.  
  512.    case    LMXM_QUERYSOUNDEVENT :
  513.        if ( (LONGFROMMP(mp1) > 0L) && PVOIDFROMMP(mp2) && plbw->hmodSnd    )
  514.        {
  515.                /* Register exception handler that is used for    */
  516.                /* the lazy pointer validation tests        */
  517.  
  518.        xcptregr.prev_structure   = NULL;
  519.        xcptregr.ExceptionHandler = &ListBoxExceptionHandler;
  520.  
  521.        DosSetExceptionHandler(&xcptregr);
  522.  
  523.        if (    setjmp(jBuf) )
  524.            {
  525.                /* Remove the exception handle since the    lazy    */
  526.                /* pointer evaluation is    done            */
  527.  
  528.            DosUnsetExceptionHandler(&xcptregr);
  529.            return(0L);
  530.            }
  531.  
  532.        switch ( LONGFROMMP(mp1) )
  533.            {
  534.                /* Querying the single click wave file        */
  535.  
  536.            case LSND_SINGLECLICK :
  537.            if (    plbw->ulSClkWAV    )
  538.                ul = strlen(strcpy((PSZ)PVOIDFROMMP(mp2), plbw->szSClkWAV));
  539.            else
  540.                {
  541.                psz = (PSZ)PVOIDFROMMP(mp2);
  542.                psz[0] =    0;
  543.                ul = 0UL;
  544.                }
  545.            break;
  546.  
  547.                /* Querying the double click wave file        */
  548.  
  549.            case LSND_DOUBLECLICK :
  550.            if (    plbw->ulSClkWAV    )
  551.                ul = strlen(strcpy((PSZ)PVOIDFROMMP(mp2), plbw->szDClkWAV));
  552.            else
  553.                {
  554.                psz = (PSZ)PVOIDFROMMP(mp2);
  555.                psz[0] =    0;
  556.                ul = 0UL;
  557.                }
  558.            break;
  559.  
  560.            default :
  561.                /* Remove the exception handle since the    lazy    */
  562.                /* pointer evaluation is    done            */
  563.  
  564.            DosUnsetExceptionHandler(&xcptregr);
  565.            return(0L);
  566.            }
  567.                /* Remove the exception handle since the    lazy    */
  568.                /* pointer evaluation is    done            */
  569.  
  570.        DosUnsetExceptionHandler(&xcptregr);
  571.        return(MRFROMLONG(ul));
  572.        }
  573.        else
  574.        return(0L);
  575.    }
  576. return(0L);
  577. }
  578.