home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / mdi / regmpad / mpfile.c < prev    next >
C/C++ Source or Header  |  1995-12-29  |  16KB  |  519 lines

  1. /***************************************************************************
  2.  *                                       *
  3.  *  MODULE    : MpFile.c                           *
  4.  *                                       *
  5.  *  PURPOSE   : Contains the code for File I/O for Multipad.           *
  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.  *        MyReadFile    - 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 "multipad.h"
  28. #include <fcntl.h>
  29. #include <SYS\types.h>
  30. #include <SYS\stat.h>
  31. #include <io.h>
  32. #include <string.h>
  33.  
  34. VOID APIENTRY GetFileName(PSTR);
  35. //INT APIENTRY DialogBoxParam(HANDLE,LPSTR,HWND,FARPROC,LONG);
  36. //LPSTR WINAPI AnsiUpper(LPSTR);
  37.  
  38. OFSTRUCT    of;
  39. /****************************************************************************
  40.  *                                        *
  41.  *  FUNCTION   : AlreadyOpen(szFile)                        *
  42.  *                                        *
  43.  *  PURPOSE    : Checks to see if the file described by the string pointed  *
  44.  *         to by 'szFile' is already open.                            *
  45.  *                                        *
  46.  *  RETURNS    : a handle to the described file's window if that file is    *
  47.  *         already open;    NULL otherwise.                 *
  48.  *                                        *
  49.  ****************************************************************************/
  50.  
  51. HWND APIENTRY AlreadyOpen(CHAR *szFile)
  52. {
  53.     BOOL    fFound;
  54.     HWND    hwndCheck;
  55.     CHAR    szChild[MAX_PATH+1];
  56.     LPSTR   lpChild, lpFile, lp;
  57.  
  58.     /* Open the file with the OF_PARSE flag to obtain the fully qualified
  59.      * pathname in the OFSTRUCT structure.
  60.      */
  61.     if (HFILE_ERROR == OpenFile((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE))
  62.        return NULL;
  63.  
  64.     lpFile= CharUpper(of.szPathName);
  65.  
  66.     /* Check each MDI child window in Multipad */
  67.     for (   hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
  68.         hwndCheck;
  69.         hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
  70.     /* Initialization  for comparison */
  71.     lpChild = szChild;
  72.  
  73.     /* Skip icon title windows */
  74.     if (GetWindow(hwndCheck, GW_OWNER))
  75.         continue;
  76.  
  77.     /* Get current child window's name */
  78.     GetWindowText(hwndCheck, lpChild, MAX_PATH+1);
  79.  
  80.     CharUpper(lpChild);
  81.  
  82.     for (fFound= TRUE, lp= lpFile; (*lpChild) || (*lp); ++lpChild, ++lp)
  83.        if (*lpChild != *lp)
  84.        {
  85.           fFound= FALSE;
  86.           break;
  87.        }
  88.  
  89.     if (fFound) return(hwndCheck);
  90.     }
  91.     /* No match found -- file is not open -- return NULL handle */
  92.     return(NULL);
  93. }
  94.  
  95. /****************************************************************************
  96.  *                                        *
  97.  *  FUNCTION   : AddFile (lpName)                        *
  98.  *                                        *
  99.  *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
  100.  *         NULL, it loads a file into the window.             *
  101.  *                                        *
  102.  *  RETURNS    : HWND  - A handle to the new window.                *
  103.  *                                        *
  104.  ****************************************************************************/
  105.  
  106. HWND APIENTRY AddFile(CHAR * pName)
  107. {
  108.     HWND hwnd;
  109.  
  110.     CHAR        sz[160];
  111.     MDICREATESTRUCT mcs;
  112.  
  113.     if (!pName) {
  114.     /* The pName parameter is NULL -- load the "Untitled" string from */
  115.     /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
  116.     LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
  117.     mcs.szTitle = (LPSTR)sz;
  118.     }
  119.     else
  120.     /* Title the window with the fully qualified pathname obtained by
  121.      * calling OpenFile() with the OF_PARSE flag (in function
  122.      * AlreadyOpen(), which is called before AddFile().
  123.      */
  124.     mcs.szTitle = of.szPathName;
  125.  
  126.     mcs.szClass = szChild;
  127.     mcs.hOwner    = hInst;
  128.  
  129.     /* Use the default size for the window */
  130.     mcs.x = mcs.cx = CW_USEDEFAULT;
  131.     mcs.y = mcs.cy = CW_USEDEFAULT;
  132.  
  133.     /* Set the style DWORD of the window to default */
  134.     mcs.style = styleDefault;
  135.  
  136.     /* tell the MDI Client to create the child */
  137.     hwnd = (HWND)SendMessage (hwndMDIClient,
  138.                   WM_MDICREATE,
  139.                   0,
  140.                   (LONG)(LPMDICREATESTRUCT)&mcs);
  141.  
  142.     /* Did we get a file? Read it into the window */
  143.     if (pName){
  144.     if (!LoadFile(hwnd, pName)){
  145.         /* File couldn't be loaded -- close window */
  146.         SendMessage(hwndMDIClient, WM_MDIDESTROY, (DWORD) hwnd, 0L);
  147.     }
  148.     }
  149.  
  150.     return hwnd;
  151. }
  152.  
  153. /****************************************************************************
  154.  *                                        *
  155.  *  FUNCTION   : LoadFile (lpName)                        *
  156.  *                                        *
  157.  *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
  158.  *         file into the window's edit control child.                 *
  159.  *                                        *
  160.  *  RETURNS    : TRUE  - If file is sucessfully loaded.             *
  161.  *         FALSE - Otherwise.                        *
  162.  *                                        *
  163.  ****************************************************************************/
  164.  
  165. INT APIENTRY LoadFile (
  166.     HWND hwnd,
  167.     CHAR * pName)
  168. {
  169.     LONG   wLength;
  170.     HANDLE hT;
  171.     LPSTR  lpB;
  172.     HWND   hwndEdit;
  173.     HFILE  fh;
  174.     OFSTRUCT  of;
  175.     hwndEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
  176.  
  177.     /* The file has a title, so reset the UNTITLED flag. */
  178.     SetWindowWord(hwnd, GWW_UNTITLED, FALSE);
  179.  
  180.     fh = OpenFile(pName, &of, OF_READ);  /* JAP was 0, which is OF_READ)*/
  181.  
  182.     /* Make sure file has been opened correctly */
  183.     if ( fh < 0 )
  184.     goto error;
  185.  
  186.     /* Find the length of the file */
  187.     wLength = (DWORD)_llseek(fh, 0L, 2);
  188.     _llseek(fh, 0L, 0);
  189.  
  190.     /* Attempt to reallocate the edit control's buffer to the file size */
  191.     hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  192.     if (LocalReAlloc(hT, wLength+1, LHND) == NULL) {
  193.     /* Couldn't reallocate to new size -- error */
  194.     _lclose(fh);
  195.     goto error;
  196.     }
  197.  
  198.     /* read the file into the buffer */
  199.     if (wLength != (LONG)_lread(fh, (lpB = (LPSTR)LocalLock (hT)), (UINT)wLength))
  200.     MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);
  201.  
  202.     /* Zero terminate the edit buffer */
  203.     lpB[wLength] = 0;
  204.     LocalUnlock (hT);
  205.  
  206.     SendMessage (hwndEdit, EM_SETHANDLE, (UINT)hT, 0L);
  207.     _lclose(fh);
  208.  
  209.     return TRUE;
  210.  
  211. error:
  212.     /* Report the error and quit */
  213.     MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
  214.     return FALSE;
  215. }
  216.  
  217. /****************************************************************************
  218.  *                                        *
  219.  *  FUNCTION   : MyReadFile(hwnd)                        *
  220.  *                                        *
  221.  *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
  222.  *         the user for a file name and responds appropriately.        *
  223.  *                                        *
  224.  ****************************************************************************/
  225.  
  226. VOID APIENTRY MyReadFile(HWND hwnd)
  227. {
  228.     CHAR    szFile[128];
  229.     HWND    hwndFile;
  230.  
  231.     GetFileName (szFile);
  232.  
  233.     /* If the result is not the empty string -- take appropriate action */
  234.     if (*szFile) {
  235.         /* Is file already open?? */
  236.         if (hwndFile = AlreadyOpen(szFile)) {
  237.             /* Yes -- bring the file's window to the top */
  238.             BringWindowToTop(hwndFile);
  239.         }
  240.         else {
  241.             /* No -- make a new window and load file into it */
  242.             AddFile(szFile);
  243.         }
  244.     }
  245.     UNREFERENCED_PARAMETER(hwnd);
  246. }
  247.  
  248. /****************************************************************************
  249.  *                                        *
  250.  *  FUNCTION   : SaveFile (hwnd)                        *
  251.  *                                        *
  252.  *  PURPOSE    : Saves contents of current edit control to disk.        *
  253.  *                                        *
  254.  ****************************************************************************/
  255.  
  256. VOID APIENTRY SaveFile(HWND hwnd)
  257. {
  258.     HANDLE   hT;
  259.     LPSTR    lpT;
  260.     CHAR     szFile[128];
  261.     INT      cch;
  262.     INT      fh;
  263. //    OFSTRUCT of;
  264.     HWND     hwndEdit;
  265.  
  266.     PSTR     pch;
  267.  
  268.     hwndEdit = (HWND)GetWindowLong ( hwnd, GWL_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 = CharNext(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 = open(szFile, O_BINARY | O_WRONLY | O_CREAT, S_IWRITE);
  287.  
  288.     /* If file could not be opened, quit */
  289.     if (fh < 0){
  290.     MPError (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 != write(fh, lpT, cch))
  303.     MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);
  304.  
  305.     /* Clean up */
  306.     LocalUnlock (hT);
  307.     SendMessage (hwndEdit, EM_SETHANDLE, (UINT)hT, 0L);
  308.  
  309.     close(fh);
  310.  
  311.     return;
  312.     UNREFERENCED_PARAMETER(pch);
  313. }
  314.  
  315. /****************************************************************************
  316.  *                                        *
  317.  *  FUNCTION   : SetSaveFrom ()                         *
  318.  *                                        *
  319.  *  PURPOSE    : Formats the "Save 'file' to .." string.                    *
  320.  *                                        *
  321.  ****************************************************************************/
  322.  
  323. VOID NEAR PASCAL SetSaveFrom (
  324.     HWND hwnd,
  325.     PSTR psz)
  326. {
  327.     CHAR szFmt[32];
  328.     CHAR szText[160];
  329.  
  330.     /* The text string in the .RC file contains the format string... */
  331.     GetDlgItemText( hwnd, IDD_SAVEFROM, szFmt, sizeof(szFmt));
  332.  
  333.     /* NOTE: this (LPSTR) cast MUST be here... wsprintf() is a cdecl
  334.      * (C calling conventions) function with varying args... there is
  335.      * no way for the compiler to know that all strings must be LPSTR's
  336.      * and do the conversion, so we have to be careful about wsprintf()'s.
  337.      */
  338.     wsprintf ( szText, szFmt, (LPSTR)psz);
  339.  
  340.     /* set the text in the static control */
  341.     SetDlgItemText (hwnd, IDD_SAVEFROM, szText);
  342. }
  343.  
  344. /****************************************************************************
  345.  *                                        *
  346.  *  FUNCTION   : SaveAsDlgProc(hwnd, message, wParam, lParam)            *
  347.  *                                        *
  348.  *  PURPOSE    : Dialog function File/SaveAs. It waits for a filename, and  *
  349.  *         then calls SaveFile or cancels the operation.            *
  350.  *                                        *
  351.  ****************************************************************************/
  352.  
  353. BOOL APIENTRY SaveAsDlgProc(
  354.     HWND hwnd,
  355.     UINT message,
  356.     UINT wParam,
  357.     LONG lParam)
  358. {
  359.     CHAR   sz[64];
  360.     CHAR   *pch;
  361.     BOOL   fExt;
  362.     HWND   hwndSave;
  363.  
  364.     switch (message){
  365.  
  366.     case WM_INITDIALOG:
  367.  
  368.         /* Identify the window whose contents we're saving */
  369. #ifdef ORGCODE
  370.         hwndSave = LOWORD (lParam);
  371. #else
  372.         hwndSave = (HWND)lParam;        /*passed in from another procedure*/
  373. #endif
  374.         /* Set it's name in the property list */
  375.         SetProp (hwnd, PROP_FILENAME, hwndSave);
  376.  
  377.         GetWindowText (hwndSave, sz, sizeof(sz));
  378.  
  379.         /* Set the save from string... */
  380.         SetSaveFrom (hwnd,sz);
  381.  
  382.         /* Generate a filename complete with extension */
  383.         CharUpper (sz);
  384.         for (fExt = FALSE, pch = sz; *pch; pch = CharNext(pch))
  385.         if (*pch == '.')
  386.             fExt = TRUE;
  387.         else if (*pch == '\\')
  388.             fExt = FALSE;
  389.         if (!fExt)
  390.         LoadString (hInst, IDS_ADDEXT, (LPSTR)pch, pch - sz);
  391.  
  392.         /* Display the filename in the edit control */
  393.         SetDlgItemText (hwnd, IDD_SAVETO, sz);
  394.  
  395.         /* Select the entire range of text */
  396.         SendMessage(GetDlgItem(hwnd, IDD_SAVETO), EM_SETSEL, GET_EM_SETSEL_MPS(0, 100));
  397.  
  398.         DlgDirList (hwnd, "*.*", (INT)IDD_DIRS, (INT)IDD_PATH, (WORD)ATTR_DIRS);
  399.  
  400.         /* enable OK butto iff edit control is nonempty */
  401.         if (!*sz)
  402.         EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  403.         break;
  404.  
  405.     case WM_COMMAND:
  406.         switch (LOWORD(wParam)){
  407.         case IDCANCEL:
  408.             /* Abort operation */
  409.             EndDialog(hwnd,1);
  410.             break;
  411.  
  412.         case IDOK:
  413.            /*  Just change the title of the MDI child. The calling
  414.             *  function of ChangeFile(), which uses the title text
  415.             *  for the filename, will do the actual save.
  416.             */
  417.             hwndSave = GetProp (hwnd, PROP_FILENAME);
  418.             GetDlgItemText (hwnd, IDD_SAVETO, sz, sizeof(sz));
  419.             CharUpper ((LPSTR)sz);
  420.             SetWindowText (hwndSave, sz);
  421.             EndDialog (hwnd, 0);
  422.             break;
  423.  
  424.         case IDD_SAVETO:
  425.            /* If the edit control changes, check to see if its empty.
  426.             * enable OK if it contains something
  427.             */
  428.             if (HIWORD (lParam) != EN_CHANGE)
  429.             return FALSE;
  430.             EnableWindow (GetDlgItem (hwnd, IDOK),
  431.                 SendDlgItemMessage (hwnd,
  432.                            IDD_SAVETO,
  433.                            WM_GETTEXTLENGTH,
  434.                            0,
  435.                            0L));
  436.             break;
  437.  
  438.         case IDD_DIRS:
  439.             if (HIWORD(lParam)==LBN_DBLCLK){
  440.             CHAR szT[64];
  441.  
  442.             DlgDirSelectEx(hwnd, szT, 64, IDD_DIRS);
  443.             lstrcat ( szT, "*.*");
  444.             DlgDirList (hwnd, szT, (INT)IDD_DIRS, (INT)IDD_PATH, (WORD)ATTR_DIRS);
  445.             break;
  446.             }
  447.             return FALSE;
  448.  
  449.         default:
  450.             return FALSE;
  451.         }
  452.  
  453.     default:
  454.         return FALSE;
  455.     }
  456.     return TRUE;
  457. }
  458.  
  459. /****************************************************************************
  460.  *                                        *
  461.  *  FUNCTION   : ChangeFile (hwnd)                        *
  462.  *                                        *
  463.  *  PURPOSE    : Invokes the File/SaveAs dialog.                *
  464.  *                                        *
  465.  *  RETURNS    : TRUE  - if user selected OK or NO.                *
  466.  *         FALSE - otherwise.                        *
  467.  *                                        *
  468.  ****************************************************************************/
  469.  
  470. BOOL APIENTRY ChangeFile (HWND hwnd)
  471. {
  472.     INT     i;
  473.  
  474. #ifdef NOTCOMMONDIALOGS
  475.     i = DialogBoxParam (hInst, IDD_SAVEAS, hwnd, SaveAsDlgProc, (LONG)hwnd);
  476.     if (!i)
  477.         SetWindowWord (hwnd, GWW_UNTITLED, 0);
  478.     return !i;
  479. #else
  480.     OPENFILENAME ofn;
  481.     CHAR szFilterSpec[128];                       /* file type filters */
  482.     CHAR szBuffer[128];
  483.  
  484.     #define MAXFILENAME 256
  485.     CHAR szFileName[MAXFILENAME];
  486.     CHAR szFileTitle[MAXFILENAME];
  487.  
  488.     LoadString(hInst, IDS_SAVEFILTERSPEC, szFilterSpec, sizeof (szFilterSpec));
  489.     LoadString(hInst, IDS_SAVEFILETITLE, szBuffer, sizeof (szBuffer));
  490.  
  491.     strcpy(szFileName, "");   /* these need be NULL*/
  492.     strcpy(szFileTitle, "");
  493.  
  494.     /* fill in non-variant fields of OPENFILENAME struct. */
  495.     ofn.lStructSize       = sizeof(OPENFILENAME);
  496.     ofn.hwndOwner          = hwnd;
  497.     ofn.lpstrFilter          = szFilterSpec;
  498.     ofn.lpstrCustomFilter = NULL;
  499.     ofn.nMaxCustFilter      = 0;
  500.     ofn.nFilterIndex      = 0;
  501.     ofn.lpstrFile         = szFileName;
  502.     ofn.nMaxFile          = MAXFILENAME;
  503.     ofn.lpstrInitialDir   = NULL;
  504.     ofn.lpstrFileTitle    = szFileTitle;
  505.     ofn.nMaxFileTitle     = MAXFILENAME;
  506.     ofn.lpstrTitle        = szBuffer;
  507.     ofn.lpstrDefExt       = "TXT";
  508.     ofn.Flags             = OFN_HIDEREADONLY;
  509.     /* Use standard open dialog */
  510.     i = GetSaveFileName ((LPOPENFILENAME)&ofn);
  511.     CharUpper ((LPSTR)ofn.lpstrFile);
  512.     SetWindowText (hwnd, ofn.lpstrFile);
  513.     if (i)
  514.         SetWindowWord (hwnd, GWW_UNTITLED, 0);
  515.     return i;
  516. #endif
  517.  
  518. }
  519.