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 / chap08 / cocosmo / document.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  22KB  |  1,032 lines

  1. /*
  2.  * DOCUMENT.CPP
  3.  * Component Cosmo Chapter 8
  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 "cocosmo.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.     m_pIConnectPt=NULL;
  37.     m_dwCookie=0;
  38.  
  39.     //CHAPTER8MOD
  40.     m_pIStorage=NULL;
  41.     m_pp.psModel=PERSIST_UNKNOWN;
  42.     m_pp.pIP.pIPersistStorage=NULL; //Affects all pointers
  43.     //End CHAPTER8MOD
  44.     return;
  45.     }
  46.  
  47.  
  48. CCosmoDoc::~CCosmoDoc(void)
  49.     {
  50.     //CHAPTER8MOD
  51.     ReleaseInterface(m_pp.pIP.pIPersistStorage);
  52.     ReleaseInterface(m_pIStorage);
  53.     //End CHAPTER8MOD
  54.  
  55.     if (NULL!=m_pIConnectPt)
  56.         {
  57.         m_pIConnectPt->Unadvise(m_dwCookie);
  58.         ReleaseInterface(m_pIConnectPt);
  59.         }
  60.  
  61.     ReleaseInterface(m_pPL);
  62.     ReleaseInterface(m_pPLAdv);
  63.  
  64.     CoFreeUnusedLibraries();
  65.     return;
  66.     }
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. /*
  74.  * CCosmoDoc::Init
  75.  *
  76.  * Purpose:
  77.  *  Initializes an already created document window.  The client
  78.  *  actually creates the window for us, then passes that here for
  79.  *  further initialization.
  80.  *
  81.  * Parameters:
  82.  *  pDI             PDOCUMENTINIT containing initialization
  83.  *                  parameters.
  84.  *
  85.  * Return Value:
  86.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  87.  */
  88.  
  89. BOOL CCosmoDoc::Init(PDOCUMENTINIT pDI)
  90.     {
  91.     RECT                        rc;
  92.     HRESULT                     hr;
  93.     IConnectionPointContainer  *pCPC;
  94.  
  95.     //Change the stringtable range to our customization.
  96.     pDI->idsMin=IDS_DOCUMENTMIN;
  97.     pDI->idsMax=IDS_DOCUMENTMAX;
  98.  
  99.     //Do default initialization
  100.     if (!CDocument::Init(pDI))
  101.         return FALSE;
  102.  
  103.     //CHAPTER8MOD
  104.     //Create the Polyline component
  105.     hr=CoCreateInstance(CLSID_Polyline8, NULL, CLSCTX_INPROC_SERVER
  106.         , IID_IPolyline8, (PPVOID)&m_pPL);
  107.     //End CHAPTER8MOD
  108.  
  109.     if (FAILED(hr))
  110.         {
  111.         //Warn that we could not load the Polyline
  112.         MessageBox(pDI->hWndDoc, PSZ(IDS_NOPOLYLINE)
  113.             , PSZ(IDS_CAPTION), MB_OK);
  114.         return FALSE;
  115.         }
  116.  
  117.     //Initialize the contained Polyline which creates a window.
  118.     GetClientRect(m_hWnd, &rc);
  119.     InflateRect(&rc, -8, -8);
  120.  
  121.     if (FAILED(m_pPL->Init(m_hWnd, &rc, WS_CHILD | WS_VISIBLE
  122.         , ID_POLYLINE)))
  123.         return FALSE;
  124.  
  125.     //Set up an advise on the Polyline.
  126.     m_pPLAdv=new CPolylineAdviseSink(this);
  127.     m_pPLAdv->AddRef();
  128.  
  129.     if (SUCCEEDED(m_pPL->QueryInterface(IID_IConnectionPointContainer
  130.         , (PPVOID)&pCPC)))
  131.         {
  132.         //CHAPTER8MOD
  133.         if (SUCCEEDED(pCPC->FindConnectionPoint
  134.             (IID_IPolylineAdviseSink8, &m_pIConnectPt)))
  135.         //End CHAPTER8MOD
  136.             {
  137.             m_pIConnectPt->Advise((LPUNKNOWN)m_pPLAdv, &m_dwCookie);
  138.             }
  139.  
  140.         pCPC->Release();
  141.         }
  142.  
  143.     //CHAPTER8MOD
  144.     /*
  145.      * Check for the storage model being used in Polyline.
  146.      * Any InitNew member will be called from CCosmoDoc::Load.
  147.      */
  148.     hr=m_pPL->QueryInterface(IID_IPersistStorage
  149.         , (PPVOID)&m_pp.pIP.pIPersistStorage);
  150.  
  151.     if (SUCCEEDED(hr))
  152.         m_pp.psModel=PERSIST_STORAGE;
  153.     else
  154.         {
  155.         hr=m_pPL->QueryInterface(IID_IPersistStreamInit
  156.             , (PPVOID)&m_pp.pIP.pIPersistStreamInit);
  157.  
  158.         if (SUCCEEDED(hr))
  159.             m_pp.psModel=PERSIST_STREAMINIT;
  160.         else
  161.             {
  162.             hr=m_pPL->QueryInterface(IID_IPersistStream
  163.             , (PPVOID)&m_pp.pIP.pIPersistStream);
  164.  
  165.             if (SUCCEEDED(hr))
  166.                 m_pp.psModel=PERSIST_STREAM;
  167.             else
  168.                 return FALSE;
  169.             }
  170.         }
  171.  
  172.     //End CHAPTER8MOD
  173.  
  174.     return TRUE;
  175.     }
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183. /*
  184.  * CCosmoDoc::FMessageHook
  185.  *
  186.  * Purpose:
  187.  *  Processes WM_SIZE for the document so we can resize
  188.  *  the Polyline.
  189.  *
  190.  * Parameters:
  191.  *  <WndProc Parameters>
  192.  *  pLRes           LRESULT * in which to store the return
  193.  *                  value for the message.
  194.  *
  195.  * Return Value:
  196.  *  BOOL            TRUE to prevent further processing,
  197.  *                  FALSE otherwise.
  198.  */
  199.  
  200. BOOL CCosmoDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  201.     , LPARAM lParam, LRESULT *pLRes)
  202.     {
  203.     UINT        dx, dy;
  204.     RECT        rc;
  205.  
  206.     *pLRes=0;
  207.  
  208.     if (WM_SIZE==iMsg)
  209.         {
  210.         //Don't effect the Polyline size to or from minimized state.
  211.         if (SIZE_MINIMIZED!=wParam && SIZE_MINIMIZED !=m_uPrevSize)
  212.             {
  213.             //When we change size, resize any Polyline we hold.
  214.             dx=LOWORD(lParam);
  215.             dy=HIWORD(lParam);
  216.  
  217.             /*
  218.              * If we are getting WM_SIZE in response to a Polyline
  219.              * notification, then don't resize the Polyline window
  220.              * again.
  221.              */
  222.             if (!m_fNoSize && NULL!=m_pPL)
  223.                 {
  224.                 //Resize the polyline to fit the new client
  225.                 SetRect(&rc, 8, 8, dx-8, dy-8);
  226.                 m_pPL->RectSet(&rc, FALSE);
  227.  
  228.                 /*
  229.                  * We consider sizing something that makes the file
  230.                  * dirty, but not until we've finished the create
  231.                  * process, which is why we set fNoDirty to FALSE
  232.                  * in WM_CREATE since we get a WM_SIZE on the first
  233.                  * creation.
  234.                  */
  235.                 if (!m_fNoDirty)
  236.                     FDirtySet(TRUE);
  237.  
  238.                 SetRect(&rc, 0, 0, dx, dy);
  239.  
  240.                 if (NULL!=m_pAdv)
  241.                     m_pAdv->OnSizeChange(this, &rc);
  242.  
  243.                 m_fNoDirty=FALSE;
  244.                 }
  245.             }
  246.  
  247.         m_uPrevSize=wParam;
  248.         }
  249.  
  250.     /*
  251.      * We return FALSE even on WM_SIZE so we can let the default
  252.      * procedure handle maximized MDI child windows appropriately.
  253.      */
  254.     return FALSE;
  255.     }
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264. /*
  265.  * CCosmoDoc::Clear
  266.  *
  267.  * Purpose:
  268.  *  Sets all contents in the document back to defaults with
  269.  *  no filename.
  270.  *
  271.  * Paramters:
  272.  *  None
  273.  *
  274.  * Return Value:
  275.  *  None
  276.  */
  277.  
  278. void CCosmoDoc::Clear(void)
  279.     {
  280.     //Completely reset the polyline
  281.     m_pPL->New();
  282.  
  283.     CDocument::Clear();
  284.     return;
  285.     }
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292. /*
  293.  * CCosmoDoc::Load
  294.  *
  295.  * Purpose:
  296.  *  Loads a given document without any user interface overwriting
  297.  *  the previous contents of the Polyline window.  We do this by
  298.  *  opening the file and telling the Polyline to load itself from
  299.  *  that file.
  300.  *
  301.  * Parameters:
  302.  *  fChangeFile     BOOL indicating if we're to update the window
  303.  *                  title and the filename from using this file.
  304.  *  pszFile         LPTSTR to the filename to load, NULL if the file
  305.  *                  is new and untitled.
  306.  *
  307.  * Return Value:
  308.  *  UINT            An error value from DOCERR_*
  309.  */
  310.  
  311. UINT CCosmoDoc::Load(BOOL fChangeFile, LPTSTR pszFile)
  312.     {
  313.     HRESULT             hr;
  314.     //CHAPTER8MOD
  315.     LPSTORAGE           pIStorage;
  316.  
  317.     if (NULL==pszFile)
  318.         {
  319.         //CHAPTER8MOD
  320.         /*
  321.          * As a user of an IPersistStorage we have to provide all
  322.          * objects with an IStorage they can use for incremental
  323.          * access passing that storage to InitNew.  Here we create
  324.          * a temporary file that we don't bother holding on to.
  325.          * If the object doesn't use it, then our Release destroys
  326.          * it immediately.
  327.          */
  328.  
  329.         hr=StgCreateDocfile(NULL, STGM_DIRECT | STGM_READWRITE
  330.             | STGM_CREATE | STGM_DELETEONRELEASE
  331.             | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  332.  
  333.         if (FAILED(hr))
  334.             return DOCERR_COULDNOTOPEN;
  335.  
  336.         if (PERSIST_STORAGE==m_pp.psModel)
  337.             m_pp.pIP.pIPersistStorage->InitNew(pIStorage);
  338.         else
  339.             {
  340.             if (PERSIST_STREAMINIT==m_pp.psModel)
  341.                 m_pp.pIP.pIPersistStreamInit->InitNew();
  342.             }
  343.  
  344.         m_pIStorage=pIStorage;
  345.         //End CHAPTER8MOD
  346.  
  347.         Rename(NULL);
  348.         return DOCERR_NONE;
  349.         }
  350.  
  351.     //CHAPTER8MOD
  352.     /*
  353.      * Open a storage and have the Polyline read its data
  354.      * using whatever persistence model it employs.
  355.      */
  356.     hr=StgOpenStorage(pszFile, NULL, STGM_DIRECT | STGM_READWRITE
  357.         | STGM_SHARE_EXCLUSIVE, NULL, 0, &pIStorage);
  358.  
  359.     if (FAILED(hr))
  360.         return DOCERR_COULDNOTOPEN;
  361.  
  362.     if (PERSIST_STORAGE==m_pp.psModel)
  363.         hr=m_pp.pIP.pIPersistStorage->Load(pIStorage);
  364.     else
  365.         {
  366.         LPSTREAM    pIStream;
  367.  
  368.         hr=pIStorage->OpenStream(SZSTREAM, 0, STGM_DIRECT
  369.             | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  370.  
  371.         if (SUCCEEDED(hr))
  372.             {
  373.             //This also works for PERSIST_STREAMINIT
  374.             hr=m_pp.pIP.pIPersistStream->Load(pIStream);
  375.             pIStream->Release();
  376.             }
  377.         }
  378.  
  379.     m_pIStorage=pIStorage;
  380.     //End CHAPTER8MOD
  381.  
  382.     if (FAILED(hr))
  383.         return DOCERR_READFAILURE;
  384.  
  385.     if (fChangeFile)
  386.         Rename(pszFile);
  387.  
  388.     //Importing a file makes things dirty
  389.     FDirtySet(!fChangeFile);
  390.  
  391.     return DOCERR_NONE;
  392.     }
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400. /*
  401.  * CCosmoDoc::Save
  402.  *
  403.  * Purpose:
  404.  *  Writes the file to a known filename, requiring that the user
  405.  *  has previously used FileOpen or FileSaveAs in order to have
  406.  *  a filename.
  407.  *
  408.  * Parameters:
  409.  *  uType           UINT indicating the type of file the user
  410.  *                  requested to save in the File Save As dialog.
  411.  *  pszFile         LPTSTR under which to save.  If NULL, use the
  412.  *                  current name.
  413.  *
  414.  * Return Value:
  415.  *  UINT            An error value from DOCERR_*
  416.  */
  417.  
  418. UINT CCosmoDoc::Save(UINT uType, LPTSTR pszFile)
  419.     {
  420.     BOOL                fRename=TRUE;
  421.     HRESULT             hr;
  422.     //CHAPTER8MOD
  423.     LPSTORAGE           pIStorage;
  424.     BOOL                fSameAsLoad;
  425.  
  426.     //If Save or Save As under the same name, do Save.
  427.     if (NULL==pszFile || 0==lstrcmpi(pszFile, m_szFile))
  428.         {
  429.         fRename=FALSE;
  430.         pszFile=m_szFile;
  431.  
  432.         /*
  433.          * If we're saving to an existing storage, just pass
  434.          * the IStorage we have from Load along with TRUE
  435.          * in fSameAsLoad.
  436.          */
  437.         fSameAsLoad=TRUE;
  438.         }
  439.     else
  440.         {
  441.         /*
  442.          * In Component Cosmo, we only deal with one version of
  443.          * data; all the code in Chapter 1 Cosmo that dealt with
  444.          * 1.0 and 2.0 files has been removed.
  445.          */
  446.  
  447.         hr=StgCreateDocfile(pszFile, STGM_DIRECT | STGM_READWRITE
  448.             | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  449.  
  450.         if (FAILED(hr))
  451.             return DOCERR_COULDNOTOPEN;
  452.  
  453.         //Tell the object to save into this new storage
  454.         fSameAsLoad=FALSE;
  455.  
  456.         //Update our variable
  457.         m_pIStorage->Release();
  458.         m_pIStorage=pIStorage;
  459.         }
  460.  
  461.     if (PERSIST_STORAGE==m_pp.psModel)
  462.         {
  463.         hr=m_pp.pIP.pIPersistStorage->Save(m_pIStorage, fSameAsLoad);
  464.  
  465.         if (SUCCEEDED(hr))
  466.             {
  467.             hr=m_pp.pIP.pIPersistStorage->SaveCompleted(fSameAsLoad
  468.                 ? NULL : m_pIStorage);
  469.             }
  470.         }
  471.     else
  472.         {
  473.         LPSTREAM    pIStream;
  474.  
  475.         hr=m_pIStorage->CreateStream(SZSTREAM, STGM_DIRECT
  476.             | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE
  477.             , 0, 0, &pIStream);
  478.  
  479.         if (SUCCEEDED(hr))
  480.             {
  481.             //This also works for PERSIST_STREAMINIT
  482.             hr=m_pp.pIP.pIPersistStream->Save(pIStream, TRUE);
  483.             pIStream->Release();
  484.             }
  485.         }
  486.     //End CHAPTER8MOD
  487.  
  488.     if (FAILED(hr))
  489.         return DOCERR_WRITEFAILURE;
  490.  
  491.     //Saving makes us clean
  492.     FDirtySet(FALSE);
  493.  
  494.     if (fRename)
  495.         Rename(pszFile);
  496.  
  497.     return DOCERR_NONE;
  498.     }
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505. /*
  506.  * CCosmoDoc::Undo
  507.  *
  508.  * Purpose:
  509.  *  Reverses a previous action.
  510.  *
  511.  * Parameters:
  512.  *  None
  513.  *
  514.  * Return Value:
  515.  *  None
  516.  */
  517.  
  518. void CCosmoDoc::Undo(void)
  519.     {
  520.     m_pPL->Undo();
  521.     return;
  522.     }
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529. /*
  530.  * CCosmoDoc::Clip
  531.  *
  532.  * Purpose:
  533.  *  Places a private format, a metafile, and a bitmap of the display
  534.  *  on the clipboard, optionally implementing Cut by deleting the
  535.  *  data in the current window after rendering.
  536.  *
  537.  * Parameters:
  538.  *  hWndFrame       HWND of the main window.
  539.  *  fCut            BOOL indicating cut (TRUE) or copy (FALSE).
  540.  *
  541.  * Return Value:
  542.  *  BOOL            TRUE if successful, FALSE otherwise.
  543.  */
  544.  
  545. BOOL CCosmoDoc::Clip(HWND hWndFrame, BOOL fCut)
  546.     {
  547.     BOOL            fRet=TRUE;
  548.     HGLOBAL         hMem;
  549.     UINT            i;
  550.  
  551.     //This array is so we can loop over the formats we provide.
  552.     static UINT     rgcf[3]={0, CF_METAFILEPICT, CF_BITMAP};
  553.     const UINT      cFormats=3;
  554.  
  555.     if (!OpenClipboard(hWndFrame))
  556.         return FALSE;
  557.  
  558.     //Clean out whatever junk is in the clipboard.
  559.     EmptyClipboard();
  560.  
  561.     rgcf[0]=m_cf;
  562.  
  563.     for (i=0; i < cFormats; i++)
  564.         {
  565.         //Copy private data first.
  566.         hMem=RenderFormat(rgcf[i]);
  567.  
  568.         if (NULL!=hMem)
  569.             SetClipboardData(rgcf[i], hMem);
  570.         else
  571.             fRet &=FALSE;
  572.         }
  573.  
  574.     //Free clipboard ownership.
  575.     CloseClipboard();
  576.  
  577.     //Delete our current data if copying succeeded.
  578.     if (fRet && fCut)
  579.         {
  580.         m_pPL->New();
  581.         FDirtySet(TRUE);
  582.         }
  583.  
  584.     return fRet;
  585.     }
  586.  
  587.  
  588.  
  589.  
  590.  
  591. /*
  592.  * CCosmoDoc::RenderFormat
  593.  *
  594.  * Purpose:
  595.  *  Renders a specific clipboard format into global memory.
  596.  *
  597.  * Parameters:
  598.  *  cf              UINT format to render.
  599.  *
  600.  * Return Value:
  601.  *  HGLOBAL         Global memory handle containing the data.
  602.  */
  603.  
  604. HGLOBAL CCosmoDoc::RenderFormat(UINT cf)
  605.     {
  606.     HGLOBAL     hMem;
  607.  
  608.     if (cf==m_cf)
  609.         {
  610.         m_pPL->DataGetMem(&hMem);
  611.         return hMem;
  612.         }
  613.  
  614.     switch (cf)
  615.         {
  616.         case CF_METAFILEPICT:
  617.             m_pPL->RenderMetafilePict(&hMem);
  618.             return hMem;
  619.  
  620.         case CF_BITMAP:
  621.             m_pPL->RenderBitmap((HBITMAP *)&hMem);
  622.             return hMem;
  623.         }
  624.  
  625.     return NULL;
  626.     }
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634. /*
  635.  * CCosmoDoc::FQueryPaste
  636.  *
  637.  * Purpose:
  638.  *  Determines if we can paste data from the clipboard.
  639.  *
  640.  * Parameters:
  641.  *  None
  642.  *
  643.  * Return Value:
  644.  *  BOOL            TRUE if data is available, FALSE otherwise.
  645.  */
  646.  
  647. BOOL CCosmoDoc::FQueryPaste(void)
  648.     {
  649.     return IsClipboardFormatAvailable(m_cf);
  650.     }
  651.  
  652.  
  653.  
  654.  
  655.  
  656. /*
  657.  * CCosmoDoc::Paste
  658.  *
  659.  * Purpose:
  660.  *  Retrieves the private data format from the clipboard and sets it
  661.  *  to the current figure in the editor window.
  662.  *
  663.  *  Note that if this function is called, then the clipboard format
  664.  *  is available because the Paste menu item is only enabled if the
  665.  *  format is present.
  666.  *
  667.  * Parameters:
  668.  *  hWndFrame       HWND of the main window.
  669.  *
  670.  * Return Value:
  671.  *  BOOL            TRUE if successful, FALSE otherwise.
  672.  */
  673.  
  674. BOOL CCosmoDoc::Paste(HWND hWndFrame)
  675.     {
  676.     HGLOBAL         hMem;
  677.     PPOLYLINEDATA   ppl;
  678.     BOOL            fRet=FALSE;
  679.  
  680.     if (!OpenClipboard(hWndFrame))
  681.         return FALSE;
  682.  
  683.     hMem=GetClipboardData(m_cf);
  684.  
  685.     if (NULL!=hMem)
  686.         {
  687.         ppl=(PPOLYLINEDATA)GlobalLock(hMem);
  688.  
  689.         //TRUE in wParam to cause PLN_SIZECHANGE notification
  690.         m_pPL->DataSet(ppl, FALSE, TRUE);
  691.         GlobalUnlock(hMem);
  692.  
  693.         FDirtySet(TRUE);
  694.         fRet=TRUE;
  695.         }
  696.  
  697.     CloseClipboard();
  698.     return fRet;
  699.     }
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706. /*
  707.  * CCosmoDoc::ColorSet
  708.  *
  709.  * Purpose:
  710.  *  Changes a color used in our contained Polyline.
  711.  *
  712.  * Parameters:
  713.  *  iColor          UINT index of the color to change.
  714.  *  cr              COLORREF new color.
  715.  *
  716.  * Return Value:
  717.  *  COLORREF        Previous color for the given index.
  718.  */
  719.  
  720. COLORREF CCosmoDoc::ColorSet(UINT iColor, COLORREF cr)
  721.     {
  722.     COLORREF    crRet;
  723.  
  724.     m_pPL->ColorSet(iColor, cr, &crRet);
  725.     return crRet;
  726.     }
  727.  
  728.  
  729.  
  730.  
  731.  
  732. /*
  733.  * CCosmoDoc::ColorGet
  734.  *
  735.  * Purpose:
  736.  *  Retrieves a color currently in use in the Polyline.
  737.  *
  738.  * Parameters:
  739.  *  iColor          UINT index of the color to retrieve.
  740.  *
  741.  * Return Value:
  742.  *  COLORREF        Current color for the given index.
  743.  */
  744.  
  745. COLORREF CCosmoDoc::ColorGet(UINT iColor)
  746.     {
  747.     COLORREF    crRet;
  748.  
  749.     m_pPL->ColorGet(iColor, &crRet);
  750.     return crRet;
  751.     }
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758. /*
  759.  * CCosmoDoc::LineStyleSet
  760.  *
  761.  * Purpose:
  762.  *  Changes the line style currently used in the Polyline
  763.  *
  764.  * Parameters:
  765.  *  iStyle          UINT index of the new line style to use.
  766.  *
  767.  * Return Value:
  768.  *  UINT            Previous line style.
  769.  */
  770.  
  771. UINT CCosmoDoc::LineStyleSet(UINT iStyle)
  772.     {
  773.     UINT    i;
  774.  
  775.     m_pPL->LineStyleSet(iStyle, &i);
  776.     return i;
  777.     }
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785. /*
  786.  * CCosmoDoc::LineStyleGet
  787.  *
  788.  * Purpose:
  789.  *  Retrieves the line style currently used in the Polyline
  790.  *
  791.  * Parameters:
  792.  *  None
  793.  *
  794.  * Return Value:
  795.  *  UINT            Current line style.
  796.  */
  797.  
  798.  
  799. UINT CCosmoDoc::LineStyleGet(void)
  800.     {
  801.     UINT    i=0;
  802.  
  803.     //m_pPL might not be valid yet.
  804.     if (NULL!=m_pPL)
  805.         m_pPL->LineStyleGet(&i);
  806.  
  807.     return i;
  808.     }
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816. /*
  817.  * CPolylineAdviseSink::CPolylineAdviseSink
  818.  * CPolylineAdviseSink::~CPolylineAdviseSink
  819.  *
  820.  * Constructor Parameters:
  821.  *  pDoc            PCCosmoDoc to store in this object
  822.  */
  823.  
  824. CPolylineAdviseSink::CPolylineAdviseSink(PCCosmoDoc pDoc)
  825.     {
  826.     m_pDoc=pDoc;
  827.     m_cRef=0;
  828.     AddRef();
  829.     return;
  830.     }
  831.  
  832.  
  833. CPolylineAdviseSink::~CPolylineAdviseSink(void)
  834.     {
  835.     return;
  836.     }
  837.  
  838.  
  839.  
  840.  
  841. /*
  842.  * CPolylineAdviseSink::QueryInterface
  843.  * CPolylineAdviseSink::AddRef
  844.  * CPolylineAdviseSink::Release
  845.  *
  846.  * Purpose:
  847.  *  IUnknown members for this IPolylineAdviseSink implementations.
  848.  */
  849.  
  850. STDMETHODIMP CPolylineAdviseSink::QueryInterface(REFIID riid
  851.     , PPVOID ppv)
  852.     {
  853.     *ppv=NULL;
  854.  
  855.     //CHAPTER8MOD
  856.     if (IID_IUnknown==riid || IID_IPolylineAdviseSink8==riid)
  857.         *ppv=this;
  858.     //End CHAPTER8MOD
  859.  
  860.     if (NULL!=*ppv)
  861.         {
  862.         ((LPUNKNOWN)*ppv)->AddRef();
  863.         return NOERROR;
  864.         }
  865.  
  866.     return ResultFromScode(S_FALSE);
  867.     }
  868.  
  869.  
  870. STDMETHODIMP_(ULONG) CPolylineAdviseSink::AddRef(void)
  871.     {
  872.     return ++m_cRef;
  873.     }
  874.  
  875.  
  876. STDMETHODIMP_(ULONG) CPolylineAdviseSink::Release(void)
  877.     {
  878.     if (0L!=--m_cRef)
  879.         return m_cRef;
  880.  
  881.     delete this;
  882.     return 0;
  883.     }
  884.  
  885.  
  886.  
  887.  
  888. /*
  889.  * CPolylineAdviseSink::OnPointChange
  890.  *
  891.  * Purpose:
  892.  *  Informs the document that the polyline added or removed a point.
  893.  *
  894.  * Parameters:
  895.  *  None
  896.  *
  897.  * Return Value:
  898.  *  None
  899.  */
  900.  
  901. STDMETHODIMP_(void) CPolylineAdviseSink::OnPointChange(void)
  902.     {
  903.     m_pDoc->FDirtySet(TRUE);
  904.     return;
  905.     }
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912. /*
  913.  * CPolylineAdviseSink::OnSizeChange
  914.  *
  915.  * Purpose:
  916.  *  Informs the document that the polyline changed size.
  917.  *
  918.  * Parameters:
  919.  *  None
  920.  *
  921.  * Return Value:
  922.  *  None
  923.  */
  924.  
  925. STDMETHODIMP_(void) CPolylineAdviseSink::OnSizeChange(void)
  926.     {
  927.     RECT            rc;
  928.     DWORD           dwStyle;
  929.     HWND            hWnd;
  930.  
  931.     /*
  932.      * Polyline window is informing us that it changed size in
  933.      * response to setting it's data.  Therefore we have to
  934.      * size ourselves accordingly but without moving the screen
  935.      * position of the polyline window.
  936.      */
  937.  
  938.     m_pDoc->m_fNoSize=TRUE;
  939.  
  940.     //Set the document window size.
  941.     m_pDoc->m_pPL->Window(&hWnd);
  942.     GetWindowRect(hWnd, &rc);
  943.     InflateRect(&rc, 8, 8);
  944.  
  945.     //Adjust for a window sans menu
  946.     dwStyle=GetWindowLong(m_pDoc->m_hWnd, GWL_STYLE);
  947.     AdjustWindowRect(&rc, dwStyle, FALSE);
  948.  
  949.     SetWindowPos(m_pDoc->m_hWnd, NULL, 0, 0, rc.right-rc.left
  950.         , rc.bottom-rc.top, SWP_NOMOVE | SWP_NOZORDER);
  951.  
  952.     if (NULL!=m_pDoc->m_pAdv)
  953.         m_pDoc->m_pAdv->OnSizeChange(m_pDoc, &rc);
  954.  
  955.     m_pDoc->m_fNoSize=FALSE;
  956.     m_pDoc->FDirtySet(TRUE);
  957.  
  958.     return;
  959.     }
  960.  
  961.  
  962.  
  963.  
  964.  
  965. /*
  966.  * CPolylineAdviseSink::OnDataChange
  967.  *
  968.  * Purpose:
  969.  *  Informs the document that the polyline data changed.
  970.  *
  971.  * Parameters:
  972.  *  None
  973.  *
  974.  * Return Value:
  975.  *  None
  976.  */
  977.  
  978. STDMETHODIMP_(void) CPolylineAdviseSink::OnDataChange(void)
  979.     {
  980.     if (NULL!=m_pDoc->m_pAdv)
  981.         m_pDoc->m_pAdv->OnDataChange(m_pDoc);
  982.  
  983.     m_pDoc->FDirtySet(TRUE);
  984.     return;
  985.     }
  986.  
  987.  
  988.  
  989.  
  990.  
  991. /*
  992.  * CPolylineAdviseSink::OnColorChange
  993.  *
  994.  * Purpose:
  995.  *  Informs the document that the polyline data changed a color.
  996.  *
  997.  * Parameters:
  998.  *  None
  999.  *
  1000.  * Return Value:
  1001.  *  None
  1002.  */
  1003.  
  1004. STDMETHODIMP_(void) CPolylineAdviseSink::OnColorChange(void)
  1005.     {
  1006.     m_pDoc->FDirtySet(TRUE);
  1007.     return;
  1008.     }
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014. /*
  1015.  * CPolylineAdviseSink::OnLineStyleChange
  1016.  *
  1017.  * Purpose:
  1018.  *  Informs the document that the polyline changed its line style.
  1019.  *
  1020.  * Parameters:
  1021.  *  None
  1022.  *
  1023.  * Return Value:
  1024.  *  None
  1025.  */
  1026.  
  1027. STDMETHODIMP_(void) CPolylineAdviseSink::OnLineStyleChange(void)
  1028.     {
  1029.     m_pDoc->FDirtySet(TRUE);
  1030.     return;
  1031.     }
  1032.