home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / FILEDLG6.ZIP / SOURCE.ZIP / OPENDLG.C < prev    next >
C/C++ Source or Header  |  1990-11-14  |  36KB  |  796 lines

  1. /****************************************************************************
  2.  * OPENDLG.C - Open File dialog box routines.                               *
  3.  *                                                                          *
  4.  *  Modifications -                                                         *
  5.  *      11-Aug-1989 : Initial version.                                      *
  6.  *      07-Sep-1989 : Added file find function.                             *
  7.  *      21-Sep-1989 : Cleaned up code to make it a little more readable.    *
  8.  *                    Separated open file and find file dialog procedures   *
  9.  *                      into separate files.                                *
  10.  *                    Forced OPEN button to be default button whenever      *
  11.  *                      the focus passes to a non-pushbutton control.       *
  12.  *                    Eliminated duplicate error messages when enter key    *
  13.  *                      is used to select a list box item.                  *
  14.  *      11-Oct-1989 : Changed to DLL version of ErrMessageBox function.     *
  15.  *      19-Nov-1989 : Fixed bug causing protection violation when the       *
  16.  *                    pszSearchSpec string is located in a read-only        *
  17.  *                    segment.                                              *
  18.  *      11-Oct-1990 : Added long filename support.                          *
  19.  *                    Eliminated ResetDefaultButton function as OS/2 1.21   *
  20.  *                    fixed the bug that rendered it necessary.             *
  21.  *      02-Nov-1990 : Added workaround to eliminate the listing of the      *
  22.  *                    ".." directory in the directory list box when the     *
  23.  *                    current directory is the root. This is needed         *
  24.  *                    because on HPFS drives, ".." is returned as one of    *
  25.  *                    the subdirectories of the root.                       *
  26.  *      14-Nov-1990 : Eliminated bug causing internally stored current      *
  27.  *                      directory to sometimes get out of synch with        *  *
  28.  *                      actual value when an error occurred while opening   *  *
  29.  *                      a file.                                             *
  30.  *                    Disabled hard-error processing while executing        *
  31.  *                      FileOpenDlg functions.                              *
  32.  *                    Added ability to suppress display of error messages   *
  33.  *                      for errors that occur in FillListBoxes().           *
  34.  *                                                                          *
  35.  *                                                                          *
  36.  * (c)Copyright 1990 Rick Yoder                                             *
  37.  ****************************************************************************/
  38.  
  39.     #define INCL_WIN
  40.     #define INCL_DOS
  41.     #define INCL_DOSERRORS
  42.     #define INCL_GPIBITMAPS
  43.     #define INCL_GPIPRIMITIVES
  44.     #include <os2.h>
  45.  
  46.     #include <string.h>
  47.     #include <errmsg.h>
  48.  
  49.     #include "filedlg.h"
  50.     #include "dialog.h"
  51.     #define INCL_ARROWS
  52.     #include "tools.h"
  53.     #include "static.h"
  54.     #include "opendata.h"   // definition of structure holding dialog box
  55.                             //  static data (DATA & PDATA types).
  56.  
  57. /****************************************************************************
  58.  *  Procedure declarations                                                  *
  59.  ****************************************************************************/
  60.     /* Open file dialog box procedures */
  61.     MRESULT EXPENTRY _OpenDlgProc( HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2 );
  62.     static MRESULT NEAR OpenInit( HWND hwnd,MPARAM mp2 );
  63.     static MRESULT NEAR DriveListbox( HWND hwnd,USHORT msg,
  64.                                       MPARAM mp1,MPARAM mp2 );
  65.     static MRESULT NEAR DirListbox( HWND hwnd,USHORT msg,
  66.                                     MPARAM mp1,MPARAM mp2 );
  67.     static MRESULT NEAR FileListbox( HWND hwnd,USHORT msg,
  68.                                      MPARAM mp1,MPARAM mp2 );
  69.     static MRESULT NEAR FnameEditCtrl( HWND hwnd,USHORT msg,
  70.                                        MPARAM mp1,MPARAM mp2 );
  71.     static MRESULT NEAR OpenButton( HWND hwnd,PDATA pData );
  72.     static VOID NEAR FillListBoxes( HWND hDlg,PDATA pData,BOOL fError );
  73.     static USHORT NEAR OpenFile( HWND hDlg,PDATA pData );
  74.  
  75.     /* Find file dialog box procedures */
  76.     extern MRESULT EXPENTRY _FindDlgProc( HWND hwnd,USHORT msg,
  77.                                           MPARAM mp1,MPARAM mp2 );
  78. /****************************************************************************/
  79.  
  80.  
  81. /****************************************************************************
  82.  *  FileOpenDlg()                                                           *
  83.  ****************************************************************************/
  84.     USHORT EXPENTRY FileOpenDlg( HWND hwndOwner,
  85.                                  PSZ pszTitle,PSZ pszIns,
  86.                                  PSZ pszShowSpec,USHORT usShowAttr,
  87.                                  void (EXPENTRY *pfnHelpProc)(HWND hDlg),
  88.                                  PSZ pszFile,
  89.                                  PHFILE phf,
  90.                                  ULONG ulFileSize,
  91.                                  PUSHORT pusAction,
  92.                                  USHORT usAttribute,
  93.                                  USHORT fsOpenFlags,
  94.                                  USHORT fsOpenMode,
  95.                                  ULONG ulReserved )
  96.     {
  97.         USHORT  usMaxPathLen;
  98.         SEL     sel;
  99.         PDATA   pData;
  100.         USHORT  rc;
  101.         HMODULE hmod = 0;
  102.  
  103.     /* Disable hard-error processing */
  104.         DosError( HARDERROR_DISABLE );
  105.  
  106.     /* Set pszTitle and pszIns to default if NULL */
  107.         if ( pszTitle == NULL ) pszTitle = szDefOpenTitle;
  108.         if ( pszIns == NULL ) pszIns = szDefOpenIns;
  109.  
  110.     /* Get maximum pathname length */
  111.         DosQSysInfo( 0,(PBYTE)&usMaxPathLen,sizeof(USHORT) );
  112.  
  113.     /* Get module handle for FILEDLG dynamic-link library
  114.      *  Note: Remove this code section if the file dialog box
  115.      *        resources are not located in a dynamic-link library.
  116.      */
  117.         if ( (rc = DosGetModHandle(szDLLName,&hmod)) )
  118.             {
  119.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  120.             rc = FDLG_CANCEL;
  121.             goto EXIT;
  122.             }
  123.  
  124.     /* Allocate memory for dialog data */
  125.         if ( (rc = DosAllocSeg(sizeof(DATA),&sel,SEG_NONSHARED)) )
  126.             {
  127.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  128.             rc = FDLG_CANCEL;
  129.             goto EXIT;
  130.             }
  131.         pData = MAKEP(sel,0);
  132.  
  133.     /* Allocate memory for search spec */
  134.         if ( (rc = DosAllocSeg(usMaxPathLen,&sel,SEG_NONSHARED)) )
  135.             {
  136.             DosFreeSeg( SELECTOROF(pData) );
  137.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  138.             rc = FDLG_CANCEL;
  139.             goto EXIT;
  140.             }
  141.         pData->pszShowSpec = MAKEP(sel,0);
  142.  
  143.     /* Allocate scratch data area */
  144.         if ( (rc = DosAllocSeg(usMaxPathLen+3,&sel,SEG_NONSHARED)) )
  145.             {
  146.             DosFreeSeg( SELECTOROF(pData->pszShowSpec) );
  147.             DosFreeSeg( SELECTOROF(pData) );
  148.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  149.             rc = FDLG_CANCEL;
  150.             goto EXIT;
  151.             }
  152.         pData->pszScratch = MAKEP(sel,0);
  153.  
  154.     /* Allocate storage for current directory string */
  155.         if ( (rc = DosAllocSeg(usMaxPathLen+3,&sel,SEG_NONSHARED)) )
  156.             {
  157.             DosFreeSeg( SELECTOROF(pData->pszShowSpec) );
  158.             DosFreeSeg( SELECTOROF(pData->pszScratch) );
  159.             DosFreeSeg( SELECTOROF(pData) );
  160.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  161.             rc = FDLG_CANCEL;
  162.             goto EXIT;
  163.             }
  164.         pData->pszCurDir = MAKEP(sel,0);
  165.  
  166.     /* Set current drive and directory to drive and directory listed   */
  167.     /* in show file specification, and store filename portion of spec. */
  168.         strcpy( pData->pszShowSpec,pszShowSpec );
  169.         if ( rc = ParseFileName(pData->pszShowSpec,
  170.                                 pData->pszScratch,
  171.                                 szStarDotStar) )
  172.             {
  173.             ErrMessageBox( hwndOwner,pszTitle,rc,NULL,0 );
  174.             strcpy( pData->pszShowSpec,szStarDotStar );
  175.             }
  176.         else
  177.             strcpy( pData->pszShowSpec,strrchr(pData->pszScratch,'\\')+1 );
  178.  
  179.     /* Initialize contents of dialog box data structure */
  180.         pData->pszTitle         = pszTitle;
  181.         pData->pszIns           = pszIns;
  182.         pData->pfnHelpProc      = pfnHelpProc;
  183.         pData->pszFile          = pszFile;
  184.         pData->phf              = phf;
  185.         pData->ulFileSize       = ulFileSize;
  186.         pData->pusAction        = pusAction;
  187.         pData->usAttribute      = usAttribute;
  188.         pData->fsOpenFlags      = fsOpenFlags;
  189.         pData->fsOpenMode       = fsOpenMode;
  190.         pData->ulReserved       = ulReserved;
  191.         pData->usShowAttr       = usShowAttr;
  192.         pData->usMaxPathLen     = usMaxPathLen;
  193.         pData->hmod             = hmod;
  194.         pData->usFocus          = OPEN_FNAME;
  195.         pData->iFirstChar       = 0;
  196.         pData->hbmLeft          = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBLFARROW);
  197.         pData->hbmLeftPressed   = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBLFARROWDEP);
  198.         pData->hbmLeftDisabled  = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBLFARROWDIS);
  199.         pData->hbmRight         = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBRGARROW);
  200.         pData->hbmRightPressed  = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBRGARROWDEP);
  201.         pData->hbmRightDisabled = WinGetSysBitmap(HWND_DESKTOP,SBMP_SBRGARROWDIS);
  202.  
  203.     /* Activate open file dialog box */
  204.         rc = WinDlgBox( HWND_DESKTOP,hwndOwner,_OpenDlgProc,
  205.                         hmod,IDD_OPEN,pData );
  206.  
  207.     /* Free resources */
  208.         GpiDeleteBitmap( pData->hbmLeft );
  209.         GpiDeleteBitmap( pData->hbmLeftPressed );
  210.         GpiDeleteBitmap( pData->hbmLeftDisabled );
  211.         GpiDeleteBitmap( pData->hbmRight );
  212.         GpiDeleteBitmap( pData->hbmRightPressed );
  213.         GpiDeleteBitmap( pData->hbmRightDisabled );
  214.         DosFreeSeg( SELECTOROF(pData->pszShowSpec) );
  215.         DosFreeSeg( SELECTOROF(pData->pszScratch) );
  216.         DosFreeSeg( SELECTOROF(pData) );
  217.  
  218.     /* Re-enable hard error processing and return */
  219. EXIT:   DosError( HARDERROR_ENABLE );
  220.         return rc;
  221.     }
  222. /****************************************************************************/
  223.  
  224.  
  225. /****************************************************************************
  226.  * _OpenDlgProc()                                                           *
  227.  ****************************************************************************/
  228.     MRESULT EXPENTRY _OpenDlgProc( HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2 )
  229.     {
  230.         PDATA   pData;
  231.  
  232.         switch ( msg ) {
  233.             case WM_INITDLG:
  234.                 return OpenInit( hwnd,mp2 );
  235.  
  236.             case WM_CONTROL:
  237.                 switch ( SHORT1FROMMP(mp1) ) {
  238.                     case OPEN_DRIVES:
  239.                         return DriveListbox( hwnd,msg,mp1,mp2 );
  240.  
  241.                     case OPEN_DIRLIST:
  242.                         return DirListbox( hwnd,msg,mp1,mp2 );
  243.  
  244.                     case OPEN_FILELIST:
  245.                         return FileListbox( hwnd,msg,mp1,mp2 );
  246.  
  247.                     case OPEN_FNAME:
  248.                         return FnameEditCtrl( hwnd,msg,mp1,mp2 );
  249.  
  250.                     case OPEN_LEFTARROW:
  251.                         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  252.                         return LeftArrow( hwnd,msg,mp1,mp2,
  253.                                           pData->hbmLeft,
  254.                                           pData->hbmLeftPressed,
  255.                                           pData->hbmLeftDisabled );
  256.  
  257.                     case OPEN_RIGHTARROW:
  258.                         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  259.                         return RightArrow( hwnd,msg,mp1,mp2,
  260.                                            pData->hbmRight,
  261.                                            pData->hbmRightPressed,
  262.                                            pData->hbmRightDisabled );
  263.                     }
  264.                 break;
  265.  
  266.             case WM_COMMAND:
  267.                 pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  268.                 switch (COMMANDMSG(&msg)->cmd) {
  269.                     case OPEN_OK:
  270.                         return OpenButton( hwnd,pData );
  271.  
  272.                     case DID_CANCEL:
  273.                     case OPEN_CANCEL:
  274.                         WinDismissDlg( hwnd,FDLG_CANCEL );
  275.                         return 0L;
  276.  
  277.                     case OPEN_FIND:
  278.                         if ( FDLG_OK == WinDlgBox(HWND_DESKTOP,hwnd,
  279.                                                   _FindDlgProc,pData->hmod,
  280.                                                   IDD_FIND,pData) )
  281.                             WinDismissDlg( hwnd,FDLG_OK );
  282.                         else
  283.                             WinSetFocus( HWND_DESKTOP,
  284.                                          WinWindowFromID(hwnd,OPEN_FNAME) );
  285.                         return 0L;
  286.  
  287.                     case OPEN_LEFTARROW:
  288.                         if ( pData->iFirstChar == 0 )
  289.                             WinAlarm( HWND_DESKTOP,WA_ERROR );
  290.                         else
  291.                             {
  292.                             pData->iFirstChar--;
  293.                             WinSetDlgItemText( hwnd,OPEN_CURDIR,
  294.                                                &pData->pszCurDir[pData->iFirstChar] );
  295.                             }
  296.                         return 0L;
  297.  
  298.                     case OPEN_RIGHTARROW:
  299.                         {
  300.                         size_t len = strlen(pData->pszCurDir);
  301.  
  302.                         if ( len == 0 || pData->iFirstChar == len-1 )
  303.                             WinAlarm( HWND_DESKTOP,WA_ERROR );
  304.                         else
  305.                             {
  306.                             pData->iFirstChar++;
  307.                             WinSetDlgItemText( hwnd,OPEN_CURDIR,
  308.                                                &pData->pszCurDir[pData->iFirstChar] );
  309.                             }
  310.                         return 0L;
  311.                         }
  312.                     }
  313.                 break;
  314.  
  315.             case WM_HELP:
  316.                 pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  317.                 if ( pData->pfnHelpProc != NULL )
  318.                     {
  319.                     (*pData->pfnHelpProc)( hwnd );
  320.                     return 0L;
  321.                     }
  322.                 break;
  323.             }
  324.         return WinDefDlgProc( hwnd,msg,mp1,mp2 );
  325.     }
  326. /****************************************************************************/
  327.  
  328.  
  329. /****************************************************************************
  330.  * OpenInit() -- Process WM_INITDLG message for the open file dialog        *
  331.  *               box.                                                       *
  332.  ****************************************************************************/
  333.     static MRESULT near OpenInit( HWND hwnd,MPARAM mp2 )
  334.     {
  335.         PDATA pData;
  336.  
  337.         pData = PVOIDFROMMP( mp2 );
  338.         WinSetWindowULong( hwnd,QWL_USER,(ULONG)pData );
  339.         if ( pData->pfnHelpProc == NULL )
  340.             WinDestroyWindow( WinWindowFromID(hwnd,OPEN_HELP) );
  341.         WinSetWindowText( WinWindowFromID(hwnd,FID_TITLEBAR),pData->pszTitle );
  342.         WinSetDlgItemText( hwnd,OPEN_HLPTEXT,pData->pszIns );
  343.         WinSendDlgItemMsg( hwnd,OPEN_FNAME,EM_SETTEXTLIMIT,
  344.                            MPFROMSHORT(pData->usMaxPathLen),NULL );
  345.         FillListBoxes( hwnd,pData,TRUE );
  346.         return 0L;
  347.     }
  348. /****************************************************************************/
  349.  
  350.  
  351. /****************************************************************************
  352.  * DriveListbox() -- Handle messages sent by the disk drive list box to     *
  353.  *                   the open file dialog.                                  *
  354.  ****************************************************************************/
  355.     static MRESULT near DriveListbox( HWND hwnd,USHORT msg,
  356.                                       MPARAM mp1,MPARAM mp2 )
  357.     {
  358.         PDATA   pData;
  359.         USHORT  usResult;
  360.  
  361.         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  362.         switch ( SHORT2FROMMP(mp1) ) {
  363.             case LN_ENTER:
  364.                 pData->usFocus = OPEN_DRIVES;
  365.                 WinSendDlgItemMsg( hwnd,OPEN_DRIVES,LM_QUERYITEMTEXT,
  366.                                    MPFROM2SHORT(pData->usSelectDrive,pData->usMaxPathLen),
  367.                                    MPFROMP(pData->pszScratch) );
  368.                 usResult = DosSelectDisk(pData->pszScratch[0]-'@');
  369.                 if ( usResult )
  370.                     ErrMessageBox( hwnd,pData->pszTitle,usResult,NULL,0 );
  371.                 else
  372.                     WinSendDlgItemMsg( hwnd,OPEN_OK,BM_CLICK,0L,0L );
  373.                 WinSendDlgItemMsg( hwnd,OPEN_DRIVES,LM_SELECTITEM,
  374.                                    MPFROMSHORT(pData->usSelectDrive),
  375.                                    MPFROMSHORT(TRUE) );
  376.                 return 0L;
  377.  
  378.             case LN_SETFOCUS:
  379.                 usResult = SHORT1FROMMR( WinSendDlgItemMsg(hwnd,OPEN_DRIVES,
  380.                                                            LM_QUERYTOPINDEX,
  381.                                                            0L,0L)
  382.                                        );
  383.                 if ( usResult != LIT_NONE )
  384.                     {
  385.                     if ( pData->usSelectDrive < usResult )
  386.                         pData->usSelectDrive = usResult;
  387.                     else if (pData->usSelectDrive > usResult+5)
  388.                         pData->usSelectDrive = usResult+5;
  389.  
  390.                     WinSendDlgItemMsg( hwnd,OPEN_DRIVES,LM_SELECTITEM,
  391.                                        MPFROMSHORT(pData->usSelectDrive),
  392.                                        MPFROMSHORT(TRUE) );
  393.                     }
  394.                 return 0L;
  395.  
  396.             case LN_KILLFOCUS:
  397.                 WinSendDlgItemMsg( hwnd,OPEN_DRIVES,LM_SELECTITEM,
  398.                                    MPFROMSHORT(pData->usSelectDrive),
  399.                                    MPFROMSHORT(FALSE) );
  400.                 return 0L;
  401.  
  402.             case LN_SELECT:
  403.                 usResult = SHORT1FROMMR( WinSendDlgItemMsg(hwnd,OPEN_DRIVES,
  404.                                                            LM_QUERYSELECTION,
  405.                                                            0L,0L)
  406.                                        );
  407.                 if ( usResult != LIT_NONE ) pData->usSelectDrive = usResult;
  408.                 return 0L;
  409.             }
  410.  
  411.         return WinDefDlgProc( hwnd,msg,mp1,mp2 );
  412.     }
  413. /****************************************************************************/
  414.  
  415.  
  416. /****************************************************************************
  417.  * DirListbox() -- Handle messages sent by directory list box to the        *
  418.  *                 open file dialog.                                        *
  419.  ****************************************************************************/
  420.     static MRESULT near DirListbox( HWND hwnd,USHORT msg,
  421.                                     MPARAM mp1,MPARAM mp2 )
  422.     {
  423.         PDATA  pData;
  424.         USHORT usResult;
  425.  
  426.         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  427.         switch ( SHORT2FROMMP(mp1) ) {
  428.             case LN_ENTER:
  429.                 pData->usFocus = OPEN_DIRLIST;
  430.                 WinSendDlgItemMsg( hwnd,OPEN_DIRLIST,
  431.                                    LM_QUERYITEMTEXT,
  432.                                    MPFROM2SHORT(pData->usSelectDir,pData->usMaxPathLen),
  433.                                    MPFROMP(pData->pszScratch) );
  434.                 usResult = DosChDir(pData->pszScratch,0L);
  435.                 if ( usResult )
  436.                     ErrMessageBox( hwnd,pData->pszTitle,usResult,NULL,0 );
  437.                 else
  438.                     WinSendDlgItemMsg( hwnd,OPEN_OK,BM_CLICK,0L,0L );
  439.                 WinSendDlgItemMsg( hwnd,OPEN_DIRLIST,LM_SELECTITEM,
  440.                                    MPFROMSHORT(pData->usSelectDir),
  441.                                    MPFROMSHORT(TRUE) );
  442.                 return 0L;
  443.  
  444.             case LN_SETFOCUS:
  445.                 usResult = SHORT1FROMMR(WinSendDlgItemMsg(hwnd,OPEN_DIRLIST,
  446.                                                           LM_QUERYTOPINDEX,
  447.                                                           0L,0L)
  448.                                        );
  449.                 if ( usResult != LIT_NONE )
  450.                     {
  451.                     if ( pData->usSelectDir < usResult )
  452.                         pData->usSelectDir = usResult;
  453.                     else if (pData->usSelectDir > usResult+4)
  454.                         pData->usSelectDir = usResult+4;
  455.  
  456.                     WinSendDlgItemMsg( hwnd,OPEN_DIRLIST,LM_SELECTITEM,
  457.                                        MPFROMSHORT(pData->usSelectDir),
  458.                                        MPFROMSHORT(TRUE) );
  459.                     }
  460.                 return 0L;
  461.  
  462.             case LN_KILLFOCUS:
  463.                 WinSendDlgItemMsg( hwnd,OPEN_DIRLIST,LM_SELECTITEM,
  464.                                    MPFROMSHORT(pData->usSelectDir),
  465.                                    MPFROMSHORT(FALSE) );
  466.                 return 0L;
  467.  
  468.             case LN_SELECT:
  469.                 usResult = SHORT1FROMMR( WinSendDlgItemMsg(hwnd,OPEN_DIRLIST,
  470.                                                            LM_QUERYSELECTION,
  471.                                                            0L,0L)
  472.                                        );
  473.                 if ( usResult != LIT_NONE ) pData->usSelectDir = usResult;
  474.                 return 0L;
  475.             }
  476.  
  477.         return WinDefDlgProc( hwnd,msg,mp1,mp2 );
  478.     }
  479. /****************************************************************************/
  480.  
  481.  
  482. /****************************************************************************
  483.  * FileListbox() -- Handle messages sent by file list box the open dialog.  *
  484.  ****************************************************************************/
  485.     static MRESULT near FileListbox( HWND hwnd,USHORT msg,
  486.                                      MPARAM mp1,MPARAM mp2 )
  487.     {
  488.         PDATA  pData;
  489.         USHORT usResult;
  490.  
  491.         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  492.         switch ( SHORT2FROMMP(mp1) ) {
  493.             case LN_SELECT:
  494.                 usResult = SHORT1FROMMR( WinSendDlgItemMsg(hwnd,OPEN_FILELIST,
  495.                                                            LM_QUERYSELECTION,
  496.                                                            0L,0L)
  497.                                        );
  498.                 if ( usResult != LIT_NONE ) pData->usSelectFile = usResult;
  499.                 WinSendDlgItemMsg( hwnd,OPEN_FILELIST,
  500.                                    LM_QUERYITEMTEXT,
  501.                                    MPFROM2SHORT(pData->usSelectFile,pData->usMaxPathLen),
  502.                                    MPFROMP(pData->pszScratch) );
  503.                 WinSetDlgItemText( hwnd,OPEN_FNAME,
  504.                                    pData->pszScratch );
  505.                 return 0L;
  506.  
  507.             case LN_ENTER:
  508.                 pData->usFocus = OPEN_FILELIST;
  509.                 WinSendDlgItemMsg( hwnd,OPEN_FILELIST,
  510.                                    LM_QUERYITEMTEXT,
  511.                                    MPFROM2SHORT(pData->usSelectFile,pData->usMaxPathLen),
  512.                                    MPFROMP(pData->pszScratch) );
  513.                 WinSetDlgItemText( hwnd,OPEN_FNAME,pData->pszScratch );
  514.                 WinSendDlgItemMsg( hwnd,OPEN_OK,BM_CLICK,0L,0L );
  515.                 return 0L;
  516.  
  517.             case LN_SETFOCUS:
  518.                 usResult = SHORT1FROMMR( WinSendDlgItemMsg(hwnd,OPEN_FILELIST,
  519.                                                            LM_QUERYTOPINDEX,
  520.                                                            0L,0L)
  521.                                        );
  522.                 if ( usResult != LIT_NONE )
  523.                     {
  524.                     if ( pData->usSelectFile < usResult )
  525.                         pData->usSelectFile = usResult;
  526.                     else if (pData->usSelectFile > usResult+7)
  527.                         pData->usSelectFile = usResult+7;
  528.  
  529.                     WinSendDlgItemMsg( hwnd,OPEN_FILELIST,LM_SELECTITEM,
  530.                                        MPFROMSHORT(pData->usSelectFile),
  531.                                        MPFROMSHORT(TRUE) );
  532.                     }
  533.                 return 0L;
  534.  
  535.             case LN_KILLFOCUS:
  536.                 WinSendDlgItemMsg( hwnd,OPEN_FILELIST,LM_SELECTITEM,
  537.                                    MPFROMSHORT(pData->usSelectFile),
  538.                                    MPFROMSHORT(FALSE) );
  539.                 return 0L;
  540.             }
  541.  
  542.         return WinDefDlgProc( hwnd,msg,mp1,mp2 );
  543.     }
  544. /****************************************************************************/
  545.  
  546.  
  547. /****************************************************************************
  548.  * FnameEditCtrl() -- Handles messages sent by OPEN_FNAME edit control      *
  549.  *                    to open file dialog box.                              *
  550.  ****************************************************************************/
  551.     static MRESULT near FnameEditCtrl( HWND hwnd,USHORT msg,
  552.                                        MPARAM mp1,MPARAM mp2 )
  553.     {
  554.         USHORT usResult;
  555.         PDATA  pData;
  556.  
  557.         pData = (PDATA)WinQueryWindowULong( hwnd,QWL_USER );
  558.  
  559.         if ( SHORT2FROMMP(mp1) == EN_SETFOCUS )
  560.             {
  561.             usResult = WinQueryDlgItemTextLength( hwnd,OPEN_FNAME );
  562.             WinSendDlgItemMsg( hwnd,OPEN_FNAME,EM_SETSEL,
  563.                                MPFROM2SHORT(0,usResult),0L );
  564.             return 0L;
  565.             }
  566.  
  567.         return WinDefDlgProc( hwnd,msg,mp1,mp2 );
  568.     }
  569. /****************************************************************************/
  570.  
  571.  
  572. /****************************************************************************
  573.  * OpenButton() - Procedure to executed when OPEN button is clicked.        *
  574.  ****************************************************************************/
  575.     static MRESULT near OpenButton( HWND hwnd,PDATA pData )
  576.     {
  577.         USHORT      usDriveNum;
  578.         ULONG       ulMap;
  579.         USHORT      usCount;
  580.         HWND        hwndButton;
  581.  
  582.         hwndButton = WinWindowFromID( hwnd,OPEN_OK );
  583.  
  584.         if ( hwndButton == WinQueryFocus(HWND_DESKTOP,FALSE) )
  585.             {
  586.             switch ( pData->usFocus ) {
  587.                 case OPEN_FNAME:
  588.                 case OPEN_FILELIST:
  589.                     WinQueryDlgItemText( hwnd,OPEN_FNAME,
  590.                                          pData->usMaxPathLen,
  591.                                          pData->pszScratch );
  592.                     if ( OpenFile(hwnd,pData) )
  593.                         {
  594.                         DosQCurDisk( &usDriveNum,&ulMap );
  595.                         pData->pszScratch[0] = (CHAR)( usDriveNum + '@' );
  596.                         pData->pszScratch[1] = ':';
  597.                         pData->pszScratch[2] = '\\';
  598.                         pData->pszScratch[3] = 0;
  599.                         usCount = pData->usMaxPathLen-3;
  600.                         DosQCurDir(0,pData->pszScratch+3,&usCount);
  601.                         if ( 0 != stricmp(pData->pszScratch,pData->pszCurDir) )
  602.                             FillListBoxes( hwnd,pData,FALSE );
  603.                         }
  604.                     else
  605.                         WinDismissDlg( hwnd,FDLG_OK );
  606.                     break;
  607.  
  608.                 case OPEN_DRIVES:
  609.                 case OPEN_DIRLIST:
  610.                     FillListBoxes( hwnd,pData,TRUE );
  611.                     break;
  612.                 }
  613.             WinSetFocus( HWND_DESKTOP,WinWindowFromID(hwnd,pData->usFocus) );
  614.             pData->usFocus = OPEN_FNAME;
  615.             }
  616.  
  617.         return 0L;
  618.     }
  619. /****************************************************************************/
  620.  
  621.  
  622. /****************************************************************************
  623.  * FillListBoxes() - Fill drive, directory, and file list boxes, and        *
  624.  *                   display the name of the current drive and directory    *
  625.  *                   in the OPEN_CURDIR control.                            *
  626.  *                                                                          *
  627.  *                   This function uses the scratch data area.              *
  628.  ****************************************************************************/
  629.     static void near FillListBoxes( HWND hDlg,PDATA pData,BOOL fError )
  630.     {
  631.         USHORT      usDriveNum;
  632.         ULONG       ulMap;
  633.         USHORT      usResult;
  634.         HDIR        hdir;
  635.         FILEFINDBUF findbuf;
  636.         USHORT      usCount;
  637.  
  638.     /* Clear current contents of list boxes and text controls */
  639.         WinSendDlgItemMsg( hDlg,OPEN_DRIVES,LM_DELETEALL,NULL,NULL );
  640.         WinSendDlgItemMsg( hDlg,OPEN_DIRLIST,LM_DELETEALL,NULL,NULL );
  641.         WinSendDlgItemMsg( hDlg,OPEN_FILELIST,LM_DELETEALL,NULL,NULL );
  642.         WinSetDlgItemText( hDlg,OPEN_CURDIR,"" );
  643.         WinSetDlgItemText( hDlg,OPEN_FNAME,pData->pszShowSpec );
  644.  
  645.         pData->usSelectDrive = 0;
  646.         pData->usSelectDir   = 0;
  647.         pData->usSelectFile  = 0;
  648.         pData->pszCurDir[0]  = 0;
  649.         pData->iFirstChar    = 0;
  650.  
  651.     /* Fill in disk drive list box */
  652.         if ( usResult = DosQCurDisk(&usDriveNum,&ulMap) )
  653.             {
  654.             if ( fError ) ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  655.             return;
  656.             }
  657.  
  658.         pData->pszScratch[1] = ':';
  659.         pData->pszScratch[2] = '\0';
  660.         for ( usCount = 0; usCount < 26; usCount++ )
  661.             if ( ulMap & 1L << usCount )
  662.                 {
  663.                 pData->pszScratch[0] = (CHAR)( usCount + 'A' );
  664.  
  665.                 usResult = SHORT1FROMMR(
  666.                             WinSendDlgItemMsg( hDlg,OPEN_DRIVES,
  667.                                                LM_INSERTITEM,
  668.                                                MPFROMSHORT(LIT_END),
  669.                                                MPFROMP(pData->pszScratch) )
  670.                                        );
  671.                 if ( usCount == usDriveNum-1 )
  672.                     {
  673.                     WinSendDlgItemMsg( hDlg,OPEN_DRIVES,
  674.                                        LM_SETTOPINDEX,
  675.                                        MPFROMSHORT(usResult),
  676.                                        0L );
  677.                     pData->usSelectDrive = usResult;
  678.                     }
  679.                 }
  680.  
  681.     /* Set OPEN_CURDIR static text control to current drive/directory */
  682.         pData->pszCurDir[0] = (CHAR)( usDriveNum + '@' );
  683.         pData->pszCurDir[1] = ':';
  684.         pData->pszCurDir[2] = '\\';
  685.         pData->pszCurDir[3] = 0;
  686.         usCount = pData->usMaxPathLen-3;
  687.         usResult = DosQCurDir(0,pData->pszCurDir+3,&usCount);
  688.         WinSetDlgItemText( hDlg,OPEN_CURDIR,pData->pszCurDir );
  689.         if ( usResult )
  690.             {
  691.             if ( fError ) ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  692.             return;
  693.             }
  694.  
  695.     /* Fill list box with subdirectories of current directory */
  696.         hdir    = HDIR_CREATE;
  697.         usCount = 1;
  698.         usResult = DosFindFirst( szStarDotStar,&hdir,FILE_DIRECTORY,&findbuf,
  699.                                   sizeof(findbuf),&usCount,0L );
  700.  
  701.         while ( !usResult )
  702.             {
  703.             if (   (findbuf.attrFile & FILE_DIRECTORY)
  704.                 && !(findbuf.achName[0] == '.' && (   findbuf.achName[1]==0
  705.                                                    || pData->pszCurDir[3]==0)
  706.                     )
  707.                )
  708.                 {
  709.                 WinSendDlgItemMsg( hDlg,OPEN_DIRLIST,LM_INSERTITEM,
  710.                                    MPFROMSHORT(LIT_END),
  711.                                    MPFROMP(findbuf.achName) );
  712.                 }
  713.             usResult = DosFindNext( hdir,&findbuf,sizeof(findbuf),&usCount );
  714.             }
  715.  
  716.         if ( usResult != ERROR_NO_MORE_SEARCH_HANDLES ) DosFindClose(hdir);
  717.         if ( usResult && usResult != ERROR_NO_MORE_FILES )
  718.             {
  719.             if ( fError ) ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  720.             return;
  721.             }
  722.  
  723.     /* Fill file list box with list of files that match search specs. */
  724.         hdir    = HDIR_CREATE;
  725.         usCount = 1;
  726.         usResult = DosFindFirst( pData->pszShowSpec,&hdir,
  727.                                  pData->usShowAttr,&findbuf,
  728.                                  sizeof(findbuf),&usCount,0L );
  729.  
  730.         while ( !usResult )
  731.             {
  732.             WinSendDlgItemMsg( hDlg,OPEN_FILELIST,LM_INSERTITEM,
  733.                                MPFROMSHORT(LIT_END),
  734.                                MPFROMP(findbuf.achName) );
  735.  
  736.             usResult = DosFindNext( hdir,&findbuf,sizeof(findbuf),&usCount );
  737.             }
  738.  
  739.         if ( usResult != ERROR_NO_MORE_SEARCH_HANDLES ) DosFindClose(hdir);
  740.         if ( usResult && usResult != ERROR_NO_MORE_FILES )
  741.             if ( fError ) ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  742.  
  743.     /* Done. Return to caller. */
  744.         return;
  745.     }
  746. /****************************************************************************/
  747.  
  748.  
  749. /****************************************************************************
  750.  * OpenFile() - This function attempts to open the file specified           *
  751.  *              in the scratch data area, or if the file is a search        *
  752.  *              specification, updates the contents of the list boxes.      *
  753.  *                                                                          *
  754.  *              This function returns a non-zero value if an error occured  *
  755.  *              or the input string was a search specification.             *
  756.  ****************************************************************************/
  757.     static USHORT near OpenFile( HWND hDlg,PDATA pData )
  758.     {
  759.         USHORT  usResult;
  760.  
  761.         usResult = ParseFileName( pData->pszScratch,
  762.                                   pData->pszFile,
  763.                                   pData->pszShowSpec );
  764.         if ( usResult )
  765.             {
  766.             ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  767.             return 1;
  768.             }
  769.  
  770.         if ( NULL != strpbrk(pData->pszFile,szWildCardChars) )
  771.             {
  772.             strcpy( pData->pszShowSpec,strrchr(pData->pszFile,'\\')+1 );
  773.             FillListBoxes( hDlg,pData,TRUE );
  774.             return 1;
  775.             }
  776.         else
  777.             {
  778.             usResult = DosOpen( pData->pszFile,
  779.                                 pData->phf,
  780.                                 pData->pusAction,
  781.                                 pData->ulFileSize,
  782.                                 pData->usAttribute,
  783.                                 pData->fsOpenFlags,
  784.                                 pData->fsOpenMode,
  785.                                 pData->ulReserved );
  786.             if ( usResult )
  787.                 {
  788.                 ErrMessageBox( hDlg,pData->pszTitle,usResult,NULL,0 );
  789.                 return 1;
  790.                 }
  791.             else
  792.                 return 0;
  793.             }
  794.     }
  795. /****************************************************************************/
  796.