home *** CD-ROM | disk | FTP | other *** search
/ Sound Sensations! / sound_sensations.iso / soundb / sndhack / file.c < prev    next >
C/C++ Source or Header  |  1991-07-30  |  18KB  |  541 lines

  1. #include <windows.h>
  2. #include <io.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys\types.h>
  6. #include <sys\stat.h>
  7. #include "app.h"
  8.  
  9. /*
  10.  * Module: file.c
  11.  *
  12.  * Contains: File related functions.  File oriented fuctions
  13.  * show go here.  This includes file related callback functions
  14.  * for such dialog boxes as Open, Save, SaveAs.
  15.  *
  16.  */
  17.  
  18.  
  19. /*********************************************************************/
  20. /* Local Function Prototypes                                         */
  21. /*********************************************************************/
  22.  
  23. int FAR PASCAL SaveAsDlg(HWND, unsigned, WORD, LONG);
  24. HANDLE FAR PASCAL OpenDlg(HWND, unsigned, WORD, LONG);
  25.  
  26. void UpdateListBox(HWND hDlg);
  27.  
  28. void FileSetDefExt(PSTR Ext, PSTR Name);
  29. void FileSeparateName(LPSTR DestPath, LPSTR DestFile, LPSTR Src);
  30. void FileAddExt(PSTR Name, PSTR Ext);
  31. BOOL FileCheckName(HWND hDlg, PSTR Dest, PSTR Src);
  32. BOOL FileSaveBuffer(HWND Hdlg);
  33. void FileSetNewBuffer(HANDLE hNewBuffer, PSTR Title);
  34.  
  35. /*********************************************************************/
  36. /* Local data and structures                                         */
  37. /*********************************************************************/
  38.  
  39. static char FileName[128] = "";    /* the name of the current file   */
  40. static char PathName[128] = "";    /* file pathname                  */
  41. static char OpenName[128] = "";    /* name of a file to try and open */
  42. static char DefPath[128] = "";     /* current path                   */
  43. static char DefSpec[13] = "*.wsn"; /* current file specification     */
  44. static char DefExt[] = ".wsn";     /* current default extension      */
  45. static char str[255] = "";         /* work string                    */
  46.  
  47. static HANDLE hEditBuffer;         /* edit buffer                    */
  48. static HANDLE hOldBuffer;          /* old buffer handle              */
  49. static HANDLE hHourGlass;          /* handle to hourglass cursor     */
  50. static HANDLE hSaveCursor;         /* current cursor handle          */
  51. static int hFile;                  /* file handle                    */
  52. static int count;                  /* number of chars read or written*/
  53. static PSTR pBuffer;               /* address of read/write buffer   */
  54. static OFSTRUCT OfStruct;          /* information from OpenFile()    */
  55. static struct stat FileStatus;     /* information from fstat()       */
  56. static BOOL bSaveEnabled = FALSE;  /* TRUE if text in the edit buffer*/
  57. static PSTR pEditBuffer;           /* address of the edit buffer     */
  58. static RECT Rect;                  /* dimension of the client window */
  59. static HWND hwnd;                  /* handle to main window          */
  60.  
  61. /*********************************************************************/
  62. /* Global functions                                                  */
  63. /*********************************************************************/
  64.  
  65. /*-------------------------------------------------------------------*/
  66. /* Set current file to NEW.                                          */
  67. /*-------------------------------------------------------------------*/
  68.  
  69. void FileNew(hWnd)
  70. HWND hWnd;
  71. {
  72.   if (!FileQuerySave(hWnd))
  73.     return;
  74.  
  75.   FileName[0] = 0;
  76.  
  77.   /* Update the edit buffer */
  78.   wsprintf(str, "%s %s", (LPSTR) WindowName,(LPSTR)" - Untitled");
  79.   FileSetNewBuffer(NULL, str);
  80. }
  81.  
  82. /*-------------------------------------------------------------------*/
  83. /* Invoke a dialog box to open a file, check to save the current file*/
  84. /*-------------------------------------------------------------------*/
  85.  
  86. void FileOpen(hWnd)
  87. HWND hWnd;
  88. {
  89.   int numbytes;
  90.  
  91.   if (!FileQuerySave(hWnd))
  92.     return;
  93.  
  94.   /* Open the file and get its handle */
  95.   hFile = GoDialogBox(hInst, "Open", hWnd, (FARPROC)OpenDlg);
  96.   if (hFile <= 0)
  97.     return;
  98.  
  99.   /* Allocate edit buffer to the size of the file + 1 */
  100.   hEditBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, (WORD)(FileStatus.st_size+1));
  101.  
  102.   if (!hEditBuffer) {
  103.     MessageBox(hWnd, "Not enough memory.", NULL, MB_OK | MB_ICONHAND);
  104.     return;
  105.   }
  106.   hSaveCursor = SetCursor(hHourGlass);
  107.   pEditBuffer = LocalLock(hEditBuffer);
  108.  
  109.   numbytes = _lread(hFile, (LPSTR)pEditBuffer, (WORD)FileStatus.st_size);
  110.   close(hFile);
  111.  
  112.   /* # bytes read must equal file size */
  113.   if (numbytes != FileStatus.st_size) {
  114.     wsprintf(str, "Error reading %s.", (LPSTR)FileName);
  115.     SetCursor(hSaveCursor);      /* Remove the hourglass */
  116.     MessageBox(hWnd, str, NULL, MB_OK | MB_ICONEXCLAMATION);
  117.   }
  118.  
  119.   LocalUnlock(hEditBuffer);
  120.   /* Set up a new buffer and window title */
  121.   wsprintf(str, (LPSTR)"%s - %s", (LPSTR)WindowName, (LPSTR)FileName);
  122.   FileSetNewBuffer(hEditBuffer, str);
  123.   SetCursor(hSaveCursor);
  124. }
  125.  
  126. /*-------------------------------------------------------------------*/
  127. /* Save the current file                                             */
  128. /*-------------------------------------------------------------------*/
  129.  
  130. void FileSave(hWnd)
  131. HWND hWnd;
  132. {
  133.   if (!FileName[0])
  134.     FileSaveAs(hWnd);
  135.   FileSaveBuffer(hWnd);
  136. }
  137.  
  138. /*-------------------------------------------------------------------*/
  139. /* Save the current file prompting for a filename                    */
  140. /*-------------------------------------------------------------------*/
  141.  
  142. void FileSaveAs(hWnd)
  143. HWND hWnd;
  144. {
  145.   int Success;
  146.  
  147.   /* Call the SaveAsDlg() function to get the new filename */
  148.   Success = GoDialogBox(hInst, "SaveAs", hWnd, (FARPROC)SaveAsDlg);
  149.  
  150.   /* If successful, update the window title, save the file */
  151.   if (Success == IDOK) {
  152.     wsprintf(str, (LPSTR)"%s - %s", (LPSTR)WindowName,(LPSTR)FileName);
  153.     SetWindowText(hWnd, str);
  154.     FileSaveBuffer(hWnd);
  155.   }
  156. }
  157.  
  158.  
  159. /*-------------------------------------------------------------------*/
  160. /*  SaveAs dialog box callback function.                             */
  161. /*-------------------------------------------------------------------*/
  162.  
  163. int FAR PASCAL SaveAsDlg(hDlg, message, wParam, lParam)
  164. HWND hDlg;
  165. unsigned message;
  166. WORD wParam;
  167. LONG lParam;
  168. {
  169.   char TempName[128];
  170.  
  171.   switch (message) {
  172.     case WM_INITDIALOG:
  173.       /* If no filename is entered, don't allow the user to save to it */
  174.       if (!FileName[0])
  175.         bSaveEnabled = FALSE;
  176.       else {
  177.         bSaveEnabled = TRUE;
  178.  
  179.         /* Process the path to fit within the IDC_PATH field */
  180.         DlgDirList(hDlg, DefPath, NULL, IDC_PATH, 0x4010);
  181.  
  182.         /* Send the current filename to the edit control */
  183.         SetDlgItemText(hDlg, IDC_EDIT, FileName);
  184.  
  185.         /* Accept all characters in the edit control */
  186.         SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0, MAKELONG(0, 0x7fff));
  187.       }
  188.  
  189.       /* Enable or disable the save control depending on whether the
  190.        * filename exists.
  191.        */
  192.       EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled);
  193.  
  194.       /* Set the focus to the edit control within the dialog box */
  195.       SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  196.       return(FALSE);                 /* FALSE since Focus was changed */
  197.  
  198.     case WM_COMMAND:
  199.       switch (wParam) {
  200.         case IDC_EDIT:
  201.           /* If there was previously no filename in the edit
  202.            * control, then the save control must be enabled as soon as
  203.            * a character is entered.
  204.            */
  205.           if (HIWORD(lParam) == EN_CHANGE && !bSaveEnabled)
  206.             EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled = TRUE);
  207.           return (TRUE);
  208.  
  209.         case IDOK:
  210.           /* Get the filename from the edit control */
  211.           GetDlgItemText(hDlg, IDC_EDIT, TempName, 128);
  212.  
  213.           /* If there are no wildcards, then separate the name into
  214.            * path and name.  If a path was specified, replace the
  215.            * default path with the new path.
  216.            */
  217.           if (FileCheckName(hDlg, FileName, TempName)) {
  218.             FileSeparateName((LPSTR) str, (LPSTR) DefSpec, (LPSTR) FileName);
  219.             if (str[0])
  220.               strcpy(DefPath, str);
  221.  
  222.             /* Tell the caller a filename was selected */
  223.             EndDialog(hDlg, IDOK);
  224.           }
  225.           return (TRUE);
  226.  
  227.         case IDCANCEL:
  228.           /* Tell the caller the user canceled the SaveAs function */
  229.           EndDialog(hDlg, IDCANCEL);
  230.           return (TRUE);
  231.       }
  232.       break;
  233.   }
  234.   return (FALSE);
  235. }
  236.  
  237. /*-------------------------------------------------------------------*/
  238. /* Open dialog box callback function.                                */
  239. /*-------------------------------------------------------------------*/
  240.  
  241. HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
  242. HWND hDlg;
  243. unsigned message;
  244. WORD wParam;
  245. LONG lParam;
  246. {
  247.   WORD index;
  248.   PSTR pTptr;
  249.   HANDLE hFile;
  250.  
  251.   switch (message) {
  252.     case WM_COMMAND:
  253.       switch (wParam) {
  254.         case IDC_LISTBOX:
  255.           if (HIWORD(lParam) == LBN_SELCHANGE) {
  256.             /* If item is a directory name, append "*.*" */
  257.             if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
  258.               strcat(str, DefSpec);
  259.  
  260.             SetDlgItemText(hDlg, IDC_EDIT, str);
  261.             SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, NULL, MAKELONG(0, 0x7fff));
  262.             break;
  263.           }
  264.           else if (HIWORD(lParam) == LBN_DBLCLK)
  265.             ;
  266.           else
  267.             return(TRUE);
  268.  
  269.         case IDOK:
  270.           GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
  271.           if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
  272.             FileSeparateName((LPSTR) str, (LPSTR) DefSpec, (LPSTR) OpenName);
  273.             if (str[0])
  274.               strcpy(DefPath, str);
  275.             FileSetDefExt(DefExt, DefSpec);
  276.             UpdateListBox(hDlg);
  277.             return (TRUE);
  278.           }
  279.  
  280.           if (!OpenName[0]) {
  281.             MessageBox(hDlg, "No filename specified.", NULL, MB_OK | MB_ICONHAND);
  282.             return (TRUE);
  283.           }
  284.  
  285.           FileAddExt(OpenName, DefExt);
  286.  
  287.           /* Open the file */
  288.           if ((int)(hFile = OpenFile(OpenName, (LPOFSTRUCT)&OfStruct, OF_READ)) == -1) {
  289.             wsprintf(str, "Error %d opening %s.", OfStruct.nErrCode, (LPSTR)OpenName);
  290.             MessageBox(hDlg, str, NULL, MB_OK | MB_ICONHAND);
  291.           }
  292.           else {
  293.             /* Make sure there's enough room for the file */
  294.             fstat(hFile, &FileStatus);
  295.             if (FileStatus.st_size > MAXFILESIZE) {
  296.               wsprintf(str,
  297.                 "Not enough memory to load %s.\n%s exceeds %ld bytes.",
  298.                 (LPSTR)OpenName,
  299.                 (LPSTR)OpenName,
  300.                 MAXFILESIZE);
  301.               MessageBox(hDlg, str, NULL, MB_OK | MB_ICONHAND);
  302.               return (TRUE);
  303.             }
  304.  
  305.             /* File is opened and there is enough room so return
  306.              * the handle to the caller.
  307.              */
  308.  
  309.             strcpy(FileName, OpenName);
  310.             EndDialog(hDlg, hFile);
  311.             return (TRUE);
  312.           }
  313.           return (TRUE);
  314.  
  315.         case IDCANCEL:
  316.           EndDialog(hDlg, NULL);
  317.           return (TRUE);
  318.       }
  319.       break;
  320.  
  321.     case WM_INITDIALOG:                        /* message: initialize    */
  322.       UpdateListBox(hDlg);
  323.       SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  324.       SendDlgItemMessage(hDlg,               /* dialog handle      */
  325.         IDC_EDIT,                            /* where to send message  */
  326.         EM_SETSEL,                           /* select characters      */
  327.         NULL,                                /* additional information */
  328.         MAKELONG(0, 0x7fff));                /* entire contents      */
  329.       SetFocus(GetDlgItem(hDlg, IDC_EDIT));
  330.       return (FALSE);           /* Indicates the focus is set to a control */
  331.   }
  332.   return FALSE;
  333. }
  334.  
  335. /*-------------------------------------------------------------------*/
  336. /*  Update the list box of OpenDlg.                                  */
  337. /*-------------------------------------------------------------------*/
  338.  
  339. void UpdateListBox(hDlg)
  340. HWND hDlg;
  341. {
  342.   strcpy(str, DefPath);
  343.   strcat(str, DefSpec);
  344.   DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);
  345.  
  346.   /* To ensure that the listing is made for a subdir. of
  347.    * current drive dir...
  348.    */
  349.   if (!strchr (DefPath, ':'))
  350.     DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);
  351.  
  352.   /* Remove the '..' character from path if it exists, since this
  353.    * will make DlgDirList move us up an additional level in the tree
  354.    * when UpdateListBox() is called again.
  355.    */
  356.   if (strstr (DefPath, ".."))
  357.     DefPath[0] = '\0';
  358.  
  359.   SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
  360. }
  361.  
  362. /*-------------------------------------------------------------------*/
  363. /*  Change the default extension.                                    */
  364. /*-------------------------------------------------------------------*/
  365.  
  366. void FileSetDefExt(Ext, Name)
  367. PSTR Ext, Name;
  368. {
  369.   PSTR pTptr;
  370.  
  371.   pTptr = Name;
  372.   while (*pTptr && *pTptr != '.')
  373.     pTptr++;
  374.   if (*pTptr)
  375.     if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
  376.       strcpy(Ext, pTptr);
  377. }
  378.  
  379. /*-------------------------------------------------------------------*/
  380. /*  Separate the filename and the path.                              */
  381. /*-------------------------------------------------------------------*/
  382.  
  383. void FileSeparateName(lpDestPath, lpDestFileName, lpSrcFileName)
  384. LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
  385. {
  386.   LPSTR lpTmp;
  387.   char  cTmp;
  388.  
  389.   lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
  390.   while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
  391.     lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
  392.   if (*lpTmp != ':' && *lpTmp != '\\') {
  393.     lstrcpy(lpDestFileName, lpSrcFileName);
  394.     lpDestPath[0] = 0;
  395.     return;
  396.   }
  397.   lstrcpy(lpDestFileName, lpTmp + 1);
  398.   cTmp = *(lpTmp + 1);
  399.   lstrcpy(lpDestPath, lpSrcFileName);
  400.   *(lpTmp + 1) = cTmp;
  401.   lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
  402. }
  403.  
  404. /*-------------------------------------------------------------------*/
  405. /*  Add the default extension to a file name.                        */
  406. /*-------------------------------------------------------------------*/
  407.  
  408. void FileAddExt(Name, Ext)
  409. PSTR Name, Ext;
  410. {
  411.   PSTR pTptr;
  412.  
  413.   pTptr = Name;
  414.   while (*pTptr && *pTptr != '.')
  415.     pTptr++;
  416.   if (*pTptr != '.')
  417.     strcat(Name, Ext);
  418. }
  419.  
  420. /*-------------------------------------------------------------------*/
  421. /* Check the filename for wildcards and extension when saving a file.*/
  422. /*-------------------------------------------------------------------*/
  423.  
  424. BOOL FileCheckName(hDlg,pDest, pSrc)
  425. HWND hDlg;
  426. PSTR pDest, pSrc;
  427. {
  428.   PSTR pTmp;
  429.  
  430.   if (!pSrc[0])
  431.     return (FALSE);               /* Indicates no filename was specified */
  432.  
  433.   pTmp = pSrc;
  434.   while (*pTmp) {                     /* Searches the string for wildcards */
  435.     switch (*pTmp++) {
  436.       case '*':
  437.       case '?':
  438.         MessageBox(hDlg, "Wildcards not allowed.", NULL, MB_OK | MB_ICONEXCLAMATION);
  439.         return (FALSE);
  440.     }
  441.   }
  442.  
  443.   FileAddExt(pSrc, DefExt);
  444.  
  445.   if (OpenFile(pSrc, (LPOFSTRUCT) &OfStruct, OF_EXIST) >= 0) {
  446.     wsprintf(str, "Replace existing %s?", (LPSTR)pSrc);
  447.     if (MessageBox(hDlg, str, WindowName, MB_OKCANCEL | MB_ICONHAND) == IDCANCEL)
  448.       return (FALSE);
  449.   }
  450.   strcpy(pDest, pSrc);
  451.   return (TRUE);
  452. }
  453.  
  454. /*-------------------------------------------------------------------*/
  455. /*  Save the contents of the edit buffer to a file.                  */
  456. /*-------------------------------------------------------------------*/
  457.  
  458. BOOL FileSaveBuffer(hDlg)
  459. HWND hDlg;
  460. {
  461.   BOOL bSuccess;
  462.   int numbytes;
  463.  
  464.   if ((hFile = OpenFile(FileName, &OfStruct, OF_PROMPT|OF_CANCEL|OF_CREATE)) < 0) {
  465.     wsprintf(str, "Cannot write to %s.", (LPSTR)FileName);
  466.     MessageBox(hDlg, str, NULL, MB_OK | MB_ICONEXCLAMATION);
  467.     return (FALSE);
  468.   }
  469.  
  470.   hEditBuffer = SendMessage(hEditWindow, EM_GETHANDLE, 0, 0L);
  471.   pEditBuffer = LocalLock(hEditBuffer);
  472.  
  473.   hSaveCursor = SetCursor(hHourGlass);
  474.   numbytes = _lwrite(hFile, (LPSTR)pEditBuffer, (WORD)strlen(pEditBuffer));
  475.   close(hFile);
  476.   SetCursor(hSaveCursor);
  477.   if (numbytes != strlen(pEditBuffer)) {
  478.     wsprintf(str, "Error writing to %s.", (LPSTR)FileName);
  479.     MessageBox(hDlg, str, NULL, MB_OK | MB_ICONHAND);
  480.     bSuccess = FALSE;
  481.   }
  482.   else {
  483.     bSuccess = TRUE;                /* Indicates the file was saved      */
  484.   }
  485.   LocalUnlock(hEditBuffer);
  486.   SendMessage(hEditWindow, EM_SETMODIFY, 0, 0L);
  487.   return (bSuccess);
  488. }
  489.  
  490. /*-------------------------------------------------------------------*/
  491. /*  Ask if the current contents of the edit buffer should be saved.  */
  492. /*-------------------------------------------------------------------*/
  493.  
  494. BOOL FileQuerySave(hWnd)
  495. HWND hWnd;
  496. {
  497.   int Response;
  498.  
  499.   if (SendMessage(hEditWindow, EM_GETMODIFY, 0, 0L) != 0) {
  500.     wsprintf(str, "Save current changes: %s", (LPSTR)FileName);
  501.     Response = MessageBox(hWnd, str, WindowName, MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  502.     if (Response == IDYES) {
  503.       while (!FileName[0]) {
  504.         Response = GoDialogBox(hInst, "SaveAs", hWnd, (FARPROC)SaveAsDlg);
  505.         if (Response == IDOK)
  506.           continue;
  507.         else
  508.           return (FALSE);
  509.       }
  510.       FileSaveBuffer(hWnd);
  511.     }
  512.     else if (Response == IDCANCEL)
  513.       return(FALSE);
  514.   }
  515.   return(TRUE);
  516. }
  517.  
  518. /*-------------------------------------------------------------------*/
  519. /*  Reset the edit window file buffer to a new one.                  */
  520. /*-------------------------------------------------------------------*/
  521.  
  522. void FileSetNewBuffer(hNewBuffer, Title)
  523. HANDLE hNewBuffer;
  524. PSTR Title;
  525. {
  526.   HANDLE hOldBuffer;
  527.  
  528.   hOldBuffer = SendMessage(hEditWindow, EM_GETHANDLE, 0, 0L);
  529.   LocalFree(hOldBuffer);
  530.   if (!hNewBuffer)
  531.     hNewBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 1);
  532.  
  533.   /* Updates the buffer and displays new buffer */
  534.   SendMessage(hEditWindow, EM_SETHANDLE, hNewBuffer, 0L);
  535.   SendMessage(hEditWindow, EM_SETMODIFY, 0, 0L);
  536.  
  537.   SetWindowText(hWindow, Title);
  538.   SetFocus(hEditWindow);
  539. }
  540.  
  541.