home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1995 July / IMM0795.ISO / share / os2 / pmfract / src / file1.c < prev    next >
C/C++ Source or Header  |  1994-01-24  |  17KB  |  557 lines

  1. /*
  2.     FILE1.C -- Dialog Directory Listbox and Open File functions
  3.     Created by Microsoft Corporation, 1989
  4. */
  5.  
  6. #define  INCL_DOS
  7. #include "tool.h"
  8.  
  9. /****************************************************************************\
  10. * This function builds a directory list in a list box.
  11. \****************************************************************************/
  12.  
  13. int FAR PASCAL DlgDirList(HWND hwnd, PSZ lpszPath, int idDirList,
  14.               int idFileList, int idStaticPath, USHORT attr)
  15.     {
  16.     CHAR szPath[MAX_FNAME_LEN];
  17.     CHAR chTmp;
  18.     PSZ  lpszFile, lpszNull;
  19.     HPOINTER hPointer;
  20.  
  21.     /* ensure path is legal and expand to full search path */
  22.     if (!DlgParseFile(lpszPath, (PSZ)szPath, FALSE, TRUE))
  23.         return FALSE;
  24.  
  25.     /* set pointer to hours glass */
  26.     hPointer = WinQueryPointer(HWND_DESKTOP); 
  27.     WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
  28.  
  29.     /* set current drive */
  30.     DosSelectDisk(*szPath - 'A' + 1);
  31.  
  32.     /* temporarily put zero after directory spec and set current directory */
  33.     lpszFile = FileInPath((PSZ)szPath);
  34.     lpszNull = lpszFile;
  35.     if (lpszNull > (PSZ)szPath + 3)
  36.         lpszNull--;
  37.     chTmp = *lpszNull;
  38.     *lpszNull = '\0';
  39.     DosChDir((PSZ)szPath, 0l);
  40.     if (idStaticPath)
  41.         WinSetWindowText(WinWindowFromID(hwnd, idStaticPath),
  42.                          DlgFitPathToBox(hwnd, idStaticPath, (PSZ)szPath));
  43.     *lpszNull = chTmp;
  44.  
  45.     /* fill list box with file names */
  46.     if (idDirList && idFileList)
  47.         {
  48.         /* fill them up with new entries */
  49.         DlgFillListBoxes(hwnd, idDirList, idFileList, attr, lpszFile);
  50.         }
  51.  
  52.     /* reset pointer to previous figure */
  53.     WinSetPointer(HWND_DESKTOP, hPointer);
  54.  
  55.     return TRUE;
  56.     }
  57.  
  58.  
  59.  
  60.  
  61. /****************************************************************************\
  62. * This function gets the file name selected by the user.
  63. \****************************************************************************/
  64.  
  65. int FAR PASCAL DlgDirSelect(HWND hwnd, PSZ lpszIn, int idListBox)
  66.     {
  67.     CHAR sz[MAX_FNAME_LEN];
  68.     int item;
  69.     PSZ  lpsz, lpszFile;
  70.     BOOL fDir;
  71.  
  72.     /* get currently selected list entry */
  73.     item = (int) WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYSELECTION, 0L, 0L);
  74.     if (item == LIT_NONE)
  75.         return FALSE;
  76.     WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYITEMTEXT,
  77.                       MPFROM2SHORT(item, MAX_FNAME_LEN), (MPARAM)(PSZ)sz);
  78.     lpszFile = sz;
  79.  
  80.     /* extract name */
  81.     if (fDir = (*sz == '['))
  82.         {
  83.         lpszFile = NextChar(lpszFile);
  84.         if (*lpszFile == '-')
  85.             {
  86.             /* drive selection */
  87.             lpszFile = NextChar(lpszFile);
  88.             *(lpszFile+1) = ':';
  89.             *(lpszFile+2) = '\0';
  90.             }
  91.         else
  92.             {
  93.             /* directory selection */
  94.             lpsz = lpszFile;
  95.             while (*lpsz != ']')
  96.                 lpsz = NextChar(lpsz);
  97.             *lpsz = '\\';
  98.             }
  99.         }
  100.  
  101.     lstrcpy(lpszIn, lpszFile);
  102.     return (fDir);
  103.     }
  104.  
  105.  
  106.  
  107.  
  108. /****************************************************************************\
  109. * This function tries to open pdlf=>szFileName.  If the file does not
  110. * exist, the function asks to create it.
  111. *
  112. *  Returns:
  113. *    TDF_NOOPEN  - Illegal Filename or user didn't want to create
  114. *    TDF_OLDOPEN - Existing file
  115. *    TDF_NEWOPEN - File was created
  116. \****************************************************************************/
  117.  
  118. USHORT PASCAL DlgOpenFile(PDLF pdlf, HWND hwnd)
  119.     {
  120.     /* check for legal dos name */
  121.     if (!DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
  122.                       FALSE, FALSE))
  123.         {
  124.         DlgAlertBox(hwnd, IDS_IFN, pdlf, MB_OK | MB_ICONEXCLAMATION);
  125.         return (TDF_NOOPEN);
  126.         }
  127.     /* see if file already exists */
  128.     if (DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
  129.                       TRUE, FALSE))
  130.         {
  131.         if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
  132.                         (PSZ)pdlf->szOpenFile, OF_READ))
  133.             return (TDF_OLDOPEN);
  134.         else
  135.             {
  136.             DlgAlertBox(hwnd, IDS_EOF, pdlf, MB_OK | MB_ICONEXCLAMATION);
  137.             return (TDF_NOOPEN);
  138.             }
  139.         }
  140.     /* file doesn't exist: create new one? */
  141.     else if (DlgAlertBox(hwnd, IDS_FNF, pdlf, MB_YESNO | MB_ICONQUESTION) == MBID_YES)
  142.         {
  143.         if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
  144.                         (PSZ)pdlf->szOpenFile, OF_CREATE))
  145.             return (TDF_NEWOPEN);
  146.         else
  147.             DlgAlertBox(hwnd, IDS_ECF, pdlf, MB_OK | MB_ICONEXCLAMATION);
  148.         }
  149.     return(TDF_NOOPEN);
  150.     }
  151.  
  152.  
  153.  
  154.  
  155. /****************************************************************************\
  156. * This function returns the OS/2 file handle if operation is successful,
  157. * 0 otherwise.
  158. *
  159. * Effects:  Depend on wMode:
  160. *     OF_READ:      open file for reading only
  161. *     OF_WRITE:     open file for writing only
  162. *     OF_READWRITE: open file for reading and writing
  163. *     OF_CREATE:    create the file if it does not exist
  164. *     OF_REOPEN:    open file using info in the reopen buffer
  165. *     OF_EXIST:     test file existence
  166. *     OF_PARSE:     fill reopen buffer, with no other action
  167. \****************************************************************************/
  168.  
  169.  
  170. BOOL EXPENTRY OpenFile(PSZ lpszFile, PHFILE lpHandle,
  171.                PSZ lpszOpenFile, USHORT wMode)
  172.     {
  173.     HFILE hFile = NULL;
  174.     USHORT wAction = NULL;
  175.     USHORT wAttrs = NULL;
  176.     USHORT wOpenFlag, wOpenMode;
  177.     CHAR sz[MAX_FNAME_LEN];
  178.  
  179.     /* if reopen specified, use earlier pathname */
  180.     if (wMode & OF_REOPEN)
  181.         {
  182.         lstrcpy((PSZ)sz, lpszOpenFile);
  183.         lpszFile = (PSZ)sz;
  184.         }
  185.  
  186.     /* parse file */
  187.     if (!DlgParseFile(lpszFile, lpszOpenFile, wMode&OF_EXIST, FALSE))
  188.         {
  189.         *lpszOpenFile = '\0';
  190.         return FALSE;
  191.         }
  192.     /* return if implementing boolean test OF_PARSE or OF_EXIST */
  193.     if (wMode & (OF_PARSE | OF_EXIST))
  194.         {
  195.         return TRUE;
  196.         }
  197.  
  198.     if (wMode & OF_READ)
  199.         {
  200.         wOpenFlag = 0x01;               /* fail if it doesn't exist */
  201.         wOpenMode = 0x20;               /* read only */
  202.         }
  203.     else if (wMode & OF_WRITE)
  204.         {
  205.         wOpenFlag = 0x11;               /* create if necessary */
  206.         wOpenMode = 0x11;               /* write only */
  207.         }
  208.     else if (wMode & OF_READWRITE)
  209.         {
  210.         wOpenFlag = 0x11;               /* create if necessary */
  211.         wOpenMode = 0x12;               /* read-write */
  212.         }
  213.     else if (wMode & OF_CREATE)
  214.         {
  215.         /* create and close file */
  216.         wOpenFlag = 0x10;               /* fail if exists */
  217.         wOpenMode = 0x10;               /* read only */
  218.         }
  219.     else
  220.         {
  221.         return FALSE;
  222.         }
  223.  
  224.     if (DosOpen(lpszFile, (PHFILE)&hFile, &wAction,
  225.                 (ULONG) 0, 0, wOpenFlag, wOpenMode, (ULONG) 0))
  226.         return FALSE;
  227.  
  228.     if (wMode & OF_CREATE)
  229.         {
  230.         if (DosClose(hFile))
  231.             return FALSE;
  232.         }
  233.     else
  234.         *lpHandle = hFile;
  235.  
  236.     return TRUE;
  237.     }
  238.  
  239.  
  240.  
  241.  
  242. /****************************************************************************\
  243. * This function puts a path string into a static box.
  244. \****************************************************************************/
  245.  
  246. PSZ  PASCAL DlgFitPathToBox(HWND hwnd, int idStatic, PSZ lpch)
  247.     {
  248.     WRECT rc;
  249.     int cxField;
  250.     char chDrive;
  251.     HPS hps;
  252.  
  253.     /* get length of static field */
  254.     WinQueryWindowRect(WinWindowFromID(hwnd, idStatic), (PRECTL)&rc);
  255.     cxField = rc.xRight - rc.xLeft;
  256.  
  257.     hps = WinGetPS(hwnd);
  258.     if (cxField < LOUSHORT(GetTextExtent(hps, lpch,
  259.                                            lstrlen(lpch))))
  260.         {
  261.         chDrive = *lpch;
  262.         /* chop characters off front of string until text is short enough */
  263.         do
  264.             do
  265.                 lpch = NextChar(lpch);
  266.             while (*(lpch+6) != '\\' &&
  267.                    *(lpch+6) != '\0');
  268.         while (cxField < LOUSHORT(GetTextExtent(hps, lpch,
  269.                                                  lstrlen(lpch))));
  270.         /* insert header */
  271.         *lpch++ = chDrive;
  272.         *lpch++ = ':';
  273.         *lpch++ = '\\';
  274.         *lpch++ = '.';
  275.         *lpch++ = '.';
  276.         *lpch++ = '.';
  277.         lpch -= 6;
  278.         }
  279.     WinReleasePS(hps);
  280.     return (lpch);
  281.     }
  282.  
  283.  
  284.  
  285.  
  286. /****************************************************************************\
  287. * This function fills a list box with appropriate file names from the
  288. * current directory.
  289. \****************************************************************************/
  290.  
  291. int PASCAL DlgFillListBoxes(HWND hwnd, int idDirList, int idFileList,
  292.                 USHORT attr, PSZ lpszFileSpec)
  293.     {
  294.     USHORT usFiles, usDrive;
  295.     int i;
  296.     PSZ  lpsz;
  297.     HDIR hDir;
  298.     ULONG lrgfDrives;
  299.     FILEFINDBUF ffb;
  300.     CHAR sz[20];
  301.     int cDrives;
  302.     int result = -1;
  303.     HWND hwndFiles, hwndDirs;
  304.  
  305.     /* get listbox window handles */
  306.     hwndFiles = WinWindowFromID(hwnd, idFileList);
  307.     hwndDirs = WinWindowFromID(hwnd, idDirList);
  308.  
  309.     /* disable updates to listboxes */
  310.     WinEnableWindowUpdate(hwndFiles, FALSE);
  311.     WinEnableWindowUpdate(hwndDirs, FALSE);
  312.  
  313.     /* empty list boxes of any old entries */
  314.     WinSendMsg(hwndFiles, LM_DELETEALL, 0L, 0L);
  315.     WinSendMsg(hwndDirs, LM_DELETEALL, 0L, 0L);
  316.  
  317.     /* put files that lMatch search spec in file listbox */
  318.     usFiles = 1;
  319.     hDir = 0xFFFF;
  320.     if (!DosFindFirst(lpszFileSpec, (PHDIR)&hDir,
  321.         attr&~(BITATTRDIR|BITATTRDRIVE), (PFILEFINDBUF)&ffb, sizeof(FILEFINDBUF),
  322.         &usFiles, 0L))
  323.         {
  324.         do
  325.             {
  326.             /* add string to list box */
  327.             result = (int) WinSendMsg(hwndFiles, LM_INSERTITEM,
  328.                                       MPFROM2SHORT(LIT_SORTASCENDING, 0),
  329.                                       (MPARAM)(PSZ)&(ffb.achName[0]));
  330.             usFiles = 1;
  331.             }
  332.         while (result >= 0 && !DosFindNext(hDir,
  333.                                            (PFILEFINDBUF)&ffb,
  334.                                            sizeof(FILEFINDBUF),
  335.                                            &usFiles));
  336.         DosFindClose(hDir);
  337.         }
  338.  
  339.     if (result != LIT_MEMERROR && (attr   & BITATTRDIR))
  340.         {
  341.         /* get directories */
  342.         usFiles = 1;
  343.         hDir = 0xFFFF;
  344.     if (!DosFindFirst((PSZ)szStarStar, (PHDIR)&hDir, BITATTRDIR,
  345.             (PFILEFINDBUF)&ffb, sizeof(FILEFINDBUF), &usFiles, 0l))
  346.             {
  347.             do
  348.                 {
  349.                 /* extract file name */
  350.                 if (ffb.attrFile & BITATTRDIR)
  351.                     {
  352.                     /* put brackets around directory */
  353.             lpsz = (PSZ)&(ffb.achName[0]);
  354.                     if (*lpsz == '.' && *(lpsz+1) == '\0')
  355.                         /* forget about current directory name '.' */
  356.             continue;
  357.                     sz[0] = '[';
  358.                     lstrcpy((PSZ)&sz[1], lpsz);
  359.                     sz[ffb.cchName    + 1] = ']';
  360.                     sz[ffb.cchName    + 2] = '\0';
  361.                     lpsz = (PSZ)sz;
  362.                     /* add string to list box */
  363.                     result = (int) WinSendMsg(hwndDirs, LM_INSERTITEM,
  364.                                               MPFROM2SHORT(LIT_SORTASCENDING, 0),
  365.                                               (MPARAM)lpsz);
  366.                     }
  367.                 usFiles = 1;
  368.                 }
  369.             while (result >= -1 && !DosFindNext(hDir,
  370.                                                (PFILEFINDBUF)&ffb,
  371.                                                sizeof(FILEFINDBUF),
  372.                                                &usFiles));
  373.             DosFindClose(hDir);
  374.             }
  375.         }
  376.  
  377.     if (result != LIT_MEMERROR && (attr   & BITATTRDRIVE))
  378.         /* get drives */
  379.         {
  380.         sz[0] = '[';
  381.         sz[1] = sz[3] = '-';
  382.         sz[4] = ']';
  383.         sz[5] = '\0';
  384.  
  385.         DosQCurDisk(&usDrive, (unsigned long far *)&lrgfDrives);
  386.         cDrives = 0;
  387.         for (i=0; 'A' + i <= 'Z'; i++)
  388.             {
  389.             if (lrgfDrives & 1L)
  390.                 {
  391.                 sz[2] = (char)('A' + i);
  392.                 /* add drive to list */
  393.                 result = (int) WinSendMsg(hwndDirs, LM_INSERTITEM,
  394.                       MPFROM2SHORT(LIT_END, 0),
  395.                                           (MPARAM)(PSZ)sz);
  396.                 cDrives++;
  397.                 }
  398.             lrgfDrives >>= 1;
  399.             }
  400.         }
  401.  
  402.     /* enable and show updated listboxes */
  403.     WinShowWindow(hwndFiles, TRUE);
  404.     WinShowWindow(hwndDirs, TRUE);
  405.  
  406.     return result;
  407.     }
  408.  
  409.  
  410.  
  411.  
  412. /****************************************************************************\
  413. * This function parses a string into an fully expanded file name or search
  414. * path.  If fExist is true then the file must exist or the search path must
  415. * correspond to at least one existing file.  In all cases, the corresponding
  416. * directory must exist.  The string must be a file name, ie. no wildcards,
  417. * unless fWildOkay is true.  Returns TRUE if string is parsed correctly.
  418. \****************************************************************************/
  419.  
  420. BOOL PASCAL DlgParseFile(PSZ lpszIn, PSZ lpszExp, BOOL fExist, BOOL fWildOkay)
  421.     {
  422.     CHAR szPath[MAX_FNAME_LEN];
  423.     PSZ  lpszFile, lpsz;
  424.  
  425.     /* go past any path spec to first char in file name */
  426.     lpszFile = FileInPath(lpszIn);
  427.  
  428.     /* check validity of file name */
  429.     if (!fExist && !DlgValidName(lpszFile, fWildOkay))
  430.         {
  431.         *lpszExp = '\0';
  432.         return FALSE;
  433.         }
  434.  
  435.     /* copy path part to path string */
  436.     lpsz = (PSZ)szPath;
  437.     if (lpszIn == lpszFile)
  438.         *lpsz++ = '.';
  439.     else
  440.         {
  441.         while (lpszIn < lpszFile && lpsz < ((PSZ)szPath + MAX_FNAME_LEN - 1))
  442.             *lpsz++ = *lpszIn++;
  443.         }
  444.     *lpsz = '\0';
  445.  
  446.     /* let DOS do the dirty work */
  447.     if (fExist)
  448.         {
  449.         /* test existence of file while parsing path */
  450.         if (DosSearchPath(0, (PSZ)szPath, lpszFile, lpszExp, MAX_FNAME_LEN))
  451.             {
  452.             *lpszExp = '\0';
  453.             return FALSE;
  454.             }
  455.         }
  456.     else
  457.         {
  458.         /* use dummy wild card while parsing path */
  459.     if (DosSearchPath(0, (PSZ)szPath, (PSZ)szStarStar, lpszExp, MAX_FNAME_LEN))
  460.             {
  461.             *lpszExp = '\0';
  462.             return FALSE;
  463.             }
  464.         /* replace wild card part with true file name converted to CAPS */
  465.         lpsz = lpszExp;
  466.         while (*lpsz != '?' && *lpsz != '*' && *lpsz != '\0')
  467.             lpsz++;
  468.         while (*lpszFile != '\0')
  469.             {
  470.             *lpsz++ = *lpszFile++;
  471.             }
  472.         *lpsz = '\0';
  473.         Upper(lpszExp);
  474.         }
  475.     return TRUE;
  476.     }
  477.  
  478.  
  479.  
  480.  
  481. /****************************************************************************\
  482. * This function determines if a string forms a legal file name or search
  483. * path.  Wildcard characters are acceptable if fWildOkay is true.  Returns
  484. * TRUE if string is legal.
  485. \****************************************************************************/
  486.  
  487. BOOL PASCAL DlgValidName(PSZ lpszName, BOOL fWildOkay)
  488.     {
  489.     int cLen;
  490.     PSZ  lpsz;
  491.  
  492.     /* check file name */
  493.     if (*lpszName == '\0')
  494.         return FALSE;
  495.     cLen = 0;
  496.     lpsz = lpszName;
  497.     while (*lpsz != '\0' && *lpsz != '.')
  498.         {
  499.         if (++cLen > 8 || *lpsz < 0x20)
  500.             return FALSE;
  501.         switch (*lpsz++)
  502.             {
  503.             case '*':
  504.             case '?':
  505.                 if (fWildOkay)
  506.                     break;
  507.             case '\"':
  508.             case '\\':
  509.             case '/':
  510.             case '[':
  511.             case ']':
  512.             case ':':
  513.             case '|':
  514.             case '<':
  515.             case '>':
  516.             case '+':
  517.             case '=':
  518.             case ';':
  519.             case ',':
  520.                 return FALSE;
  521.             }
  522.         }
  523.  
  524.     /* check extension */
  525.     if (*lpsz++ == '\0')
  526.         return TRUE;
  527.     cLen = 0;
  528.     while (*lpsz != '\0')
  529.         {
  530.         if (++cLen > 3 || *lpsz < 0x20)
  531.             return FALSE;
  532.         switch (*lpsz++)
  533.             {
  534.             case '*':
  535.             case '?':
  536.                 if (fWildOkay)
  537.                     break;
  538.             case '.':
  539.             case '\"':
  540.             case '\\':
  541.             case '/':
  542.             case '[':
  543.             case ']':
  544.             case ':':
  545.             case '|':
  546.             case '<':
  547.             case '>':
  548.             case '+':
  549.             case '=':
  550.             case ';':
  551.             case ',':
  552.                 return FALSE;
  553.             }
  554.         }
  555.     return TRUE;
  556.     }
  557.