home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c480 / 18.ddi / SAMPLES / PENPAD / PPFILE.C_ / PPFILE.C
Encoding:
C/C++ Source or Header  |  1993-02-08  |  16.7 KB  |  479 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  MODULE    : PpFile.c                                                   *
  4.  *                                                                         *
  5.  *  PURPOSE   : Contains the code for File I/O for penpad.               *
  6.  *                                                                         *
  7.  *  FUNCTIONS : AlreadyOpen   - Determines if a file is already open.      *
  8.  *                                                                         *
  9.  *              AddFile       - Creates a new MDI window and, if specified,*
  10.  *              loads a file into it.                      *
  11.  *                                                                         *
  12.  *              LoadFile      - Loads a file into a MDI window.            *
  13.  *                                                                         *
  14.  *              ReadFile      - Calls File/Open dialog and appropriately   *
  15.  *                              responds to the user's input.              *
  16.  *                                                                         *
  17.  *              SaveFile      - Saves the contents of a MDI window's edit  *
  18.  *                              control to a file.                         *
  19.  *                                                                         *
  20.  *              SetSaveFrom   - Formats the "Save 'file' to" string.       *
  21.  *                                                                         *
  22.  *              SaveAsDlgProc - Dialog function for the File/SaveAs dialog.*
  23.  *                                                                         *
  24.  *              ChangeFile    - Calls File/SaveAs dialog.                  *
  25.  *                                                                         *
  26.  ***************************************************************************/
  27. #include "penpad.h"
  28.  
  29. VOID FAR PASCAL GetFileName(PSTR);
  30. BOOL FAR PASCAL __export SaveAsDlgProc( HWND,WORD,WORD,LONG);
  31. int FAR PASCAL DialogBoxParam(HANDLE,LPCSTR,HWND,FARPROC,LONG);
  32.  
  33. OFSTRUCT    of;
  34. /****************************************************************************
  35.  *                                                                          *
  36.  *  FUNCTION   : AlreadyOpen(szFile)                                        *
  37.  *                                                                          *
  38.  *  PURPOSE    : Checks to see if the file described by the string pointed  *
  39.  *               to by 'szFile' is already open.                            *
  40.  *                                                                          *
  41.  *  RETURNS    : a handle to the described file's window if that file is    *
  42.  *               already open;  NULL otherwise.                             *
  43.  *                                                                          *
  44.  ****************************************************************************/
  45.  
  46. HWND AlreadyOpen(char *szFile)
  47. {
  48.     int     iDiff;
  49.     HWND    hwndCheck;
  50.     char    szChild[64];
  51.     LPSTR   lpChild, lpFile;
  52.     int     wFileTemp;
  53.  
  54.     /* Open the file with the OF_PARSE flag to obtain the fully qualified
  55.      * pathname in the OFSTRUCT structure.
  56.      */
  57.     wFileTemp = OpenFile ((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE);
  58.     if (! wFileTemp)
  59.     return(NULL);
  60.     _lclose (wFileTemp);
  61.  
  62.     /* Check each MDI child window in Penpad */
  63.     for (   hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
  64.         hwndCheck;
  65.         hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
  66.     /* Initialization  for comparison */
  67.     lpChild = szChild;
  68.     lpFile = AnsiUpper((LPSTR) of.szPathName);
  69.     iDiff = 0;
  70.  
  71.     /* Skip icon title windows */
  72.     if (GetWindow(hwndCheck, GW_OWNER))
  73.         continue;
  74.  
  75.     /* Get current child window's name */
  76.     GetWindowText(hwndCheck, lpChild, 64);
  77.  
  78.     /* Compare window name with given name */
  79.     while ((*lpChild) && (*lpFile) && (!iDiff)){
  80.         if (*lpChild++ != *lpFile++)
  81.         iDiff = 1;
  82.     }
  83.  
  84.     /* If the two names matched, the file is already   */
  85.     /* open -- return handle to matching child window. */
  86.     if (!iDiff)
  87.         return(hwndCheck);
  88.     }
  89.     /* No match found -- file is not open -- return NULL handle */
  90.     return(NULL);
  91. }
  92.  
  93. /****************************************************************************
  94.  *                                      *
  95.  *  FUNCTION   : AddFile (lpName)                       *
  96.  *                                      *
  97.  *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
  98.  *       NULL, it loads a file into the window.             *
  99.  *                                      *
  100.  *  RETURNS    : HWND  - A handle to the new window.                *
  101.  *                                      *
  102.  ****************************************************************************/
  103.  
  104. HWND FAR PASCAL AddFile(pName)
  105. char * pName;
  106. {
  107.     HWND hwnd;
  108.  
  109.     char        sz[160];
  110.     MDICREATESTRUCT mcs;
  111.  
  112.     if (!pName) {
  113.     /* The pName parameter is NULL -- load the "Untitled" string from */
  114.     /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
  115.     LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
  116.     mcs.szTitle = (LPSTR)sz;
  117.     }
  118.     else
  119.     /* Title the window with the fully qualified pathname obtained by
  120.      * calling OpenFile() with the OF_PARSE flag (in function
  121.      * AlreadyOpen(), which is called before AddFile().
  122.      */
  123.     mcs.szTitle = of.szPathName;
  124.  
  125.     mcs.szClass = szChild;
  126.     mcs.hOwner  = hInst;
  127.  
  128.     /* Use the default size for the window */
  129.     mcs.x = mcs.cx = CW_USEDEFAULT;
  130.     mcs.y = mcs.cy = CW_USEDEFAULT;
  131.  
  132.     /* Set the style DWORD of the window to default */
  133.     mcs.style = styleDefault;
  134.  
  135.     /* tell the MDI Client to create the child */
  136.     hwnd = (WORD)SendMessage (hwndMDIClient,
  137.                   WM_MDICREATE,
  138.                   0,
  139.                   (LONG)(LPMDICREATESTRUCT)&mcs);
  140.  
  141.     /* Did we get a file? Read it into the window */
  142.     if (pName){
  143.     if (!LoadFile(hwnd, pName)){
  144.         /* File couldn't be loaded -- close window */
  145.         SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwnd, 0L);
  146.     }
  147.     }
  148.  
  149.     return hwnd;
  150. }
  151.  
  152. /****************************************************************************
  153.  *                                      *
  154.  *  FUNCTION   : LoadFile (lpName)                      *
  155.  *                                      *
  156.  *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
  157.  *       file into the window's edit control child.                 *
  158.  *                                      *
  159.  *  RETURNS    : TRUE  - If file is sucessfully loaded.             *
  160.  *       FALSE - Otherwise.                     *
  161.  *                                      *
  162.  ****************************************************************************/
  163.  
  164. int FAR PASCAL LoadFile (hwnd, pName)
  165. HWND hwnd;
  166. char * pName;
  167. {
  168.     WORD   wLength;
  169.     HANDLE hT;
  170.     LPSTR  lpB;
  171.     HWND   hwndEdit;
  172.     int    fh;
  173.  
  174.     hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);
  175.  
  176.     /* The file has a title, so reset the UNTITLED flag. */
  177.     SetWindowWord(hwnd, GWW_UNTITLED, FALSE);
  178.  
  179.     fh = _lopen (pName, 0);
  180.  
  181.     /* Make sure file has been opened correctly */
  182.     if ( fh < 0 )
  183.     goto error;
  184.  
  185.     /* Find the length of the file */
  186.     wLength = (WORD)_llseek (fh, 0L, 2);
  187.     _llseek (fh, 0L, 0);
  188.  
  189.     /* Attempt to reallocate the edit control's buffer to the file size */
  190.     hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  191.     if (LocalReAlloc(hT, wLength+1, LHND) == NULL) {
  192.     /* Couldn't reallocate to new size -- error */
  193.     _lclose (fh);
  194.     goto error;
  195.     }
  196.  
  197.     /* read the file into the buffer */
  198.     if (wLength != _lread (fh, (lpB = (LPSTR)LocalLock (hT)), wLength))
  199.     PPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);
  200.  
  201.     /* Zero terminate the edit buffer */
  202.     lpB[wLength] = 0;
  203.     LocalUnlock (hT);
  204.  
  205.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  206.     _lclose (fh);
  207.  
  208.     return TRUE;
  209.  
  210. error:
  211.     /* Report the error and quit */
  212.     PPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
  213.     return FALSE;
  214. }
  215.  
  216. /****************************************************************************
  217.  *                                                                          *
  218.  *  FUNCTION   : ReadFile(hwnd)                                             *
  219.  *                                                                          *
  220.  *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
  221.  *               the user for a file name and responds appropriately.       *
  222.  *                                                                          *
  223.  ****************************************************************************/
  224.  
  225. VOID FAR PASCAL ReadFile(HWND hwnd)
  226. {
  227.     char    szFile[128];
  228.     HWND    hwndFile;
  229.  
  230.      hwnd;                  /* Needed to prevent compiler warning message */
  231.  
  232.     GetFileName (szFile);
  233.  
  234.     /* If the result is not the empty string -- take appropriate action */
  235.     if (*szFile) {
  236.     /* Is file already open?? */
  237.     if (hwndFile = AlreadyOpen(szFile)) {
  238.         /* Yes -- bring the file's window to the top */
  239.         BringWindowToTop(hwndFile);
  240.     }
  241.     else {
  242.         /* No -- make a new window and load file into it */
  243.         AddFile(szFile);
  244.     }
  245.     }
  246. }
  247.  
  248. /****************************************************************************
  249.  *                                      *
  250.  *  FUNCTION   : SaveFile (hwnd)                        *
  251.  *                                      *
  252.  *  PURPOSE    : Saves contents of current edit control to disk.        *
  253.  *                                      *
  254.  ****************************************************************************/
  255.  
  256. VOID FAR PASCAL SaveFile( hwnd )
  257.  
  258. HWND hwnd;
  259. {
  260.     HANDLE   hT;
  261.     LPSTR    lpT;
  262.     char     szFile[128];
  263.     WORD     cch;
  264.     int      fh;
  265.     OFSTRUCT of;
  266.     HWND     hwndEdit;
  267.  
  268.     hwndEdit = GetWindowWord ( hwnd, GWW_HWNDEDIT);
  269.     GetWindowText (hwnd, szFile, sizeof(szFile));
  270.  
  271.     /* If there is no extension (control is 'Untitled') add .TXT as extension */
  272.     for (cch = FALSE, lpT = szFile; *lpT; lpT++)
  273.     switch (*lpT){
  274.         case '.':
  275.          cch = TRUE;
  276.          break;
  277.  
  278.         case '\\':
  279.         case ':' :
  280.          cch = FALSE;
  281.          break;
  282.     }
  283.     if (!cch)
  284.     LoadString (hInst, IDS_ADDEXT, lpT, lpT - (LPSTR)szFile);
  285.  
  286.     fh = OpenFile (szFile, &of, OF_WRITE | OF_CREATE);
  287.  
  288.     /* If file could not be opened, quit */
  289.     if (fh < 0){
  290.     PPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTCREATE, (LPSTR)szFile);
  291.     return;
  292.     }
  293.  
  294.     /* Find out the length of the text in the edit control */
  295.     cch = GetWindowTextLength (hwndEdit);
  296.  
  297.     /* Obtain a handle to the text buffer */
  298.     hT  = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  299.     lpT = (LPSTR)LocalLock (hT);
  300.  
  301.     /* Write out the contents of the buffer to the file. */
  302.     if (cch != _lwrite (fh, lpT, cch))
  303.     PPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);
  304.  
  305.     /* Clean up */
  306.     LocalUnlock (hT);
  307.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  308.  
  309.     _lclose (fh);
  310.  
  311.     return;
  312. }
  313.  
  314. /****************************************************************************
  315.  *                                      *
  316.  *  FUNCTION   : SetSaveFrom ()                         *
  317.  *                                      *
  318.  *  PURPOSE    : Formats the "Save 'file' to .." string.            *
  319.  *                                      *
  320.  ****************************************************************************/
  321.  
  322. VOID NEAR PASCAL SetSaveFrom ( hwnd , psz)
  323. HWND hwnd;
  324. PSTR psz;
  325. {
  326.     char szFmt[32];
  327.     char szText[160];
  328.  
  329.     /* The text string in the .RC file contains the format string... */
  330.     GetDlgItemText( hwnd, IDD_SAVEFROM, szFmt, sizeof(szFmt));
  331.  
  332.     /* NOTE: this (LPSTR) cast MUST be here... wsprintf() is a cdecl
  333.      * (C calling conventions) function with varying args... there is
  334.      * no way for the compiler to know that all strings must be LPSTR's
  335.      * and do the conversion, so we have to be careful about wsprintf()'s.
  336.      */
  337.     wsprintf ( szText, szFmt, (LPSTR)psz);
  338.  
  339.     /* set the text in the static control */
  340.     SetDlgItemText (hwnd, IDD_SAVEFROM, szText);
  341. }
  342.  
  343. /****************************************************************************
  344.  *                                      *
  345.  *  FUNCTION   : SaveAsDlgProc(hwnd, message, wParam, lParam)           *
  346.  *                                      *
  347.  *  PURPOSE    : Dialog function File/SaveAs. It waits for a filename, and  *
  348.  *       then calls SaveFile or cancels the operation.          *
  349.  *                                      *
  350.  ****************************************************************************/
  351.  
  352. BOOL FAR PASCAL __export SaveAsDlgProc( hwnd, message, wParam, lParam)
  353. HWND hwnd;
  354. WORD message;
  355. WORD wParam;
  356. LONG lParam;
  357. {
  358.     char   sz[64];
  359.     char   *pch;
  360.     BOOL   fExt;
  361.     HWND   hwndSave;
  362.  
  363.     switch (message){
  364.  
  365.     case WM_INITDIALOG:
  366.  
  367.         /* Identify the window whose contents we're saving */
  368.         hwndSave = LOWORD (lParam);
  369.  
  370.         /* Set it's name in the property list */
  371.         SetProp (hwnd, PROP_FILENAME, hwndSave);
  372.  
  373.         GetWindowText (hwndSave, sz, sizeof(sz));
  374.  
  375.         /* Set the save from string... */
  376.         SetSaveFrom (hwnd,sz);
  377.  
  378.         /* Generate a filename complete with extension */
  379.         AnsiUpper (sz);
  380.         for (fExt = FALSE, pch = sz; *pch; pch++)
  381.         if (*pch == '.')
  382.             fExt = TRUE;
  383.         else if (*pch == '\\')
  384.             fExt = FALSE;
  385.         if (!fExt)
  386.         LoadString (hInst, IDS_ADDEXT, (LPSTR)pch, pch - sz);
  387.  
  388.         /* Display the filename in the edit control */
  389.         SetDlgItemText (hwnd, IDD_SAVETO, sz);
  390.  
  391.         /* Select the entire range of text */
  392.         SendDlgItemMessage (hwnd, IDD_SAVETO, EM_SETSEL, 0, MAKELONG (0,100));
  393.  
  394.         DlgDirList (hwnd, "*.*", IDD_DIRS, IDD_PATH, ATTR_DIRS);
  395.  
  396.         /* enable OK butto iff edit control is nonempty */
  397.         if (!*sz)
  398.         EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  399.         break;
  400.  
  401.     case WM_COMMAND:
  402.         switch (wParam){
  403.         case IDCANCEL:
  404.             /* Abort operation */
  405.             EndDialog(hwnd,1);
  406.             break;
  407.  
  408.         case IDOK:
  409.            /*  Just change the title of the MDI child. The calling
  410.             *  function of ChangeFile(), which uses the title text
  411.             *  for the filename, will do the actual save.
  412.             */
  413.             hwndSave = GetProp (hwnd, PROP_FILENAME);
  414.             GetDlgItemText (hwnd, IDD_SAVETO, sz, sizeof(sz));
  415.             AnsiUpper ((LPSTR)sz);
  416.             SetWindowText (hwndSave, sz);
  417.             EndDialog (hwnd, 0);
  418.             break;
  419.  
  420.         case IDD_SAVETO:
  421.            /* If the edit control changes, check to see if its empty.
  422.             * enable OK if it contains something
  423.             */
  424.             if (HIWORD (lParam) != EN_CHANGE)
  425.             return FALSE;
  426.             EnableWindow (GetDlgItem (hwnd, IDOK),
  427.             (WORD) SendDlgItemMessage (hwnd,
  428.                            IDD_SAVETO,
  429.                            WM_GETTEXTLENGTH,
  430.                            0,
  431.                            0L));
  432.             break;
  433.  
  434.         case IDD_DIRS:
  435.             if (HIWORD(lParam)==LBN_DBLCLK){
  436.             char szT[64];
  437.  
  438.             DlgDirSelect ( hwnd, szT, IDD_DIRS);
  439.             lstrcat ( szT, "*.*");
  440.             DlgDirList (hwnd, szT, IDD_DIRS, IDD_PATH, ATTR_DIRS);
  441.             break;
  442.             }
  443.             return FALSE;
  444.  
  445.         default:
  446.             return FALSE;
  447.         }
  448.  
  449.     default:
  450.         return FALSE;
  451.     }
  452.     return TRUE;
  453. }
  454.  
  455. /****************************************************************************
  456.  *                                      *
  457.  *  FUNCTION   : ChangeFile (hwnd)                      *
  458.  *                                      *
  459.  *  PURPOSE    : Invokes the File/SaveAs dialog.                *
  460.  *                                      *
  461.  *  RETURNS    : TRUE  - if user selected OK or NO.             *
  462.  *       FALSE - otherwise.                     *
  463.  *                                      *
  464.  ****************************************************************************/
  465.  
  466. BOOL FAR PASCAL ChangeFile (hwnd)
  467. HWND hwnd;
  468. {
  469.     FARPROC lpfn;
  470.     int     i;
  471.  
  472.     lpfn = MakeProcInstance (SaveAsDlgProc, hInst);
  473.     i = DialogBoxParam (hInst, IDD_SAVEAS, hwnd, lpfn, MAKELONG (hwnd, 0));
  474.     FreeProcInstance (lpfn);
  475.     if (!i)
  476.     SetWindowWord (hwnd, GWW_UNTITLED, 0);
  477.     return !i;
  478. }
  479.