home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap18 / cosmo1.0 / file.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  11KB  |  460 lines

  1. /*
  2.  * FILE.C
  3.  *
  4.  * Functions for handling dirty files and processing File menu commands.
  5.  *
  6.  * Functions:
  7.  *  FDirtySet, FCleanVerify
  8.  *  FFileNew, FFileOpen, FFileSave, FFileSaveAs, FFileExit
  9.  *
  10.  * This file contains the only functions that manipulate the fDirty flag.
  11.  *
  12.  * Copyright(c) Microsoft Corp. 1992-1994 All Rights Reserved
  13.  * Win32 version, January 1994
  14.  */
  15.  
  16.  
  17. #include <windows.h>
  18. #include <ole.h>
  19. #include "cosmo.h"
  20. #include "oleglobl.h"
  21.  
  22.  
  23.  
  24.  
  25.  
  26. /*
  27.  * FDirtySet
  28.  *
  29.  * Purpose:
  30.  *  Sets or clears the global 'dirty' flag returning the previous state
  31.  *  of that same flag.  Even though the non-OLE part of this function
  32.  *  is trivial, it isolates handling changes, providing a single point
  33.  *  to notify a client app with OLE_CHANGED.
  34.  *
  35.  *  This function does exits if pGlob->fNoDirty is set.
  36.  *
  37.  * Parameters:
  38.  *  fDirty          BOOL used to set the value of the pGLob->fDirty flag.
  39.  *                  This allows us to use this function to both set and
  40.  *                  clear the flag.  OLE_CHANGED is only sent if the
  41.  *                  flag is set to TRUE.
  42.  *
  43.  * Return Value:
  44.  *  BOOL            Previous value of the dirty flag.
  45.  */
  46.  
  47. BOOL WINAPI FDirtySet(BOOL fDirty)
  48.     {
  49.     BOOL        fPrevious;
  50.  
  51. #ifdef MAKEOLESERVER
  52.     /*
  53.      * If we are a hidden window, then there's nothing that could make
  54.      * us dirty since there cannot be any user interaction here.  Therefore
  55.      * ignore any changes to the dirty flag, leaving it FALSE.
  56.      */
  57.     if (!IsWindowVisible(pGlob->hWnd))
  58.         return pGlob->fDirty;
  59.  
  60. #endif //MAKEOLESERVER
  61.  
  62.     if (pGlob->fNoDirty)
  63.         return pGlob->fDirty;
  64.  
  65.     fPrevious=pGlob->fDirty;
  66.     pGlob->fDirty=fDirty;
  67.  
  68. #ifdef MAKEOLESERVER
  69.     if (fDirty)
  70.         //Fun indirection, huh?  That what you get with an OOP.
  71.         OLEClientNotify(pOLE->pSvr->pDoc->pObj, OLE_CHANGED);
  72. #endif //MAKEOLESERVER
  73.  
  74.     return fPrevious;
  75.     }
  76.  
  77.  
  78.  
  79.  
  80.  
  81. /*
  82.  * FCleanVerify
  83.  *
  84.  * Purpose:
  85.  *  Checks the pGLob->fDirty flag, and if set, displays a message
  86.  *  box informing the user that the file is dirty and asking if
  87.  *  the file should be saved or updated.  If YES is chosen, the file
  88.  *  is saved or updated.
  89.  *
  90.  * Parameters:
  91.  *  pGlob           LPGLOBALS to global variable block.
  92.  *
  93.  * Return Value:
  94.  *  BOOL            TRUE if it's safe to proceed with the operation (file
  95.  *                  is clean, user answered NO, or file was saved).
  96.  *                  FALSE if the user wants to cancel the operation or there
  97.  *                  was an error.
  98.  */
  99.  
  100. BOOL WINAPI FCleanVerify(LPGLOBALS pGlob)
  101.     {
  102.     BOOL        fRet=TRUE;
  103.     UINT        uRet;
  104.     char       *psz;
  105.  
  106. #ifdef MAKEOLESERVER
  107.     char        szClient[40];
  108. #endif //MAKEOLESERVER
  109.  
  110.     //Nothing to do if we're clean.
  111.     if (!pGlob->fDirty)
  112.         return TRUE;
  113.  
  114.     if (!pGlob->fOLE)
  115.         {
  116.         uRet=MessageBox(pGlob->hWnd, rgpsz[IDS_FILEDIRTY]
  117.             , rgpsz[IDS_CAPTION], MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  118.         }
  119. #ifdef MAKEOLESERVER
  120.     if (pGlob->fOLE)
  121.         {
  122.         //Linking case, use the same message as before.
  123.         if (pOLE->pSvr->fLink)
  124.             {
  125.             uRet=MessageBox(pGlob->hWnd, rgpsz[IDS_FILEDIRTY],
  126.                             rgpsz[IDS_CAPTION], MB_YESNOCANCEL);
  127.             }
  128.  
  129.         //Embedding: Ask the user about updating instead of saving.
  130.         if (pOLE->pSvr->fEmbed)
  131.             {
  132.             //Build the standard string for Updating.
  133.             psz=(PSTR)LocalAlloc(LPTR, 1024);
  134.  
  135.             if (NULL==psz)
  136.                 return FALSE;
  137.  
  138.             GetAtomName(pOLE->pSvr->pDoc->aClient, szClient, sizeof(szClient));
  139.  
  140.             lstrcpy(psz, rgpsz[IDS_CLOSEALERT1]);
  141.             lstrcat(psz, szClient);
  142.             lstrcat(psz, rgpsz[IDS_CLOSEALERT2]);
  143.  
  144.             uRet=MessageBox(pGlob->hWnd, psz, rgpsz[IDS_CAPTION],
  145.                             MB_YESNOCANCEL | MB_ICONEXCLAMATION);
  146.  
  147.             LocalFree((HLOCAL)psz);
  148.             }
  149.         }
  150. #endif //MAKEOLESERVER
  151.  
  152.     switch (uRet)
  153.         {
  154.         case IDCANCEL:
  155.             fRet=FALSE;
  156.             break;
  157.  
  158.         case IDNO:
  159.             fRet=TRUE;
  160.             break;
  161.  
  162.         case IDYES:
  163.             if (!pGlob->fOLE)
  164.                 fRet=FFileSave(pGlob);
  165.  
  166. #ifdef MAKEOLESERVER
  167.             //Linking same as stand-alone.
  168.             if (pOLE->pSvr->fLink)
  169.                 fRet=FFileSave(pGlob);
  170.  
  171.             if (pOLE->pSvr->fEmbed)
  172.                 OLEClientNotify(pOLE->pSvr->pDoc->pObj, OLE_CLOSED);
  173.  
  174. #endif //MAKEOLESERVER
  175.             break;
  176.         }
  177.  
  178.     return fRet;
  179.     }
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186. /*
  187.  * FFileNew
  188.  *
  189.  * Purpose:
  190.  *  Confirms the new file with the user and cleans out the Polyline
  191.  *  image.
  192.  *
  193.  * Parameters:
  194.  *  pGlob           LPGLOBALS to the global variable block.
  195.  *
  196.  * Return Value:
  197.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  198.  *
  199.  */
  200.  
  201. BOOL WINAPI FFileNew(LPGLOBALS pGlob)
  202.     {
  203.     if (!FCleanVerify(pGlob))
  204.         return FALSE;
  205.  
  206. #ifdef MAKEOLESERVER
  207.     PDocRevokeAndCreate(pOLE);
  208. #endif //MAKEOLESERVER
  209.  
  210.     pGlob->fOLE=FALSE;
  211.  
  212.     SendMessage(pGlob->hWndPolyline, PLM_POLYLINENEW, 0, 0L);
  213.     pGlob->fDirty=FALSE;
  214.     pGlob->fOpenFile=FALSE;
  215.  
  216.     WindowTitleSet(pGlob->hWnd, rgpsz[IDS_UNTITLED]);
  217.     return TRUE;
  218.     }
  219.  
  220.  
  221.  
  222.  
  223. /*
  224.  * FFileOpen
  225.  *
  226.  * Purpose:
  227.  *  Confirms that the user wants to open a new file and invokes the
  228.  *  common dialog file open to get the filename, then reads the
  229.  *  contents of the file.  If the fImport flag is TRUE, then we
  230.  *  import the contents of the file into the current document,
  231.  *  not changing the document name or any of the UI.
  232.  *
  233.  * Parameters:
  234.  *  pGlob           LPGLOBALS to the global variable block.
  235.  *  fImport         BOOL indicates if we're importing from a file,
  236.  *                  not affecting the current filename.
  237.  *
  238.  * Return Value:
  239.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  240.  *
  241.  */
  242.  
  243. BOOL WINAPI FFileOpen(LPGLOBALS pGlob, BOOL fImport)
  244.     {
  245.     POLYLINE        pl;
  246.     BOOL            fOK;
  247.     LPSTR           psz;
  248.     char            szTemp[CCHPATHMAX];
  249.     LPSTR           pszFile;
  250.  
  251.     if (!fImport)
  252.         {
  253.         if (!FCleanVerify(pGlob))
  254.             return FALSE;
  255.         }
  256.  
  257.     psz=(fImport) ? rgpsz[IDS_FILEIMPORT] : rgpsz[IDS_FILEOPEN];
  258.  
  259.     //We have to use a temp for Import or else we'll wipe out a real filename.
  260.     pszFile=(fImport) ? (LPSTR)szTemp : (LPSTR)pGlob->szFile;
  261.  
  262.     fOK=FSaveOpenDialog(pGlob->hWnd, pGlob->hInst, rgpsz[IDS_DEFEXT]
  263.         , rgpsz[IDS_FILEOPENFILTER], pszFile, psz, TRUE);
  264.  
  265.  
  266.     if (fOK)
  267.         {
  268.         //Attempt to read the file in and display it.
  269.         if (!FCosFileRead(pGlob, pszFile, &pl))
  270.             return FALSE;
  271.  
  272. #ifdef MAKEOLESERVER
  273.         if (!fImport)
  274.             PDocRevokeAndCreate(pOLE);
  275. #endif //MAKEOLESERVER
  276.  
  277.         SendMessage(pGlob->hWndPolyline, PLM_POLYLINESET,
  278.                     TRUE, (LONG)(LPSTR)&pl);
  279.  
  280.         if (!fImport)
  281.             {
  282.             WindowTitleSet(pGlob->hWnd, pszFile);
  283.             pGlob->fOLE=FALSE;
  284.  
  285.             pGlob->fOpenFile=TRUE;
  286.             pGlob->fDirty=FALSE;
  287.             }
  288.         else
  289.             pGlob->fDirty=TRUE;
  290.         }
  291.  
  292.     return fOK;
  293.     }
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300. /*
  301.  * FFileSave
  302.  *
  303.  * Purpose:
  304.  *  Writes the file to a known filename, requiring that the user has
  305.  *  previously used FileOpen or FileSaveAs in order to have a filename.
  306.  *
  307.  * Parameters:
  308.  *  pGlob           LPGLOBALS to the global variable block.
  309.  *
  310.  * Return Value:
  311.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  312.  *
  313.  */
  314.  
  315. BOOL WINAPI FFileSave(LPGLOBALS pGlob)
  316.     {
  317.     POLYLINE        pl;
  318.  
  319. #ifdef MAKEOLESERVER
  320.     OLESTATUS       os;
  321.  
  322.     //In OLE cases, this may be Update; call OleSavedServerDoc
  323.     if (pGlob->fOLE)
  324.         {
  325.         if (pOLE->pSvr->fLink)
  326.             {
  327.             SendMessage(pGlob->hWndPolyline, PLM_POLYLINEGET, 0,
  328.                         (LONG)(LPSTR)&pl);
  329.  
  330.             if (!FCosFileWrite(pGlob, pGlob->szFile, &pl))
  331.                 return FALSE;
  332.             }
  333.  
  334.         //This notifies the client for us.
  335.         os=OleSavedServerDoc(pOLE->pSvr->pDoc->lh);
  336.  
  337.         pGlob->fDirty=(BOOL)(OLE_OK!=os);
  338.         return !pGlob->fDirty;
  339.         }
  340.  
  341. #endif //MAKEOLESERVER
  342.  
  343.     if (!pGlob->fOpenFile)
  344.         return FFileSaveAs(pGlob);
  345.  
  346.     SendMessage(pGlob->hWndPolyline, PLM_POLYLINEGET, 0, (LONG)(LPSTR)&pl);
  347.  
  348.     if (!FCosFileWrite(pGlob, pGlob->szFile, &pl))
  349.         return FALSE;
  350.  
  351.     pGlob->fOpenFile=TRUE;
  352.     pGlob->fDirty=FALSE;
  353.     return TRUE;
  354.     }
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361. /*
  362.  * FFileSaveAs
  363.  *
  364.  * Purpose:
  365.  *  Invokes the common dialog for Save As to get a filename then
  366.  *  writes the polyline data to that file, creating if necessary.
  367.  *
  368.  * Parameters:
  369.  *  pGlob           LPGLOBALS to the global variable block.
  370.  *
  371.  * Return Value:
  372.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  373.  *
  374.  */
  375.  
  376. BOOL WINAPI FFileSaveAs(LPGLOBALS pGlob)
  377.     {
  378.     POLYLINE        pl;
  379.     BOOL            fOK;
  380.  
  381.     fOK=FSaveOpenDialog(pGlob->hWnd, pGlob->hInst, rgpsz[IDS_DEFEXT]
  382.         , rgpsz[IDS_FILEOPENFILTER], pGlob->szFile, rgpsz[IDS_FILESAVEAS]
  383.         , FALSE);
  384.  
  385.     if (fOK)
  386.         {
  387.         SendMessage(pGlob->hWndPolyline, PLM_POLYLINEGET
  388.             , 0, (LONG)(LPSTR)&pl);
  389.  
  390.         fOK=FCosFileWrite(pGlob, pGlob->szFile, &pl);
  391.  
  392. #ifdef MAKEOLESERVER
  393.         /*
  394.          * In the Save Copy As case, when an object is embedded, we
  395.          * don't need to call Rename or Saved since we just saved a
  396.          * silent copy of the data.
  397.          */
  398.         if (pGlob->fOLE && pOLE->pSvr->fEmbed)
  399.             return fOK;
  400.  
  401.         if (fOK && pGlob->fOLE && pOLE->pSvr->fLink)
  402.             {
  403.             OleRenameServerDoc(pOLE->pSvr->pDoc->lh, pGlob->szFile);
  404.             OleSavedServerDoc(pOLE->pSvr->pDoc->lh);
  405.             }
  406. #endif //MAKEOLESERVER
  407.  
  408.         pGlob->fOpenFile=fOK;
  409.         WindowTitleSet(pGlob->hWnd, pGlob->szFile);
  410.         pGlob->fDirty=FALSE;
  411.         }
  412.  
  413.     return fOK;
  414.     }
  415.  
  416.  
  417.  
  418. /*
  419.  * FFileExit
  420.  *
  421.  * Purpose:
  422.  *  Handles the File/Exit menu command, verifying dirty files as necessary
  423.  *  and revoking the server.
  424.  *
  425.  * Parameters:
  426.  *  pGlob           LPGLOBALS to the global variable block.
  427.  *
  428.  * Return Value:
  429.  *  BOOL            TRUE if the application can exit, FALSE otherwise.
  430.  */
  431.  
  432. BOOL WINAPI FFileExit(LPGLOBALS pGlob)
  433.     {
  434.     BOOL            fRet;
  435. #ifdef MAKEOLESERVER
  436.     OLESTATUS       os;
  437.     LHSERVER        lhT;
  438. #endif //MAKEOLESERVER
  439.  
  440.     if (!FCleanVerify(pGlob))
  441.         return FALSE;
  442.  
  443. #ifdef MAKEOLESERVER
  444.     lhT=pOLE->pSvr->lh;
  445.     pOLE->pSvr->lh=0L;
  446.     os=OleRevokeServer(lhT);
  447.  
  448.     if (OLE_WAIT_FOR_RELEASE==os)
  449.         {
  450.         pOLE->pSvr->fRelease=FALSE;
  451.         FOLEReleaseWait(&pOLE->pSvr->fRelease, lhT);
  452.         fRet=TRUE;
  453.         }
  454.     else
  455.         fRet=(OLE_OK==os);
  456. #endif //MAKEOLESERVER
  457.  
  458.     return fRet;
  459.     }
  460.