home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / gw / oddev.exe / MPFILE.C < prev    next >
Text File  |  1994-08-09  |  25KB  |  817 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  MODULE    : MpFile.c                                                   *
  4.  *                                                                         *
  5.  *  PURPOSE   : Contains the code for File I/O for MultODMA                *
  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 "multipad.h"
  28. #include "commdlg.h"
  29.  
  30. /* local OF variable for parsing DOS filenames */
  31. OFSTRUCT    of;
  32.  
  33. /* routine prototype for CallBack function  */
  34. LPSTR FAR OptionsCallBack(DWORD dwEnvData,
  35.                                          LPSTR lpszFormat,
  36.                                          LPVOID lpData);
  37.  
  38.  
  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 AlreadyOpen(char *szFile)
  52. {
  53.     int     iDiff;
  54.     HWND    hwndCheck;
  55.     LPSTR   lpFile;
  56.     int     wFileTemp;
  57.     LPSTR    lpCurFile;
  58.     HANDLE    hFile;
  59.     BOOL    bODMA;
  60.  
  61.     /* NULL pointer passed in? */
  62.     if (szFile == (char *) 0 || szFile[0] == NULL)
  63.         return (HWND) 0;
  64.  
  65.     /* ODMA docID passed in? */
  66.     if (szFile[0] == ':' && szFile[1] == ':') {
  67.         bODMA = TRUE;
  68.     }
  69.     else {
  70.         bODMA = FALSE;
  71.         /* Open the file with the OF_PARSE flag to obtain the fully qualified
  72.          * pathname in the OFSTRUCT structure.
  73.          */
  74.         wFileTemp = OpenFile ((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE);
  75.         if (! wFileTemp)
  76.             return(NULL);
  77.         _lclose (wFileTemp);
  78.     }
  79.  
  80.     /* Check each MDI child window in MultODMA */
  81.     for (hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
  82.             hwndCheck;
  83.             hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
  84.         /* Initialization  for comparison */
  85.         if (bODMA)
  86.             lpFile = AnsiUpper(szFile);
  87.         else
  88.             lpFile = AnsiUpper((LPSTR) of.szPathName);
  89.         iDiff = 0;
  90.  
  91.         /* Skip icon title windows */
  92.         if (GetWindow(hwndCheck, GW_OWNER))
  93.             continue;
  94.  
  95.         /* ODMA docID? */
  96.         if (bODMA)
  97.             /* Get current child window's ODMA docID */
  98.             hFile = (HANDLE) GetWindowWord(hwndCheck, GWW_ODMADOCID);
  99.         else
  100.             /* Get current child window's name */
  101.             hFile = (HANDLE) GetWindowWord(hwndCheck, GWW_FILEPTR);
  102.         if (hFile == (HANDLE) 0)
  103.             continue;
  104.         lpCurFile =  AnsiUpper((LPSTR) GlobalLock(hFile));
  105.  
  106.         /* Compare window name with given name */
  107.         while ((*lpCurFile) && (*lpFile) && (!iDiff)){
  108.             if (*lpCurFile++ != *lpFile++)
  109.                 iDiff = 1;
  110.         }
  111.  
  112.         /* Release global filename memory */
  113.         GlobalUnlock(hFile);
  114.  
  115.         /* If the two names matched, the file is already   */
  116.         /* open -- return handle to matching child window. */
  117.         if (!iDiff)
  118.             return(hwndCheck);
  119.     }
  120.  
  121.     /* No match found -- file is not open -- return NULL handle */
  122.     return(NULL);
  123. }
  124.  
  125. /****************************************************************************
  126.  *                                        *
  127.  *  FUNCTION   : AddFile (lpName)                        *
  128.  *                                        *
  129.  *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
  130.  *         NULL, it loads a file into the window.             *
  131.  *                                        *
  132.  *  RETURNS    : HWND  - A handle to the new window.                *
  133.  *                                        *
  134.  ****************************************************************************/
  135.  
  136. HWND FAR PASCAL AddFile(pName)
  137. char * pName;
  138. {
  139.     HWND hwnd;
  140.  
  141.     char        sz[160];
  142.     MDICREATESTRUCT mcs;
  143.  
  144.     if (!pName || *pName == NULL) {
  145.         /* The pName parameter is NULL -- load the "Untitled" string from */
  146.         /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
  147.         LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
  148.         mcs.szTitle = (LPSTR)sz;
  149.     }
  150.     else {
  151.         /* default to using fully qualified path */
  152.         mcs.szTitle = of.szPathName;
  153.  
  154.         /* if ODMA docID - set title with correct text */
  155.         if (pName[0] == ':' && pName[1] == ':') {
  156.             if (ODMGetDocInfo(odmHandle, pName, ODM_TITLETEXT, sz, 160) == 0)
  157.                 mcs.szTitle = (LPSTR) sz;
  158.         }
  159.     }
  160.  
  161.     mcs.szClass = szChild;
  162.     mcs.hOwner    = hInst;
  163.  
  164.     /* Use the default size for the window */
  165.     mcs.x = mcs.cx = CW_USEDEFAULT;
  166.     mcs.y = mcs.cy = CW_USEDEFAULT;
  167.  
  168.     /* Set the style DWORD of the window to default */
  169.     mcs.style = styleDefault;
  170.  
  171.     /* tell the MDI Client to create the child */
  172.     hwnd = (WORD)SendMessage (hwndMDIClient,
  173.                   WM_MDICREATE,
  174.                   0,
  175.                   (LONG)(LPMDICREATESTRUCT)&mcs);
  176.  
  177.     /* Did we get a file? Read it into the window */
  178.     if (pName && *pName != NULL){
  179.         if (!LoadFile(hwnd, pName)){
  180.             /* File couldn't be loaded -- close window */
  181.             SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwnd, 0L);
  182.         }
  183.     }
  184.  
  185.     return hwnd;
  186. }
  187.  
  188. /****************************************************************************
  189.  *                                        *
  190.  *  FUNCTION   : LoadFile (lpName)                        *
  191.  *                                        *
  192.  *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
  193.  *         file into the window's edit control child.                 *
  194.  *                                        *
  195.  *  RETURNS    : TRUE  - If file is sucessfully loaded.             *
  196.  *         FALSE - Otherwise.                        *
  197.  *                                        *
  198.  ****************************************************************************/
  199.  
  200. int FAR PASCAL LoadFile (hwnd, pName)
  201. HWND hwnd;
  202. char * pName;
  203. {
  204.     WORD   wLength;
  205.     HANDLE hT;
  206.     LPSTR  lpB;
  207.     HWND   hwndEdit;
  208.     int    fh;
  209.     char   szFName[256];
  210.  
  211.     hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);
  212.  
  213.     /* The file has a title, so reset the UNTITLED flag. */
  214.     SetWindowWord(hwnd, GWW_UNTITLED, FALSE);
  215.  
  216.     /* ODMA docID passed in? */
  217.     if (pName[0] == ':' && pName[1] == ':') {
  218.         /* Place docID into global memory */
  219.         hT = GlobalAlloc(GHND, (DWORD) (lstrlen(pName) + 1));
  220.         if (hT == (HANDLE) 0) {
  221.             /* Report the error and quit */
  222.             MPError(hwnd, MB_OK | MB_ICONHAND, IDS_NOMEM, (LPSTR)pName);
  223.             return FALSE;
  224.             }
  225.         lpB = (LPSTR) GlobalLock(hT);
  226.         lstrcpy (lpB, pName);
  227.         GlobalUnlock(hT);
  228.         /* store fileptr in window word */
  229.         SetWindowWord(hwnd, GWW_ODMADOCID, hT);
  230.     }
  231.  
  232.     /* default to opening the passed in filename */
  233.     lstrcpy(szFName, pName);
  234.     /* filename an ODMA docID? */
  235.     if (pName[0] == ':' && pName[1] == ':') {
  236.         /* convert docID into DOS filename */
  237.         switch (ODMOpenDoc( odmHandle, ODM_MODIFYMODE, pName, szFName)) {
  238.             case 0:    /* SUCCESS! */
  239.                 /* set flag to READ-WRITE access */
  240.                 SetWindowWord(hwnd, GWW_READ_ONLY, FALSE);
  241.                 break;
  242.             case ODM_E_ACCESS: /* User doesn't have rights to open doc */
  243.             case ODM_E_INUSE: /* Can't open in modify mode - try read only */
  244.                 if (MPError (hwnd, MB_YESNO | MB_ICONQUESTION, IDS_READONLY,
  245.                      (LPSTR) pName) == IDNO)
  246.                         return FALSE;    /* don't try opening read-only */
  247.                 if (ODMOpenDoc( odmHandle, ODM_VIEWMODE, pName, szFName) == 0) {
  248.                     /* set window flag to READ ONLY access */
  249.                     SetWindowWord(hwnd, GWW_READ_ONLY, TRUE);
  250.                     break;
  251.                     }
  252.                 /* error opening file in ANY mode - fall thru to error */
  253.             default:
  254.                 /* error getting filename */
  255.                 MPError(hwnd, MB_OK | MB_ICONHAND, IDS_NOMEM, (LPSTR)pName);
  256.                 return FALSE;
  257.         }
  258.     }
  259.  
  260.     /* Place filename into global memory */
  261.     hT = GlobalAlloc(GHND, (DWORD) (lstrlen(szFName) + 1));
  262.     if (hT == (HANDLE) 0) {
  263.         /* Report the error and quit */
  264.         MPError(hwnd, MB_OK | MB_ICONHAND, IDS_NOMEM, (LPSTR)pName);
  265.         return FALSE;
  266.         }
  267.     lpB = (LPSTR) GlobalLock(hT);
  268.     lstrcpy (lpB, szFName);
  269.     GlobalUnlock(hT);
  270.     /* store fileptr in window word */
  271.     SetWindowWord(hwnd, GWW_FILEPTR, hT);
  272.  
  273.     fh = _lopen (szFName, 0);
  274.  
  275.     /* Make sure file has been opened correctly */
  276.     if ( fh < 0 )
  277.         goto error;
  278.  
  279.     /* Find the length of the file */
  280.     wLength = (WORD)_llseek (fh, 0L, 2);
  281.     _llseek (fh, 0L, 0);
  282.  
  283.     /* Attempt to reallocate the edit control's buffer to the file size */
  284.     hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  285.     if (LocalReAlloc(hT, wLength+1, LHND) == NULL) {
  286.         /* Couldn't reallocate to new size -- error */
  287.         _lclose (fh);
  288.         goto error;
  289.     }
  290.  
  291.     /* read the file into the buffer */
  292.     if (wLength != _lread (fh, (lpB = (LPSTR)LocalLock (hT)), wLength))
  293.         MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);
  294.  
  295.     /* Zero terminate the edit buffer */
  296.     lpB[wLength] = 0;
  297.     LocalUnlock (hT);
  298.  
  299.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  300.     _lclose (fh);
  301.  
  302.     /* set title bar text */
  303.     /* default will use DOS filename */
  304.     if (pName[0] == ':' && pName[1] == ':') {
  305.         char    sz[128];
  306.  
  307.         /* get ODMA document title text */
  308.         if (ODMGetDocInfo(odmHandle, pName, ODM_TITLETEXT, sz, 128) == 0)
  309.             lstrcpy(szFName, sz);
  310.     }
  311.  
  312.     /* if read-only flag set - append READONLY to title */
  313.     if (GetWindowWord(hwnd, GWW_READ_ONLY) != FALSE) {
  314.         char    sz[128];
  315.  
  316.         LoadString(hInst, IDS_RDONLY_TITLE, sz, 127);
  317.         lstrcat(szFName, sz);
  318.     }
  319.  
  320.     SetWindowText(hwnd, szFName);
  321.  
  322.     return TRUE;
  323.  
  324. error:
  325.     /* Report the error and quit */
  326.     MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
  327.     return FALSE;
  328. }
  329.  
  330. /****************************************************************************
  331.  *                                                                          *
  332.  *  FUNCTION   : SelectFile(hwnd)                                           *
  333.  *                                                                          *
  334.  *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
  335.  *               the user for a file name and responds appropriately.       *
  336.  *                                                                          *
  337.  *  MODS       : BHC 8/9/94 - Renamed from ReadFile to avoid conflict with  *
  338.  *               Win32 function of the same name.                           *
  339.  ****************************************************************************/
  340.  
  341. VOID FAR PASCAL SelectFile(HWND hwnd)
  342. {
  343.     char    szFile[128];
  344. #ifdef FILE_TO_FRONT
  345.     HWND    hwndFile;
  346. #endif /* FILE_TO_FRONT */
  347.     OPENFILENAME of;
  348.     DWORD    dwFlags;
  349.     ODMSTATUS iRet;
  350.  
  351.     /* default to application select (no ODMA present) */
  352.     iRet = ODM_E_APPSELECT;
  353.  
  354.     /* ODMA present? */
  355.     if (odmHandle) {
  356.         dwFlags = 0;
  357.         /* call ODMA for open dialog */
  358.         iRet = ODMSelectDoc( odmHandle, szFile, (LPDWORD) &dwFlags );
  359.     }
  360.  
  361.     switch (iRet) {
  362.         case 0:
  363.             /* ODMA handled FileOpen dialog - and passed back an ODMA docID */
  364.             break;
  365.         case ODM_E_APPSELECT:
  366.         case ODM_E_NODMS:
  367.             /* normal DOS file open dialog */
  368.             lstrcpy(szFile, "*.TXT");
  369.  
  370.             of.lStructSize  = sizeof(OPENFILENAME);
  371.             of.hwndOwner    = hwnd;
  372.             of.lpstrFilter  = (LPSTR)"Text Files (*.TXT)\0*.TXT\0";
  373.             of.lpstrCustomFilter = NULL;
  374.             of.nFilterIndex = 1;
  375.             of.lpstrFile    = (LPSTR)szFile;
  376.             of.nMaxFile     = 128;
  377.             of.lpstrInitialDir = NULL;
  378.             of.lpstrTitle   = NULL;
  379.             of.Flags        = OFN_HIDEREADONLY|OFN_FILEMUSTEXIST;
  380.             of.lpstrDefExt  = NULL;
  381.  
  382.             if(!GetOpenFileName(&of))
  383.                return;
  384.             break;
  385.         case ODM_E_CANCEL:
  386.             /* user cancelled dialog */
  387.             szFile[0] = NULL;
  388.             break;
  389.         default:
  390.             /* ODMA error - possibly display error message here */
  391.             szFile[0] = NULL;
  392.             break;
  393.     }
  394.  
  395.  
  396.     /* If the result is not the empty string -- take appropriate action */
  397.     if (*szFile) {
  398. /* undefine this section if you want multiple open requests to simply */
  399. /* bring the window with the file to the front. Otherwise this code */
  400. /* will allow the file to be opened in read-only mode. */
  401. #ifdef FILE_TO_FRONT
  402.          /* Is file already open?? */
  403.          hwndFile = AlreadyOpen(szFile);
  404.          if (hwndFile) {
  405.             /* Yes -- bring the file's window to the top */
  406.             BringWindowToTop(hwndFile);
  407.          }
  408.          else {
  409.             /* No -- make a new window and load file into it */
  410.             AddFile(szFile);
  411.          }
  412. #endif /* FILE_TO_FRONT */
  413.         AddFile(szFile);
  414.     }
  415. }
  416.  
  417. /****************************************************************************
  418.  *                                        *
  419.  *  FUNCTION   : SaveFile (hwnd)                        *
  420.  *                                        *
  421.  *  PURPOSE    : Saves contents of current edit control to disk.        *
  422.  *                                        *
  423.  ****************************************************************************/
  424.  
  425. VOID FAR PASCAL SaveFile( HWND hwnd )
  426. {
  427.     HANDLE   hT, hFile;
  428.     LPSTR    lpFile, lpT;
  429.     char     szFile[128];
  430.     WORD     cch;
  431.     int      fh;
  432.     OFSTRUCT of;
  433.     HWND     hwndEdit;
  434.     HCURSOR     hCurs;
  435.     POINT     ptCaret;
  436.  
  437.     hwndEdit = GetWindowWord ( hwnd, GWW_HWNDEDIT);
  438.     hFile = (HANDLE) GetWindowWord(hwnd, GWW_FILEPTR);
  439.     if (hFile == (HANDLE) 0) {
  440.         szFile[0] = NULL;
  441.         MPError (hwnd, MB_OK | MB_ICONHAND, IDS_NOTNAMED, (LPSTR) szFile);
  442.         return;
  443.     }
  444.     else {
  445.         lpFile = (LPSTR) GlobalLock(hFile);
  446.         lstrcpy(szFile, lpFile);
  447.         GlobalUnlock(hFile);
  448.     }
  449.  
  450.     /* ODMA docID? */
  451.     if (GetWindowWord(hwnd, GWW_ODMADOCID) == 0) {
  452.         /* normal DOS filename - add extension */
  453.         lpFile = (LPSTR) GlobalLock(hFile);
  454.  
  455.         /* store temporary copy of filename */
  456.         lstrcpy (szFile, lpFile);
  457.  
  458.         /* If there is no extension (control is 'Untitled') add .TXT as extension */
  459.         for (cch = FALSE; *lpFile; lpFile++)
  460.         switch (*lpFile){
  461.             case '.':
  462.              cch = TRUE;
  463.              break;
  464.  
  465.             case '\\':
  466.             case ':' :
  467.              cch = FALSE;
  468.              break;
  469.         }
  470.         if (!cch) {
  471.             char    szExt[5];
  472.  
  473.             // Get default extension from resource file
  474.             LoadString (hInst, IDS_ADDEXT, szExt, 4);
  475.             // Append extension to filename
  476.             lstrcat(szFile, szExt);
  477.         }
  478.  
  479.         /* unlock global file pointer */
  480.         GlobalUnlock(hFile);
  481.     }
  482.  
  483.     fh = OpenFile (szFile, &of, OF_WRITE | OF_CREATE);
  484.  
  485.     /* If file could not be opened, quit */
  486.     if (fh < 0){
  487.         MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTCREATE, (LPSTR)szFile);
  488.         return;
  489.     }
  490.  
  491.     /* Get the current caret position */
  492.     GetCaretPos( (POINT FAR *) &ptCaret );
  493.     /* Hide the caret */
  494.     HideCaret(hwnd);
  495.     /* Display the 'please wait' cursor */
  496.     hCurs = SetCursor( LoadCursor (NULL, IDC_WAIT) );
  497.  
  498.     /* Find out the length of the text in the edit control */
  499.     cch = GetWindowTextLength (hwndEdit);
  500.  
  501.     /* Obtain a handle to the text buffer */
  502.     hT    = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  503.     lpT = (LPSTR)LocalLock (hT);
  504.  
  505.     /* Write out the contents of the buffer to the file. */
  506.     if (cch != _lwrite (fh, lpT, cch))
  507.         MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);
  508.     else {
  509.         SetWindowWord (hwnd, GWW_CHANGED, FALSE);
  510.         SetWindowWord (hwnd, GWW_ODMA_SAVE, TRUE);
  511.     }
  512.  
  513.     /* Clean up */
  514.     LocalUnlock (hT);
  515.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  516.  
  517.     _lclose (fh);
  518.  
  519.     /* put new filename into global memory */
  520.     hT = GlobalAlloc(GHND, (DWORD) (lstrlen(szFile) + 1));
  521.     if (hT) {
  522.         lpT = (LPSTR) GlobalLock(hT);
  523.         lstrcpy(lpT, szFile);
  524.         GlobalUnlock(hT);
  525.         SetWindowWord(hwnd, GWW_FILEPTR, hT);
  526.         GlobalFree(hFile);
  527.         hFile = hT;
  528.     }
  529.  
  530.     /* ODMA docID present? */
  531.     hT = (HANDLE) GetWindowWord(hwnd, GWW_ODMADOCID);
  532.  
  533.     /* put new title text? (not if ODMA docID) */
  534.     if ((hT == (HANDLE) 0) && hFile) {
  535.         /* lock filename */
  536.         lpT = (LPSTR) GlobalLock(hFile);
  537.         SetWindowText(hwnd, lpT);
  538.         GlobalUnlock(hFile);
  539.     }
  540.  
  541.     /* Show the caret */
  542.     ShowCaret(hwnd);
  543.     /* Set the original caret position */
  544.     SetCaretPos( (int) ptCaret.x, (int) ptCaret.y );
  545.     /* Redisplay the original cursor */
  546.     SetCursor( hCurs );
  547.  
  548.     return;
  549. }
  550.  
  551.  
  552. /****************************************************************************
  553.  *                                        *
  554.  *  FUNCTION   : ChangeFile (hwnd)                        *
  555.  *                                        *
  556.  *  PURPOSE    : Invokes the File/SaveAs dialog.                *
  557.  *                                        *
  558.  *  RETURNS    : TRUE  - if user selected OK or NO.                *
  559.  *         FALSE - otherwise.                        *
  560.  *                                        *
  561.  ****************************************************************************/
  562.  
  563. BOOL FAR PASCAL ChangeFile (hwnd)
  564. HWND hwnd;
  565. {
  566.     char    szFile[128];
  567.     OPENFILENAME of;
  568.     HANDLE    hT;
  569.     LPSTR    lpT;
  570.     ODMSTATUS iRet;
  571.     BOOL    bNewDoc;
  572.  
  573.     /* default to application select (no ODMA present) */
  574.     iRet = ODM_E_APPSELECT;
  575.     /* Default to not a new doc */
  576.     bNewDoc = FALSE;
  577.  
  578.     /* new document? */
  579.     if (odmHandle && GetWindowWord(hwnd, GWW_UNTITLED)) {
  580.         /* call ODMA NewDoc */
  581.         iRet = ODMNewDoc( odmHandle, szFile, 0, "TEXT", NULL);
  582.         switch (iRet) {
  583.             case 0:
  584.                 /* SUCCESS! new docID */
  585.                 /* store new docID in window handle */
  586.                 hT = GlobalAlloc(GHND, (DWORD) (lstrlen(szFile) + 1));
  587.                 if (hT == (HANDLE) 0) {
  588.                     /* Report the error and quit */
  589.                     MPError(hwnd, MB_OK | MB_ICONHAND, IDS_NOMEM, (LPSTR)szFile);
  590.                     return FALSE;
  591.                     }
  592.                 lpT = (LPSTR) GlobalLock(hT);
  593.                 lstrcpy (lpT, szFile);
  594.                 GlobalUnlock(hT);
  595.                 /* store fileptr in window word */
  596.                 SetWindowWord(hwnd, GWW_ODMADOCID, hT);
  597.                 bNewDoc = TRUE;
  598.                 break;
  599.             case ODM_E_APPSELECT:
  600.             case ODM_E_NODMS:
  601.                 /* let normal DOS handle it */
  602.                 break;
  603.             case ODM_E_CANCEL:
  604.                 return (FALSE);
  605.             default:
  606.                 /* display possible error message here */
  607.                 return (FALSE);
  608.         }
  609.     }
  610.  
  611.     /* ODMA docID? */
  612.     hT = GetWindowWord(hwnd, GWW_ODMADOCID);
  613.     if (hT) {
  614.         FARPROC    fpCallBack;
  615.  
  616.         /* get procedure address for call back routine */
  617.         fpCallBack = MakeProcInstance((FARPROC) OptionsCallBack, hInst);
  618.         lpT = (LPSTR) GlobalLock(hT);
  619.         /* call ODMA for SaveAs */
  620.         iRet = ODMSaveAs( odmHandle, lpT, (LPSTR) szFile, "TEXT",
  621.             (ODMSAVEASCALLBACK) fpCallBack, (LPVOID) "App Instance Data here");
  622.         /* free procedure address */
  623.         FreeProcInstance(fpCallBack);
  624.         /* is passed out docID same as passed in? */
  625.         if (szFile[0] == NULL && iRet == 0) {
  626.             /* YES! Make sure file is not opened read-only */
  627.             if (GetWindowWord(hwnd, GWW_READ_ONLY) == TRUE) {
  628.                 /* give error message */
  629.                 MPError(hwnd, MB_OK | MB_ICONHAND, IDS_SAVE_RDONLY, lpT);
  630.                 /* fake CANCEL push so save-as does not continue */
  631.                 iRet = ODM_E_CANCEL;
  632.             }
  633.             else {
  634.                 /* fake bNewDoc flag */
  635.                 bNewDoc = TRUE;
  636.                 /* copy original docID into szFile */
  637.                 lstrcpy(szFile, lpT);
  638.             }
  639.         }
  640.         GlobalUnlock(hT);
  641.     }
  642.  
  643.     switch (iRet) {
  644.         case 0:
  645.             /* ODMA handled FileSaveAs dialog - */
  646.             /* and passed back a new ODMA docID */
  647.             break;
  648.         case ODM_E_NODMS:
  649.         case ODM_E_APPSELECT:
  650.             /* normal DOS file saveas */
  651.             if (GetWindowWord(hwnd, GWW_UNTITLED))
  652.                 lstrcpy(szFile, "*.TXT");
  653.             else {
  654.                 GetWindowText(hwnd, szFile, 128);
  655.             }
  656.  
  657.             of.lStructSize  = sizeof(OPENFILENAME);
  658.             of.hwndOwner    = hwnd;
  659.             of.lpstrFilter  = (LPSTR)"Text Files (*.TXT)\0*.TXT\0";
  660.             of.lpstrCustomFilter = NULL;
  661.             of.nFilterIndex = 1;
  662.             of.lpstrFile    = (LPSTR)szFile;
  663.             of.nMaxFile     = 128;
  664.             of.lpstrInitialDir = NULL;
  665.             of.lpstrTitle   = NULL;
  666.             of.Flags        = OFN_HIDEREADONLY;
  667.             of.lpstrDefExt  = NULL;
  668.  
  669.             if(!GetSaveFileName(&of))
  670.                return(FALSE);
  671.             break;
  672.         case ODM_E_CANCEL:
  673.             return (FALSE);
  674.         default:
  675.             /* add possible error message display here */
  676.             return (FALSE);
  677.     }
  678.  
  679.  
  680.     /* Clear untitled flag */
  681.     SetWindowWord(hwnd, GWW_UNTITLED, 0);
  682.     /* new ODMA document? */
  683.     if (bNewDoc == TRUE) {
  684.         /* DOS filename allready received? */
  685.         hT = (HANDLE) GetWindowWord(hwnd, GWW_FILEPTR);
  686.         if (hT == (HANDLE) 0)
  687.             /* get DOS filename */
  688.             ODMOpenDoc( odmHandle, ODM_MODIFYMODE, szFile, szFile);
  689.         else {
  690.             /* load szFile with stored DOS filename */
  691.             lpT = (LPSTR) GlobalLock(hT);
  692.             lstrcpy(szFile, lpT);
  693.             GlobalUnlock(hT);
  694.         }
  695.  
  696.     }
  697.     else {
  698.         /* clear old ODMA docID */
  699.         hT = (HANDLE) GetWindowWord(hwnd, GWW_ODMADOCID);
  700.         if (hT) {
  701.             lpT = (LPSTR) GlobalLock(hT);
  702.             /* file saved? */
  703.             if (GetWindowWord(hwnd, GWW_ODMA_SAVE)) {
  704.                 ODMSaveDoc(odmHandle, lpT, lpT);
  705.             }
  706.             ODMCloseDoc( odmHandle, lpT, 0, 0, (LPVOID) 0, 0 );
  707.             GlobalUnlock(hT);
  708.             GlobalFree(hT);
  709.             SetWindowWord(hwnd, GWW_ODMA_SAVE, 0);
  710.             SetWindowWord(hwnd, GWW_ODMADOCID, 0);
  711.         }
  712.         /* new file an ODMA docID? */
  713.         if (szFile[0] == ':' && szFile[1] == ':') {
  714.             /* store ODMA docID in window memory */
  715.             hT = GlobalAlloc(GHND, (DWORD) (lstrlen(szFile) + 1));
  716.             if (hT == (HANDLE) 0) {
  717.                 /* Report the error and quit */
  718.                 MPError(hwnd, MB_OK | MB_ICONHAND, IDS_NOMEM, (LPSTR)szFile);
  719.                 return FALSE;
  720.                 }
  721.             lpT = (LPSTR) GlobalLock(hT);
  722.             lstrcpy (lpT, szFile);
  723.             GlobalUnlock(hT);
  724.             /* store fileptr in window word */
  725.             SetWindowWord(hwnd, GWW_ODMADOCID, hT);
  726.             /* get DOS filename for saving */
  727.             ODMOpenDoc( odmHandle, ODM_MODIFYMODE, szFile, szFile);
  728.         }
  729.     }
  730.     /* set newfilename into window handle */
  731.     hT = (HANDLE) GetWindowWord(hwnd, GWW_FILEPTR);
  732.     if (hT) {
  733.         GlobalFree(hT);
  734.     }
  735.     hT = GlobalAlloc(GHND, (DWORD) (lstrlen(szFile) + 1));
  736.     if (hT) {
  737.         lpT = (LPSTR) GlobalLock(hT);
  738.         lstrcpy(lpT, szFile);
  739.         GlobalUnlock(hT);
  740.     }
  741.     SetWindowWord(hwnd, GWW_FILEPTR, hT);
  742.  
  743.     /* set window title bar text */
  744.     /* ODMA docID? */
  745.     hT = (HANDLE) GetWindowWord(hwnd, GWW_ODMADOCID);
  746.     if (hT) {
  747.         char sz[128];
  748.  
  749.         lpT = (LPSTR) GlobalLock(hT);
  750.         if (ODMGetDocInfo(odmHandle, lpT, ODM_TITLETEXT, sz, 128) == 0)
  751.             lstrcpy(szFile, sz);
  752.         GlobalUnlock(hT);
  753.     }
  754.     SetWindowText(hwnd, szFile);
  755.  
  756.     /* clear read-only flag */
  757.     SetWindowWord(hwnd, GWW_READ_ONLY, FALSE);
  758.  
  759.     return(TRUE);
  760. }
  761.  
  762. /****************************************************************************
  763.  *                                        *
  764.  *  FUNCTION   : ParseCmdLine (char *)  *
  765.  *                                        *
  766.  *  PURPOSE    : Parse any DOS filename on the command line into the OF struct
  767.  *                                        *
  768.  *  RETURNS    : NONE                    *
  769.  *                                        *
  770.  ****************************************************************************/
  771.  
  772. VOID FAR PASCAL ParseCmdLine (char * pCmdLine)
  773. {
  774.     int     wFileTemp;
  775.  
  776.     /* NULL pointer passed in? */
  777.     if (pCmdLine == (char *) 0 || pCmdLine[0] == NULL)
  778.         return;
  779.  
  780.     /* ODMA docID passed in? */
  781.     if (pCmdLine[0] == ':' && pCmdLine[1] == ':')
  782.         return;
  783.  
  784.     /* Open the file with the OF_PARSE flag to obtain the fully qualified
  785.      * pathname in the OFSTRUCT structure.
  786.      */
  787.     wFileTemp = OpenFile ((LPSTR) pCmdLine, (LPOFSTRUCT)&of, OF_PARSE);
  788.     if (wFileTemp)
  789.         _lclose (wFileTemp);
  790. }
  791.  
  792. /****************************************************************************
  793.  *                                        *
  794.  *  FUNCTION   : OptionsCallBack        *
  795.  *                                        *
  796.  *  PURPOSE    : Serve as callback function for ODMASaveAs.
  797.  *                 Currently this only displays a message box with the
  798.  *                 passed in text.
  799.  *                                        *
  800.  *  RETURNS    : NONE                    *
  801.  *                                        *
  802.  ****************************************************************************/
  803.  
  804. LPSTR FAR OptionsCallBack(DWORD dwEnvData,
  805.                             LPSTR lpszFormat,
  806.                               LPVOID lpData)
  807. {
  808.     if (lpData)
  809.         MessageBox((HWND) dwEnvData, lpData, "MultODMA",
  810.                     MB_OK | MB_ICONINFORMATION);
  811.     else
  812.         MessageBox((HWND) dwEnvData, "App Specific info not given",
  813.                 "MultODMA", MB_OK | MB_ICONINFORMATION);
  814.     /* return a pointer at the 'format' string */
  815.     return lpszFormat;
  816. }
  817.