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 / chap21 / cosmo / document.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  33.3 KB  |  1,477 lines

  1. /*
  2.  * DOCUMENT.CPP
  3.  * Cosmo Chapter 21
  4.  *
  5.  * Implementation of the CCosmoDoc derivation of CDocument as
  6.  * well as an implementation of CPolylineAdviseSink.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "cosmo.h"
  17.  
  18.  
  19. /*
  20.  * CCosmoDoc::CCosmoDoc
  21.  * CCosmoDoc::~CCosmoDoc
  22.  *
  23.  * Constructor Parameters:
  24.  *  hInst           HINSTANCE of the application.
  25.  *  pFR             PCFrame of the frame object.
  26.  *  pAdv            PCDocumentAdviseSink to notify on events
  27.  */
  28.  
  29. CCosmoDoc::CCosmoDoc(HINSTANCE hInst, PCFrame pFR
  30.     , PCDocumentAdviseSink pAdv)
  31.     : CDocument(hInst, pFR, pAdv)
  32.     {
  33.     m_pPL=NULL;
  34.     m_pPLAdv=NULL;
  35.     m_uPrevSize=SIZE_RESTORED;
  36.  
  37.     m_pDropTarget=NULL;
  38.     m_fDragSource=FALSE;
  39.  
  40.     m_cfEmbedSource=RegisterClipboardFormat(CFSTR_EMBEDSOURCE);
  41.     m_cfObjectDescriptor=RegisterClipboardFormat
  42.         (CFSTR_OBJECTDESCRIPTOR);
  43.  
  44.     m_pFigure=NULL;
  45.  
  46.     //CHAPTER21MOD
  47.     m_pMoniker=NULL;
  48.     m_dwRegROT=0L;
  49.  
  50.     m_cfLinkSource=RegisterClipboardFormat(CFSTR_LINKSOURCE);
  51.     m_cfLinkSrcDescriptor=RegisterClipboardFormat
  52.         (CFSTR_LINKSRCDESCRIPTOR);
  53.     //End CHAPTER21MOD
  54.     return;
  55.     }
  56.  
  57.  
  58. CCosmoDoc::~CCosmoDoc(void)
  59.     {
  60.     //Make sure the object is saved
  61.     m_pFigure->SendAdvise(OBJECTCODE_SAVEOBJECT);
  62.     m_pFigure->SendAdvise(OBJECTCODE_HIDEWINDOW);
  63.     m_pFigure->SendAdvise(OBJECTCODE_CLOSED);
  64.  
  65.     //CHAPTER21MOD
  66.     //If the document is reg'd as running, revoke and free the moniker
  67.     INOLE_RevokeAsRunning(&m_dwRegROT);
  68.  
  69.     if (NULL!=m_pMoniker)
  70.         m_pMoniker->Release();
  71.     //End CHAPTER21MOD
  72.  
  73.     if (NULL!=m_pFigure)
  74.         {
  75.         m_pFigure->AddRef();
  76.         CoDisconnectObject(m_pFigure, 0L);
  77.         m_pFigure->Release();   //Starts shutdown if necessary.
  78.         delete m_pFigure;
  79.         }
  80.  
  81.     //Clean up the allocations we did in Init
  82.     if (NULL!=m_pPL)
  83.         delete m_pPL;
  84.  
  85.     if (NULL!=m_pPLAdv)
  86.         delete m_pPLAdv;
  87.  
  88.     return;
  89.     }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96. /*
  97.  * CCosmoDoc::Init
  98.  *
  99.  * Purpose:
  100.  *  Initializes an already created document window.  The client
  101.  *  actually creates the window for us, then passes that here for
  102.  *  further initialization.
  103.  *
  104.  * Parameters:
  105.  *  pDI             PDOCUMENTINIT containing initialization
  106.  *                  parameters.
  107.  *
  108.  * Return Value:
  109.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  110.  */
  111.  
  112. BOOL CCosmoDoc::Init(PDOCUMENTINIT pDI)
  113.     {
  114.     RECT        rc;
  115.  
  116.     //Change the stringtable range to our customization.
  117.     pDI->idsMin=IDS_DOCUMENTMIN;
  118.     pDI->idsMax=IDS_DOCUMENTMAX;
  119.  
  120.     //Do default initialization
  121.     if (!CDocument::Init(pDI))
  122.         return FALSE;
  123.  
  124.     //Add the Polyline stuff we need.
  125.     m_pPLAdv=new CPolylineAdviseSink(this);
  126.     m_pPL   =new CPolyline(m_hInst);
  127.  
  128.     //Attempt to create our contained Polyline.
  129.     GetClientRect(m_hWnd, &rc);
  130.     InflateRect(&rc, -8, -8);
  131.  
  132.     if (!m_pPL->Init(m_hWnd, &rc, WS_CHILD | WS_VISIBLE
  133.         , ID_POLYLINE, m_pPLAdv))
  134.         return FALSE;
  135.  
  136.     m_pDropTarget=new CDropTarget(this);
  137.  
  138.     if (NULL!=m_pDropTarget)
  139.         {
  140.         m_pDropTarget->AddRef();
  141.         CoLockObjectExternal(m_pDropTarget, TRUE, FALSE);
  142.         RegisterDragDrop(m_hWnd, m_pDropTarget);
  143.         }
  144.  
  145.     m_pFigure=new CFigure(ObjectDestroyed, this);
  146.  
  147.     if (NULL==m_pFigure)
  148.         return FALSE;
  149.  
  150.     //We created an object, so count it.
  151.     g_cObj++;
  152.  
  153.     if (!m_pFigure->Init())
  154.         return FALSE;
  155.  
  156.     return TRUE;
  157.     }
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165. /*
  166.  * CCosmoDoc::FMessageHook
  167.  *
  168.  * Purpose:
  169.  *  Processes WM_SIZE for the document so we can resize
  170.  *  the Polyline.
  171.  *
  172.  * Parameters:
  173.  *  <WndProc Parameters>
  174.  *  pLRes           LRESULT * in which to store the return
  175.  *                  value for the message.
  176.  *
  177.  * Return Value:
  178.  *  BOOL            TRUE to prevent further processing,
  179.  *                  FALSE otherwise.
  180.  */
  181.  
  182. BOOL CCosmoDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  183.     , LPARAM lParam, LRESULT *pLRes)
  184.     {
  185.     UINT        dx, dy;
  186.     RECT        rc;
  187.  
  188.     *pLRes=0;
  189.  
  190.     if (WM_SIZE==iMsg)
  191.         {
  192.         //Don't effect the Polyline size to or from minimized state.
  193.         if (SIZE_MINIMIZED!=wParam && SIZE_MINIMIZED !=m_uPrevSize)
  194.             {
  195.             //When we change size, resize any Polyline we hold.
  196.             dx=LOWORD(lParam);
  197.             dy=HIWORD(lParam);
  198.  
  199.             /*
  200.              * If we are getting WM_SIZE in response to a Polyline
  201.              * notification, then don't resize the Polyline window
  202.              * again.
  203.              */
  204.             if (!m_fNoSize && NULL!=m_pPL)
  205.                 {
  206.                 //Resize the polyline to fit the new client
  207.                 SetRect(&rc, 8, 8, dx-8, dy-8);
  208.                 m_pPL->RectSet(&rc, FALSE);
  209.  
  210.                 /*
  211.                  * We consider sizing something that makes the file
  212.                  * dirty, but not until we've finished the create
  213.                  * process, which is why we set fNoDirty to FALSE
  214.                  * in WM_CREATE since we get a WM_SIZE on the first
  215.                  * creation.
  216.                  */
  217.                 if (!m_fNoDirty)
  218.                     FDirtySet(TRUE);
  219.  
  220.                 SetRect(&rc, 0, 0, dx, dy);
  221.  
  222.                 if (NULL!=m_pAdv)
  223.                     m_pAdv->OnSizeChange(this, &rc);
  224.  
  225.                 m_fNoDirty=FALSE;
  226.                 }
  227.             }
  228.  
  229.         m_uPrevSize=wParam;
  230.         }
  231.  
  232.     if (WM_LBUTTONDOWN==iMsg)
  233.         {
  234.         LPDROPSOURCE    pIDropSource;
  235.         LPDATAOBJECT    pIDataObject;
  236.         HRESULT         hr;
  237.         SCODE           sc;
  238.         DWORD           dwEffect;
  239.  
  240.         /*
  241.          * The document has an 8 pixel border around the polyline
  242.          * window where we'll see mouse clicks.  A left mouse button
  243.          * click here means the start of a drag-drop operation.
  244.          *
  245.          * Since this is a modal operation, this IDropSource
  246.          * is entirely local.
  247.          */
  248.  
  249.         pIDropSource=new CDropSource(this);
  250.  
  251.         if (NULL==pIDropSource)
  252.             return FALSE;
  253.  
  254.         pIDropSource->AddRef();
  255.         m_fDragSource=TRUE;
  256.  
  257.         //Go get the data and start the ball rolling.
  258.         pIDataObject=TransferObjectCreate(FALSE);
  259.  
  260.         if (NULL!=pIDataObject)
  261.             {
  262.             //CHAPTER21MOD
  263.             //Add DROPEFFECT_LINK now that we source links
  264.             hr=DoDragDrop(pIDataObject, pIDropSource
  265.                 , DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK
  266.                 , &dwEffect);
  267.             //End CHAPTER21MOD
  268.  
  269.             pIDataObject->Release();
  270.             sc=GetScode(hr);
  271.             }
  272.         else
  273.             sc=E_FAIL;
  274.  
  275.         /*
  276.          * When we return from DoDragDrop, either cancel or drop.
  277.          * First toss the IDropSource we have here, then bail out
  278.          * on cancel, and possibly clear our data on a move drop.
  279.          */
  280.  
  281.         pIDropSource->Release();
  282.  
  283.         /*
  284.          * If dropped on the same document (determined using
  285.          * this flag, then dwEffect will be DROPEFFECT_NONE (see
  286.          * IDropTarget::Drop in DROPTGT.CPP).  In any case,
  287.          * reset this since the operation is done.
  288.          */
  289.  
  290.         m_fDragSource=FALSE;
  291.  
  292.         if (DRAGDROP_S_DROP==sc && DROPEFFECT_MOVE==dwEffect)
  293.             {
  294.             m_pPL->New();
  295.             FDirtySet(TRUE);
  296.             }
  297.  
  298.         //On a canceled drop or a copy we don't do anything else
  299.         return TRUE;
  300.         }
  301.  
  302.     if (WM_DESTROY==iMsg)
  303.         {
  304.         /*
  305.          * We have to revoke the drop target here because the window
  306.          * will be destroyed and the property forcefully removed
  307.          * before we could do this in the destructor.
  308.          */
  309.         if (NULL!=m_pDropTarget)
  310.             {
  311.             RevokeDragDrop(m_hWnd);
  312.             CoLockObjectExternal(m_pDropTarget, FALSE, TRUE);
  313.             ReleaseInterface(m_pDropTarget);
  314.             }
  315.  
  316.         return FALSE;
  317.         }
  318.  
  319.  
  320.     /*
  321.      * We return FALSE even on WM_SIZE so we can let the default
  322.      * procedure handle maximized MDI child windows appropriately.
  323.      */
  324.     return FALSE;
  325.     }
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334. /*
  335.  * CCosmoDoc::Clear
  336.  *
  337.  * Purpose:
  338.  *  Sets all contents in the document back to defaults with
  339.  *  no filename.
  340.  *
  341.  * Paramters:
  342.  *  None
  343.  *
  344.  * Return Value:
  345.  *  None
  346.  */
  347.  
  348. void CCosmoDoc::Clear(void)
  349.     {
  350.     //Completely reset the polyline
  351.     m_pPL->New();
  352.  
  353.     CDocument::Clear();
  354.     m_lVer=0;
  355.     return;
  356.     }
  357.  
  358.  
  359.  
  360. /*
  361.  * CCosmoDoc::FDirtySet
  362.  *
  363.  * Purpose:
  364.  *  Sets or clears the document 'dirty' flag returning the previous
  365.  *  state of that same flag.  We override this in Cosmo server to
  366.  *  send the OnDataChange notification as necessary.
  367.  *
  368.  * Parameters:
  369.  *  fDirty          BOOL indicating the new contents of the dirty
  370.  *                  flag.
  371.  *
  372.  * Return Value:
  373.  *  BOOL            Previous value of the dirty flag.
  374.  */
  375.  
  376. BOOL CCosmoDoc::FDirtySet(BOOL fDirty)
  377.     {
  378.     BOOL        fRet;
  379.  
  380.     fRet=CDocument::FDirtySet(fDirty);
  381.     m_pFigure->SendAdvise(OBJECTCODE_DATACHANGED);
  382.  
  383.     return fRet;
  384.     }
  385.  
  386.  
  387.  
  388.  
  389. /*
  390.  * CCosmoDoc::FDirtyGet
  391.  *
  392.  * Purpose:
  393.  *  Override of the normal FDirtyGet such that we never return dirty
  394.  *  for an embedded object we're serving since updates constantly
  395.  *  happen and since the object will be saved on closure.  This then
  396.  *  prevents any message boxes asking the user to save.
  397.  *
  398.  * Parameters:
  399.  *  None
  400.  *
  401.  * Return Value:
  402.  *  BOOL            TRUE if the document is dirty, FALSE otherwise.
  403.  */
  404.  
  405. BOOL CCosmoDoc::FDirtyGet(void)
  406.     {
  407.     if (m_pFigure->FIsEmbedded())
  408.         return FALSE;
  409.  
  410.     return m_fDirty;
  411.     }
  412.  
  413.  
  414.  
  415. /*
  416.  * CCosmoDoc::Load
  417.  *
  418.  * Purpose:
  419.  *  Loads a given document without any user interface overwriting
  420.  *  the previous contents of the Polyline window.  We do this by
  421.  *  opening the file and telling the Polyline to load itself from
  422.  *  that file.
  423.  *
  424.  * Parameters:
  425.  *  fChangeFile     BOOL indicating if we're to update the window
  426.  *                  title and the filename from using this file.
  427.  *  pszFile         LPTSTR to the filename to load, NULL if the file
  428.  *                  is new and untitled.
  429.  *
  430.  * Return Value:
  431.  *  UINT            An error value from DOCERR_*
  432.  */
  433.  
  434. UINT CCosmoDoc::Load(BOOL fChangeFile, LPTSTR pszFile)
  435.     {
  436.     HRESULT         hr;
  437.     LPSTORAGE       pIStorage;
  438.  
  439.     if (NULL==pszFile)
  440.         {
  441.         //For a new untitled document, just rename ourselves.
  442.         Rename(NULL);
  443.         m_lVer=VERSIONCURRENT;
  444.         return DOCERR_NONE;
  445.         }
  446.  
  447.     /*
  448.      * If not a Compound File, open the file using STGM_CONVERT in
  449.      * transacted mode to see old files as a storage with one stream
  450.      * called "CONTENTS" (which is conveniently the name we use
  451.      * in the new files).  We must use STGM_TRANSACTED here or else
  452.      * the old file will be immediately converted on disk:  we only
  453.      * want a converted image in memory from which to read.  In
  454.      * addition, note that we need STGM_READWRITE as well since
  455.      * conversion is inherently a write operation.
  456.      */
  457.  
  458.     pIStorage=NULL;
  459.  
  460.     if (NOERROR!=StgIsStorageFile(pszFile))
  461.         {
  462.         hr=StgCreateDocfile(pszFile,STGM_TRANSACTED | STGM_READWRITE
  463.             | STGM_CONVERT | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  464.  
  465.         if (FAILED(hr))
  466.             {
  467.             //If denied write access, try to load the old way
  468.             if (STG_E_ACCESSDENIED==GetScode(hr))
  469.                 m_lVer=m_pPL->ReadFromFile(pszFile);
  470.             else
  471.                 return DOCERR_COULDNOTOPEN;
  472.             }
  473.         }
  474.     else
  475.         {
  476.         hr=StgOpenStorage(pszFile, NULL, STGM_DIRECT | STGM_READ
  477.             | STGM_SHARE_EXCLUSIVE, NULL, 0, &pIStorage);
  478.  
  479.         if (FAILED(hr))
  480.             return DOCERR_COULDNOTOPEN;
  481.         }
  482.  
  483.     if (NULL!=pIStorage)
  484.         {
  485.         m_lVer=m_pPL->ReadFromStorage(pIStorage);
  486.         pIStorage->Release();
  487.         }
  488.  
  489.     if (POLYLINE_E_READFAILURE==m_lVer)
  490.         return DOCERR_READFAILURE;
  491.  
  492.     if (POLYLINE_E_UNSUPPORTEDVERSION==m_lVer)
  493.         return DOCERR_UNSUPPORTEDVERSION;
  494.  
  495.     if (fChangeFile)
  496.         Rename(pszFile);
  497.  
  498.     //Importing a file makes things dirty
  499.     FDirtySet(!fChangeFile);
  500.  
  501.     return DOCERR_NONE;
  502.     }
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510. /*
  511.  * CCosmoDoc::Save
  512.  *
  513.  * Purpose:
  514.  *  Writes the file to a known filename, requiring that the user has
  515.  *  previously used FileOpen or FileSaveAs to provide a filename.
  516.  *
  517.  * Parameters:
  518.  *  uType           UINT indicating the type of file the user
  519.  *                  requested to save in the File Save As dialog.
  520.  *  pszFile         LPTSTR under which to save.  If NULL, use the
  521.  *                  current name.
  522.  *
  523.  * Return Value:
  524.  *  UINT            An error value from DOCERR_*
  525.  */
  526.  
  527. UINT CCosmoDoc::Save(UINT uType, LPTSTR pszFile)
  528.     {
  529.     LONG        lVer, lRet;
  530.     UINT        uTemp;
  531.     BOOL        fRename=TRUE;
  532.     HRESULT     hr;
  533.     LPSTORAGE   pIStorage;
  534.     BOOL        fEmbedding;
  535.  
  536.     fEmbedding=m_pFigure->FIsEmbedded();
  537.  
  538.     if (NULL==pszFile)
  539.         {
  540.         fRename=FALSE;
  541.         pszFile=m_szFile;
  542.         }
  543.  
  544.     /*
  545.      * Type 1 is the current version, type 2 is version 1.0 of the
  546.      * Polyline so we use this to send the right version to
  547.      * CPolyline::WriteToFile/WriteToStorage.
  548.      */
  549.  
  550.     switch (uType)
  551.         {
  552.         case 0:         //From Save, use loaded version.
  553.             lVer=m_lVer;
  554.             break;
  555.  
  556.         case 1:
  557.             lVer=VERSIONCURRENT;
  558.             break;
  559.  
  560.         case 2:
  561.             lVer=MAKELONG(0, 1);    //1.0
  562.             break;
  563.  
  564.         default:
  565.             return DOCERR_UNSUPPORTEDVERSION;
  566.         }
  567.  
  568.     /*
  569.      * If the version the user wants to save is different from the
  570.      * version that we loaded and m_lVer is not zero (new doc),
  571.      * then inform the user of the version change and verify.
  572.      */
  573.  
  574.     //For embedding, this is Save Copy As, so don't ask about versions.
  575.     if (0!=m_lVer && m_lVer!=lVer && !fEmbedding)
  576.         {
  577.         TCHAR       szMsg[128];
  578.  
  579.         wsprintf(szMsg, PSZ(IDS_VERSIONCHANGE)
  580.             , (UINT)HIWORD(m_lVer), (UINT)LOWORD(m_lVer)
  581.             , (UINT)HIWORD(lVer), (UINT)LOWORD(lVer));
  582.  
  583.         uTemp=MessageBox(m_hWnd, szMsg, PSZ(IDS_DOCUMENTCAPTION)
  584.             , MB_YESNOCANCEL);
  585.  
  586.         if (IDCANCEL==uTemp)
  587.             return DOCERR_CANCELLED;
  588.  
  589.         //If the user won't upgrade, revert to loaded version.
  590.         if (IDNO==uTemp)
  591.             lVer=m_lVer;
  592.         }
  593.  
  594.     /*
  595.      * For 1.0 files, still use the old code.  For new files, use
  596.      * storages instead
  597.      */
  598.     if (lVer==MAKELONG(0, 1))
  599.         lRet=m_pPL->WriteToFile(pszFile, lVer);
  600.     else
  601.         {
  602.         hr=StgCreateDocfile(pszFile, STGM_DIRECT | STGM_READWRITE
  603.             | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  604.  
  605.         if (FAILED(hr))
  606.             return DOCERR_COULDNOTOPEN;
  607.  
  608.         //Mark this as one of our class
  609.         WriteClassStg(pIStorage, CLSID_CosmoFigure);
  610.  
  611.         //Write user-readable class information
  612.         WriteFmtUserTypeStg(pIStorage, m_cf
  613.             , PSZ(IDS_CLIPBOARDFORMAT));
  614.  
  615.         lRet=m_pPL->WriteToStorage(pIStorage, lVer);
  616.         pIStorage->Release();
  617.         }
  618.  
  619.     if (POLYLINE_E_NONE!=lRet)
  620.         return DOCERR_WRITEFAILURE;
  621.  
  622.     //Saving makes us clean, but this doesn't apply to embedding.
  623.     if (!fEmbedding)
  624.         FDirtySet(FALSE);
  625.  
  626.     //Update the known version of this document.
  627.     m_lVer=lVer;
  628.  
  629.     /*
  630.      * If we're embedding, this is Save Copy As, so no rename.
  631.      * Note that we also don't care about having been set to clean
  632.      * since we're always 'clean' as an embedded object from
  633.      * the user's perspective.
  634.      */
  635.     if (fRename && !fEmbedding)
  636.         Rename(pszFile);
  637.  
  638.     return DOCERR_NONE;
  639.     }
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646. //CHAPTER21MOD
  647. /*
  648.  * CCosmoDoc::Rename
  649.  *
  650.  * Purpose:
  651.  *  Overrides the normal rename to manage a moniker for the open
  652.  *  file.  We maintain no moniker for untitled documents, and
  653.  *  therefore do not allow linking to such documents.
  654.  *
  655.  * Parameters:
  656.  *  pszFile         LPTSTR to the new filename.
  657.  *
  658.  * Return Value:
  659.  *  None
  660.  */
  661.  
  662. void CCosmoDoc::Rename(LPTSTR pszFile)
  663.     {
  664.     LPMONIKER   pmk;
  665.  
  666.     //We don't need to change the base class, just augment...
  667.     CDocument::Rename(pszFile);
  668.  
  669.     //Unregister the old moniker (m_dwRegROT set to zero).
  670.     INOLE_RevokeAsRunning(&m_dwRegROT);
  671.  
  672.     ReleaseInterface(m_pMoniker);
  673.  
  674.     if (NULL!=pszFile)
  675.         {
  676.         CreateFileMoniker(pszFile, &pmk);
  677.  
  678.         if (NULL!=pmk)
  679.             {
  680.             m_pMoniker=pmk;     //pmk AddRef'd in CreateFileMoniker
  681.             INOLE_RegisterAsRunning(m_pFigure, m_pMoniker
  682.                 , 0, &m_dwRegROT);
  683.  
  684.             m_pFigure->SendAdvise(OBJECTCODE_RENAMED);
  685.             }
  686.         }
  687.  
  688.     return;
  689.     }
  690. //End CHAPTER21MOD
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697. /*
  698.  * CCosmoDoc::Undo
  699.  *
  700.  * Purpose:
  701.  *  Reverses a previous action.
  702.  *
  703.  * Parameters:
  704.  *  None
  705.  *
  706.  * Return Value:
  707.  *  None
  708.  */
  709.  
  710. void CCosmoDoc::Undo(void)
  711.     {
  712.     m_pPL->Undo();
  713.     return;
  714.     }
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721. /*
  722.  * CCosmoDoc::Clip
  723.  *
  724.  * Purpose:
  725.  *  Places a private format, a metafile, and a bitmap of the display
  726.  *  on the clipboard, optionally implementing Cut by deleting the
  727.  *  data in the current window after rendering.
  728.  *
  729.  * Parameters:
  730.  *  hWndFrame       HWND of the main window.
  731.  *  fCut            BOOL indicating cut (TRUE) or copy (FALSE).
  732.  *
  733.  * Return Value:
  734.  *  BOOL            TRUE if successful, FALSE otherwise.
  735.  */
  736.  
  737. BOOL CCosmoDoc::Clip(HWND hWndFrame, BOOL fCut)
  738.     {
  739.     BOOL            fRet=TRUE;
  740.     LPDATAOBJECT    pIDataObject;
  741.  
  742.     pIDataObject=TransferObjectCreate(fCut);
  743.  
  744.     if (NULL==pIDataObject)
  745.         return FALSE;
  746.  
  747.     fRet=SUCCEEDED(OleSetClipboard(pIDataObject));
  748.     pIDataObject->Release();
  749.  
  750.     //Delete our current data if "cut" succeeded.
  751.     if (fRet && fCut)
  752.         {
  753.         m_pPL->New();
  754.         FDirtySet(TRUE);
  755.         }
  756.  
  757.  
  758.     return fRet;
  759.     }
  760.  
  761.  
  762.  
  763.  
  764.  
  765. /*
  766.  * CCosmoDoc::RenderFormat
  767.  *
  768.  * Purpose:
  769.  *  Renders a specific clipboard format into global memory.
  770.  *
  771.  * Parameters:
  772.  *  cf              UINT format to render.
  773.  *
  774.  * Return Value:
  775.  *  HGLOBAL         Global memory handle containing the data.
  776.  */
  777.  
  778. HGLOBAL CCosmoDoc::RenderFormat(UINT cf)
  779.     {
  780.     HGLOBAL     hMem;
  781.  
  782.     if (cf==m_cf)
  783.         {
  784.         m_pPL->DataGetMem(VERSIONCURRENT, &hMem);
  785.         return hMem;
  786.         }
  787.  
  788.     switch (cf)
  789.         {
  790.         case CF_METAFILEPICT:
  791.             return m_pPL->RenderMetafilePict();
  792.  
  793.         case CF_BITMAP:
  794.             return (HGLOBAL)m_pPL->RenderBitmap();
  795.         }
  796.  
  797.     return NULL;
  798.     }
  799.  
  800.  
  801.  
  802.  
  803. /*
  804.  * CCosmoDoc::RenderMedium
  805.  *
  806.  * Purpose:
  807.  *  Like RenderFormat, this function creates a specific data format
  808.  *  based on the cf parameter.  Unlike RenderFormat, we store the
  809.  *  result in a STGMEDIUM in case it has a medium other than
  810.  *  TYMED_HGLOBAL.  For conveniece we'll centralize all compound
  811.  *  document formats here, hGlobal or not.
  812.  *
  813.  * Parameters:
  814.  *  cf              UINT clipboard format of interest.
  815.  *  pSTM            LSTGMEDIUM to fill.  We only fill the union
  816.  *                  and tymed.
  817.  *
  818.  * Return Value:
  819.  *  BOOL            TRUE if we could render the format,
  820.  *                  FALSE otherwise.
  821.  */
  822.  
  823. BOOL CCosmoDoc::RenderMedium(UINT cf, LPSTGMEDIUM pSTM)
  824.     {
  825.     if (NULL==pSTM)
  826.         return FALSE;
  827.  
  828.     if (cf==m_cfEmbedSource)
  829.         {
  830.         /*
  831.          * Embed Source data is an IStorage containing the native
  832.          * data (same as Embedded Object).  Since our data is small,
  833.          * it makes the most sense to create an IStorage in memory
  834.          * and put transfer that instead of a disk-based IStorage.
  835.          */
  836.  
  837.         pSTM->pstg=INOLE_CreateStorageOnHGlobal(STGM_DIRECT
  838.             | STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
  839.  
  840.         if (NULL==pSTM->pstg)
  841.             return FALSE;
  842.  
  843.         //Now save the data to the storage.
  844.         WriteClassStg(pSTM->pstg, CLSID_CosmoFigure);
  845.         WriteFmtUserTypeStg(pSTM->pstg, m_cf
  846.             , PSZ(IDS_CLIPBOARDFORMAT));
  847.  
  848.         if (POLYLINE_E_NONE!=m_pPL->WriteToStorage(pSTM->pstg
  849.             , VERSIONCURRENT))
  850.             {
  851.             /*
  852.              * When someone releases the IStorage, STORAGE.DLL will
  853.              * release the ILockBytes which, having fDeleteOnRelease
  854.              * TRUE (second parameter) will release the memory.
  855.              * That's why we don't have STGM_DELETEONRELEASE on the
  856.              * IStorage.
  857.              */
  858.             pSTM->pstg->Release();
  859.             return FALSE;
  860.             }
  861.  
  862.         pSTM->tymed=TYMED_ISTORAGE;
  863.         return TRUE;
  864.         }
  865.  
  866.     //CHAPTER21MOD
  867.     /*
  868.      * CFSTR_OBJECTDESCRIPTOR and CFSTR_LINKSRCDESCRIPTOR are the
  869.      * same formats, but only copy link source if we have a moniker.
  870.      */
  871.     if (cf==m_cfLinkSrcDescriptor && NULL==m_pMoniker)
  872.         return FALSE;
  873.  
  874.     if (cf==m_cfObjectDescriptor || cf==m_cfLinkSrcDescriptor)
  875.     //End CHAPTER21MOD
  876.         {
  877.         SIZEL   szl, szlT;
  878.         POINTL  ptl;
  879.         RECT    rc;
  880.         //CHAPTER21MOD
  881.         LPTSTR  psz=NULL;
  882.         //End CHAPTER21MOD
  883.  
  884.         m_pPL->SizeGet(&rc);
  885.         SETSIZEL(szlT, rc.right, rc.bottom);
  886.         XformSizeInPixelsToHimetric(NULL, &szlT, &szl);
  887.  
  888.         SETPOINTL(ptl, 0, 0);
  889.  
  890.         //CHAPTER21MOD
  891.         //Include the moniker display name now, if we have one.
  892.         if (m_pMoniker)
  893.             {
  894.             LPBC    pbc;
  895.  
  896.             CreateBindCtx(0, &pbc);
  897.            #ifdef WIN32ANSI
  898.             LPOLESTR    pszW;
  899.  
  900.             m_pMoniker->GetDisplayName(pbc, NULL, &pszW);
  901.             psz=(LPTSTR)CoTaskMemAlloc(512);
  902.             WideCharToMultiByte(CP_ACP, 0, pszW, -1, psz, 512
  903.                 , NULL, NULL);
  904.             CoTaskMemFree((void *)pszW);
  905.            #else
  906.             m_pMoniker->GetDisplayName(pbc, NULL, &psz);
  907.            #endif
  908.             pbc->Release();
  909.             }
  910.  
  911.         pSTM->hGlobal=INOLE_AllocObjectDescriptor
  912.             (CLSID_CosmoFigure, DVASPECT_CONTENT, szl, ptl
  913.             , OLEMISC_RECOMPOSEONRESIZE, PSZ(IDS_OBJECTDESCRIPTION)
  914.             , psz);
  915.  
  916.         CoTaskMemFree((void *)psz);
  917.         //End CHAPTER21MOD
  918.  
  919.         pSTM->tymed=TYMED_HGLOBAL;
  920.         return (NULL!=pSTM->hGlobal);
  921.         }
  922.  
  923.     //CHAPTER21MOD
  924.     if (cf==m_cfLinkSource)
  925.         {
  926.         if (NULL!=m_pMoniker)
  927.             {
  928.             FORMATETC   fe;
  929.             HRESULT     hr;
  930.  
  931.             pSTM->tymed=TYMED_NULL;
  932.             SETDefFormatEtc(fe, cf, TYMED_ISTREAM);
  933.             hr=INOLE_GetLinkSourceData(m_pMoniker
  934.                 , (LPCLSID)&CLSID_CosmoFigure, &fe, pSTM);
  935.  
  936.             return SUCCEEDED(hr);
  937.             }
  938.         }
  939.     //End CHAPTER21MOD
  940.  
  941.     return FALSE;
  942.     }
  943.  
  944.  
  945.  
  946.  
  947.  
  948. /*
  949.  * CCosmoDoc::FQueryPaste
  950.  *
  951.  * Purpose:
  952.  *  Determines if we can paste data from the clipboard.
  953.  *
  954.  * Parameters:
  955.  *  None
  956.  *
  957.  * Return Value:
  958.  *  BOOL            TRUE if data is available, FALSE otherwise.
  959.  */
  960.  
  961. BOOL CCosmoDoc::FQueryPaste(void)
  962.     {
  963.     LPDATAOBJECT    pIDataObject;
  964.     BOOL            fRet;
  965.  
  966.     if (FAILED(OleGetClipboard(&pIDataObject)))
  967.         return FALSE;
  968.  
  969.     fRet=FQueryPasteFromData(pIDataObject);
  970.     pIDataObject->Release();
  971.     return fRet;
  972.     }
  973.  
  974.  
  975.  
  976. /*
  977.  * CCosmoDoc::FQueryPasteFromData
  978.  * (Protected)
  979.  *
  980.  * Purpose:
  981.  *  Determines if we can paste data from a data object.
  982.  *
  983.  * Parameters:
  984.  *  pIDataObject    LPDATAOBJECT from which we might want to paste.
  985.  *
  986.  * Return Value:
  987.  *  BOOL            TRUE if data is available, FALSE otherwise.
  988.  */
  989.  
  990. BOOL CCosmoDoc::FQueryPasteFromData(LPDATAOBJECT pIDataObject)
  991.     {
  992.     FORMATETC       fe;
  993.  
  994.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  995.     return (NOERROR==pIDataObject->QueryGetData(&fe));
  996.     }
  997.  
  998.  
  999.  
  1000.  
  1001. /*
  1002.  * CCosmoDoc::Paste
  1003.  *
  1004.  * Purpose:
  1005.  *  Retrieves the private data format from the clipboard and sets it
  1006.  *  to the current figure in the editor window.
  1007.  *
  1008.  *  Note that if this function is called, then the clipboard format
  1009.  *  is available because the Paste menu item is only enabled if the
  1010.  *  format is present.
  1011.  *
  1012.  * Parameters:
  1013.  *  hWndFrame       HWND of the main window.
  1014.  *
  1015.  * Return Value:
  1016.  *  BOOL            TRUE if successful, FALSE otherwise.
  1017.  */
  1018.  
  1019. BOOL CCosmoDoc::Paste(HWND hWndFrame)
  1020.     {
  1021.     LPDATAOBJECT    pIDataObject;
  1022.     BOOL            fRet;
  1023.  
  1024.     if (FAILED(OleGetClipboard(&pIDataObject)))
  1025.         return FALSE;
  1026.  
  1027.     fRet=PasteFromData(pIDataObject);
  1028.     pIDataObject->Release();
  1029.  
  1030.     return fRet;
  1031.     }
  1032.  
  1033.  
  1034.  
  1035.  
  1036. /*
  1037.  * CCosmoDoc::PasteFromData
  1038.  * (Protected)
  1039.  *
  1040.  * Purpose:
  1041.  *  Retrieves the private data format from a data object and sets
  1042.  *  it to the current figure in the editor window.
  1043.  *
  1044.  * Parameters:
  1045.  *  pIDataObject    LPDATAOBJECT from which to paste.
  1046.  *
  1047.  * Return Value:
  1048.  *  BOOL            TRUE if successful, FALSE otherwise.
  1049.  */
  1050.  
  1051. BOOL CCosmoDoc::PasteFromData(LPDATAOBJECT pIDataObject)
  1052.     {
  1053.     FORMATETC       fe;
  1054.     STGMEDIUM       stm;
  1055.     BOOL            fRet;
  1056.  
  1057.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  1058.     fRet=SUCCEEDED(pIDataObject->GetData(&fe, &stm));
  1059.  
  1060.     if (fRet && NULL!=stm.hGlobal)
  1061.         {
  1062.         m_pPL->DataSetMem(stm.hGlobal, FALSE, FALSE, TRUE);
  1063.         ReleaseStgMedium(&stm);
  1064.         FDirtySet(TRUE);
  1065.         }
  1066.  
  1067.     return fRet;
  1068.     }
  1069.  
  1070.  
  1071.  
  1072.  
  1073. /*
  1074.  * CCosmoDoc::TransferObjectCreate
  1075.  * (Protected)
  1076.  *
  1077.  * Purpose:
  1078.  *  Creates a DataTransferObject and stuffs the current Polyline
  1079.  *  data into it, used for both clipboard and drag-drop operations.
  1080.  *
  1081.  * Parameters:
  1082.  *  fCut            BOOL TRUE if we're cutting, FALSE if we're
  1083.  *                  copying.
  1084.  *
  1085.  * Return Value:
  1086.  *  LPDATAOBJECT    Pointer to the object created, NULL on failure
  1087.  */
  1088.  
  1089. LPDATAOBJECT CCosmoDoc::TransferObjectCreate(BOOL fCut)
  1090.     {
  1091.     UINT            i;
  1092.     HRESULT         hr;
  1093.     STGMEDIUM       stm;
  1094.     FORMATETC       fe;
  1095.     LPDATAOBJECT    pIDataObject=NULL;
  1096.     //CHAPTER21MOD
  1097.     const UINT      cFormats=7;
  1098.     static UINT     rgcf[7]={0, 0, 0, CF_METAFILEPICT, CF_BITMAP, 0, 0};
  1099.     static DWORD    rgtm[7]={TYMED_HGLOBAL, TYMED_ISTORAGE, TYMED_HGLOBAL
  1100.         , TYMED_MFPICT, TYMED_GDI, TYMED_ISTREAM, TYMED_HGLOBAL};
  1101.     //End CHAPTER21MOD
  1102.  
  1103.     hr=CoCreateInstance(CLSID_DataTransferObject, NULL
  1104.         , CLSCTX_INPROC_SERVER, IID_IDataObject
  1105.         , (PPVOID)&pIDataObject);
  1106.  
  1107.     if (FAILED(hr))
  1108.         return NULL;
  1109.  
  1110.     rgcf[0]=m_cf;
  1111.     rgcf[1]=m_cfEmbedSource;
  1112.     rgcf[2]=m_cfObjectDescriptor;
  1113.     //CHAPTER21MOD
  1114.     //Don't include link stuff for cutting (0 format always fails)
  1115.     if (!fCut)
  1116.         {
  1117.         rgcf[5]=m_cfLinkSource;
  1118.         rgcf[6]=m_cfLinkSrcDescriptor;
  1119.         }
  1120.     //End CHAPTER21MOD
  1121.  
  1122.     for (i=0; i < cFormats; i++)
  1123.         {
  1124.         /*
  1125.          * RenderFormat handles memory handles, but for compound doc
  1126.          * formats we need something more.  So if RenderFormat fails
  1127.          * (which it will for i=1, try our latest addition which
  1128.          * writes to a different field in the STGMEDIUM.
  1129.          */
  1130.         stm.hGlobal=RenderFormat(rgcf[i]);
  1131.  
  1132.         if (NULL==stm.hGlobal)
  1133.             {
  1134.             if (!RenderMedium(rgcf[i], &stm))
  1135.                 continue;
  1136.             }
  1137.  
  1138.         stm.tymed=rgtm[i];
  1139.         stm.pUnkForRelease=NULL;
  1140.         SETDefFormatEtc(fe, rgcf[i], rgtm[i]);
  1141.         pIDataObject->SetData(&fe, &stm, TRUE);
  1142.         }
  1143.  
  1144.     return pIDataObject;    //Caller now responsible
  1145.     }
  1146.  
  1147.  
  1148.  
  1149. /*
  1150.  * CCosmoDoc::DropSelectTargetWindow
  1151.  * (Protected)
  1152.  *
  1153.  * Purpose:
  1154.  *  Creates a thin inverted frame around a window that we use to
  1155.  *  show the window as a drop target.  This is a toggle function:
  1156.  *  It uses XOR to create the effect so it must be called twice to
  1157.  *  leave the window as it was.
  1158.  *
  1159.  * Parameters:
  1160.  *  None
  1161.  *
  1162.  * Return Value:
  1163.  *  None
  1164.  */
  1165.  
  1166. void CCosmoDoc::DropSelectTargetWindow(void)
  1167.     {
  1168.     HDC         hDC;
  1169.     RECT        rc;
  1170.     UINT        dd=3;
  1171.     HWND        hWnd;
  1172.  
  1173.     hWnd=m_pPL->Window();
  1174.     hDC=GetWindowDC(hWnd);
  1175.     GetClientRect(hWnd, &rc);
  1176.  
  1177.     //Frame this window with inverted pixels
  1178.  
  1179.     //Top
  1180.     PatBlt(hDC, rc.left, rc.top, rc.right-rc.left, dd, DSTINVERT);
  1181.  
  1182.     //Bottom
  1183.     PatBlt(hDC, rc.left, rc.bottom-dd, rc.right-rc.left, dd
  1184.         , DSTINVERT);
  1185.  
  1186.     //Left excluding regions already affected by top and bottom
  1187.     PatBlt(hDC, rc.left, rc.top+dd, dd, rc.bottom-rc.top-(2*dd)
  1188.         , DSTINVERT);
  1189.  
  1190.     //Right excluding regions already affected by top and bottom
  1191.     PatBlt(hDC, rc.right-dd, rc.top+dd, dd, rc.bottom-rc.top-(2*dd)
  1192.         , DSTINVERT);
  1193.  
  1194.     ReleaseDC(hWnd, hDC);
  1195.     return;
  1196.     }
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202. /*
  1203.  * CCosmoDoc::ColorSet
  1204.  *
  1205.  * Purpose:
  1206.  *  Changes a color used in our contained Polyline.
  1207.  *
  1208.  * Parameters:
  1209.  *  iColor          UINT index of the color to change.
  1210.  *  cr              COLORREF new color.
  1211.  *
  1212.  * Return Value:
  1213.  *  COLORREF        Previous color for the given index.
  1214.  */
  1215.  
  1216. COLORREF CCosmoDoc::ColorSet(UINT iColor, COLORREF cr)
  1217.     {
  1218.     return m_pPL->ColorSet(iColor, cr);
  1219.     }
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225. /*
  1226.  * CCosmoDoc::ColorGet
  1227.  *
  1228.  * Purpose:
  1229.  *  Retrieves a color currently in use in the Polyline.
  1230.  *
  1231.  * Parameters:
  1232.  *  iColor          UINT index of the color to retrieve.
  1233.  *
  1234.  * Return Value:
  1235.  *  COLORREF        Current color for the given index.
  1236.  */
  1237.  
  1238. COLORREF CCosmoDoc::ColorGet(UINT iColor)
  1239.     {
  1240.     return m_pPL->ColorGet(iColor);
  1241.     }
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248. /*
  1249.  * CCosmoDoc::LineStyleSet
  1250.  *
  1251.  * Purpose:
  1252.  *  Changes the line style currently used in the Polyline
  1253.  *
  1254.  * Parameters:
  1255.  *  iStyle          UINT index of the new line style to use.
  1256.  *
  1257.  * Return Value:
  1258.  *  UINT            Previous line style.
  1259.  */
  1260.  
  1261.  
  1262. UINT CCosmoDoc::LineStyleSet(UINT iStyle)
  1263.     {
  1264.     return m_pPL->LineStyleSet(iStyle);
  1265.     }
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.  
  1273. /*
  1274.  * CCosmoDoc::LineStyleGet
  1275.  *
  1276.  * Purpose:
  1277.  *  Retrieves the line style currently used in the Polyline
  1278.  *
  1279.  * Parameters:
  1280.  *  None
  1281.  *
  1282.  * Return Value:
  1283.  *  UINT            Current line style.
  1284.  */
  1285.  
  1286.  
  1287. UINT CCosmoDoc::LineStyleGet(void)
  1288.     {
  1289.     if (NULL==m_pPL)    //m_pPL might not be valid yet
  1290.         return 0L;
  1291.  
  1292.     return m_pPL->LineStyleGet();
  1293.     }
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302. /*
  1303.  * CPolylineAdviseSink::CPolylineAdviseSink
  1304.  * CPolylineAdviseSink::~CPolylineAdviseSink
  1305.  *
  1306.  * Constructor Parameters:
  1307.  *  pv              LPVOID to store in this object
  1308.  */
  1309.  
  1310. CPolylineAdviseSink::CPolylineAdviseSink(LPVOID pv)
  1311.     {
  1312.     m_pv=pv;
  1313.     return;
  1314.     }
  1315.  
  1316.  
  1317. CPolylineAdviseSink::~CPolylineAdviseSink(void)
  1318.     {
  1319.     return;
  1320.     }
  1321.  
  1322.  
  1323.  
  1324.  
  1325.  
  1326. /*
  1327.  * CPolylineAdviseSink::OnPointChange
  1328.  *
  1329.  * Purpose:
  1330.  *  Informs the document that the polyline added or removed a point.
  1331.  *
  1332.  * Parameters:
  1333.  *  None
  1334.  *
  1335.  * Return Value:
  1336.  *  None
  1337.  */
  1338.  
  1339. void CPolylineAdviseSink::OnPointChange(void)
  1340.     {
  1341.     PCDocument      pDoc=(PCDocument)m_pv;
  1342.  
  1343.     pDoc->FDirtySet(TRUE);
  1344.     return;
  1345.     }
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352. /*
  1353.  * CPolylineAdviseSink::OnSizeChange
  1354.  *
  1355.  * Purpose:
  1356.  *  Informs the document that the polyline changed size.
  1357.  *
  1358.  * Parameters:
  1359.  *  None
  1360.  *
  1361.  * Return Value:
  1362.  *  None
  1363.  */
  1364.  
  1365. void CPolylineAdviseSink::OnSizeChange(void)
  1366.     {
  1367.     PCCosmoDoc      pDoc=(PCCosmoDoc)m_pv;
  1368.     RECT            rc;
  1369.     DWORD           dwStyle;
  1370.  
  1371.     /*
  1372.      * Polyline window is informing us that it changed size in
  1373.      * response to setting it's data.  Therefore we have to
  1374.      * size ourselves accordingly but without moving the screen
  1375.      * position of the polyline window.
  1376.      */
  1377.  
  1378.     pDoc->m_fNoSize=TRUE;
  1379.  
  1380.     //Set the document window size.
  1381.     GetWindowRect(pDoc->m_pPL->Window(), &rc);
  1382.     InflateRect(&rc, 8, 8);
  1383.  
  1384.     //Adjust for a window sans menu
  1385.     dwStyle=GetWindowLong(pDoc->m_hWnd, GWL_STYLE);
  1386.     AdjustWindowRect(&rc, dwStyle, FALSE);
  1387.  
  1388.     SetWindowPos(pDoc->m_hWnd, NULL, 0, 0, rc.right-rc.left
  1389.         , rc.bottom-rc.top, SWP_NOMOVE | SWP_NOZORDER);
  1390.  
  1391.     if (NULL!=pDoc->m_pAdv)
  1392.         pDoc->m_pAdv->OnSizeChange(pDoc, &rc);
  1393.  
  1394.     pDoc->m_fNoSize=FALSE;
  1395.     pDoc->FDirtySet(TRUE);
  1396.  
  1397.     return;
  1398.     }
  1399.  
  1400.  
  1401.  
  1402.  
  1403.  
  1404. /*
  1405.  * CPolylineAdviseSink::OnDataChange
  1406.  *
  1407.  * Purpose:
  1408.  *  Informs the document that the polyline data changed.
  1409.  *
  1410.  * Parameters:
  1411.  *  None
  1412.  *
  1413.  * Return Value:
  1414.  *  None
  1415.  */
  1416.  
  1417. void CPolylineAdviseSink::OnDataChange(void)
  1418.     {
  1419.     PCCosmoDoc      pDoc=(PCCosmoDoc)m_pv;
  1420.  
  1421.     if (NULL!=pDoc->m_pAdv)
  1422.         pDoc->m_pAdv->OnDataChange(pDoc);
  1423.  
  1424.     pDoc->FDirtySet(TRUE);
  1425.     return;
  1426.     }
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432. /*
  1433.  * CPolylineAdviseSink::OnColorChange
  1434.  *
  1435.  * Purpose:
  1436.  *  Informs the document that the polyline data changed a color.
  1437.  *
  1438.  * Parameters:
  1439.  *  None
  1440.  *
  1441.  * Return Value:
  1442.  *  None
  1443.  */
  1444.  
  1445. void CPolylineAdviseSink::OnColorChange(void)
  1446.     {
  1447.     PCCosmoDoc      pDoc=(PCCosmoDoc)m_pv;
  1448.  
  1449.     pDoc->FDirtySet(TRUE);
  1450.     return;
  1451.     }
  1452.  
  1453.  
  1454.  
  1455.  
  1456.  
  1457. /*
  1458.  * CPolylineAdviseSink::OnLineStyleChange
  1459.  *
  1460.  * Purpose:
  1461.  *  Informs the document that the polyline changed its line style.
  1462.  *
  1463.  * Parameters:
  1464.  *  None
  1465.  *
  1466.  * Return Value:
  1467.  *  None
  1468.  */
  1469.  
  1470. void CPolylineAdviseSink::OnLineStyleChange(void)
  1471.     {
  1472.     PCCosmoDoc      pDoc=(PCCosmoDoc)m_pv;
  1473.  
  1474.     pDoc->FDirtySet(TRUE);
  1475.     return;
  1476.     }
  1477.