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 / chap13 / patron / document.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  21KB  |  960 lines

  1. /*
  2.  * DOCUMENT.CPP
  3.  * Patron Chapter 13
  4.  *
  5.  * Implementation of the CPatronDoc derivation of CDocument that
  6.  * manages pages for us.
  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 "patron.h"
  17. #include <memory.h>
  18. #include <dlgs.h>       //Pring Dlg button IDs
  19.  
  20.  
  21. /*
  22.  * CPatronDoc::CPatronDoc
  23.  * CPatronDoc::~CPatronDoc
  24.  *
  25.  * Constructor Parameters:
  26.  *  hInst           HINSTANCE of the application.
  27.  *  pFR             PCFrame of the frame object.
  28.  *  pAdv            PCDocumentAdviseSink to notify on events.
  29.  */
  30.  
  31. CPatronDoc::CPatronDoc(HINSTANCE hInst, PCFrame pFR
  32.     , PCDocumentAdviseSink pAdv)
  33.     : CDocument(hInst, pFR, pAdv)
  34.     {
  35.     m_pPG=NULL;
  36.     m_lVer=VERSIONCURRENT;
  37.     m_pIStorage=NULL;
  38.     m_fPrintSetup=TRUE;
  39.  
  40.     //CHAPTER13MOD
  41.     m_pDropTarget=NULL;
  42.     //End CHAPTER13MOD
  43.     return;
  44.     }
  45.  
  46.  
  47. CPatronDoc::~CPatronDoc(void)
  48.     {
  49.     if (NULL!=m_pPG)
  50.         delete m_pPG;
  51.  
  52.     ReleaseInterface(m_pIStorage);
  53.     CoFreeUnusedLibraries();
  54.     return;
  55.     }
  56.  
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  * CPatronDoc::Init
  63.  *
  64.  * Purpose:
  65.  *  Initializes an already created document window.  The client
  66.  *  actually creates the window for us, then passes that here for
  67.  *  further initialization.
  68.  *
  69.  * Parameters:
  70.  *  pDI             PDOCUMENTINIT containing initialization
  71.  *                  parameters.
  72.  *
  73.  * Return Value:
  74.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  75.  */
  76.  
  77. BOOL CPatronDoc::Init(PDOCUMENTINIT pDI)
  78.     {
  79.     //Change the stringtable range to our customization.
  80.     pDI->idsMin=IDS_DOCUMENTMIN;
  81.     pDI->idsMax=IDS_DOCUMENTMAX;
  82.  
  83.     //Do default initialization
  84.     if (!CDocument::Init(pDI))
  85.         return FALSE;
  86.  
  87.     //Pages are created when we get a Load later.
  88.     return TRUE;
  89.     }
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97. /*
  98.  * CPatronDoc::FMessageHook
  99.  *
  100.  * Purpose:
  101.  *  Processes WM_SIZE for the document so we can resize the Pages
  102.  *  window.
  103.  *
  104.  * Parameters:
  105.  *  <WndProc Parameters>
  106.  *  pLRes           LRESULT * in which to store the return
  107.  *                  value for the message.
  108.  *
  109.  * Return Value:
  110.  *  BOOL            TRUE to prevent further processing,
  111.  *                  FALSE otherwise.
  112.  */
  113.  
  114. BOOL CPatronDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  115.     , LPARAM lParam, LRESULT *pLRes)
  116.     {
  117.     UINT        dx, dy;
  118.     RECT        rc;
  119.  
  120.     *pLRes=0;
  121.  
  122.     //Eat to prevent flickering
  123.     if (WM_ERASEBKGND==iMsg)
  124.         return TRUE;
  125.  
  126.     if (WM_SIZE==iMsg && NULL!=m_pPG)
  127.         {
  128.         dx=LOWORD(lParam);
  129.         dy=HIWORD(lParam);
  130.  
  131.         if (SIZE_MINIMIZED!=wParam)
  132.             {
  133.             //Resize Pages window to fit the new document size.
  134.             GetClientRect(hWnd, &rc);
  135.             m_pPG->RectSet(&rc, FALSE);
  136.             }
  137.         }
  138.  
  139.     //CHAPTER13MOD
  140.     if (WM_DESTROY==iMsg)
  141.         {
  142.         /*
  143.          * We have to revoke the drop target here because the window
  144.          * will be destroyed and the property forcefully removed
  145.          * before we could do this in the destructor.
  146.          */
  147.         if (NULL!=m_pDropTarget)
  148.             {
  149.             RevokeDragDrop(m_hWnd);
  150.             CoLockObjectExternal(m_pDropTarget, FALSE, TRUE);
  151.             ReleaseInterface(m_pDropTarget);
  152.             }
  153.  
  154.         return FALSE;
  155.         }
  156.     //End CHAPTER13MOD
  157.  
  158.     /*
  159.      * We return FALSE even on WM_SIZE so we can let the default
  160.      * procedure handle maximized MDI child windows appropriately.
  161.      */
  162.     return FALSE;
  163.     }
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. /*
  172.  * CPatronDoc::Clear
  173.  *
  174.  * Purpose:
  175.  *  Sets all contents in the document back to defaults with no
  176.  *  filename.
  177.  *
  178.  * Paramters:
  179.  *  None
  180.  *
  181.  * Return Value:
  182.  *  None
  183.  */
  184.  
  185. void CPatronDoc::Clear(void)
  186.     {
  187.     //Completely reset the pages
  188.     if (NULL!=m_pPG)
  189.         m_pPG->StorageSet(NULL, FALSE, FALSE);
  190.  
  191.     CDocument::Clear();
  192.     m_lVer=VERSIONCURRENT;
  193.     return;
  194.     }
  195.  
  196.  
  197.  
  198.  
  199. /*
  200.  * CPatronDoc::FDirtyGet
  201.  *
  202.  * Purpose:
  203.  *  Returns the current dirty status of the document.
  204.  *
  205.  * Parameters:
  206.  *  None
  207.  *
  208.  * Return Value:
  209.  *  BOOL            TRUE if the file is clean, FALSE otherwise.
  210.  */
  211.  
  212. BOOL CPatronDoc::FDirtyGet()
  213.     {
  214.     BOOL    fPageDirty;
  215.  
  216.     fPageDirty=m_pPG->FIsDirty();
  217.     return m_fDirty | fPageDirty;
  218.     }
  219.  
  220.  
  221.  
  222.  
  223.  
  224. /*
  225.  * CPatronDoc::Delete
  226.  *
  227.  * Purpose:
  228.  *  Removed the current object from the document.
  229.  *
  230.  * Paramters:
  231.  *  None
  232.  *
  233.  * Return Value:
  234.  *  None
  235.  */
  236.  
  237. void CPatronDoc::Delete(void)
  238.     {
  239.     if (NULL!=m_pPG)
  240.         m_pPG->TenantDestroy();
  241.  
  242.     CoFreeUnusedLibraries();
  243.     return;
  244.     }
  245.  
  246.  
  247.  
  248.  
  249.  
  250. /*
  251.  * CPatronDoc::FQueryObjectSelected
  252.  *
  253.  * Purpose:
  254.  *  Returns whether or not there is an object selected in this
  255.  *  document for Cut, Copy, Delete functions.
  256.  *
  257.  * Parameters:
  258.  *  hMenu           HMENU of the Edit menu.
  259.  *
  260.  * Return Value:
  261.  *  BOOL            TRUE if we have an object, FALSE otherwise.
  262.  */
  263.  
  264. BOOL CPatronDoc::FQueryObjectSelected(HMENU hMenu)
  265.     {
  266.     return m_pPG->FQueryObjectSelected(hMenu);
  267.     }
  268.  
  269.  
  270.  
  271.  
  272.  
  273. /*
  274.  * CPatronDoc::Load
  275.  *
  276.  * Purpose:
  277.  *  Loads a given document without any user interface overwriting
  278.  *  the previous contents of the editor.
  279.  *
  280.  * Parameters:
  281.  *  fChangeFile     BOOL indicating if we're to update the window
  282.  *                  title and the filename from using this file.
  283.  *  pszFile         LPTSTR to the filename to load.  Could be NULL
  284.  *                  for an untitled document.
  285.  *
  286.  * Return Value:
  287.  *  UINT            An error value from DOCERR_*
  288.  */
  289.  
  290. UINT CPatronDoc::Load(BOOL fChangeFile, LPTSTR pszFile)
  291.     {
  292.     RECT        rc;
  293.     LPSTORAGE   pIStorage;
  294.     HRESULT     hr;
  295.     CLSID       clsID;
  296.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE
  297.                     | STGM_SHARE_EXCLUSIVE;
  298.  
  299.     if (NULL==pszFile)
  300.         {
  301.         //Create a new temp file.
  302.         hr=StgCreateDocfile(NULL, dwMode | STGM_CREATE
  303.             | STGM_DELETEONRELEASE, 0, &pIStorage);
  304.  
  305.         //Mark this our class since we check with ReadClassStg.
  306.         if (SUCCEEDED(hr))
  307.             WriteClassStg(pIStorage, CLSID_PatronPages);
  308.         }
  309.     else
  310.         {
  311.         hr=StgOpenStorage(pszFile, NULL, dwMode, NULL, 0, &pIStorage);
  312.         }
  313.  
  314.     if (FAILED(hr))
  315.         return DOCERR_COULDNOTOPEN;
  316.  
  317.     //Check if this is our type of file and exit if not.
  318.     hr=ReadClassStg(pIStorage, &clsID);
  319.  
  320.     if (FAILED(hr) || CLSID_PatronPages!=clsID)
  321.         {
  322.         pIStorage->Release();
  323.         return DOCERR_READFAILURE;
  324.         }
  325.  
  326.     //Attempt to create our contained Pages window.
  327.     m_pPG=new CPages(m_hInst, m_cf);
  328.     GetClientRect(m_hWnd, &rc);
  329.  
  330.     if (!m_pPG->Init(m_hWnd, &rc, WS_CHILD | WS_VISIBLE
  331.         , ID_PAGES, NULL))
  332.         {
  333.         pIStorage->Release();
  334.         return DOCERR_READFAILURE;
  335.         }
  336.  
  337.     if (!m_pPG->StorageSet(pIStorage, FALSE, (NULL==pszFile)))
  338.         {
  339.         pIStorage->Release();
  340.         return DOCERR_READFAILURE;
  341.         }
  342.  
  343.     //CHAPTER13MOD
  344.     //Open the window up for drag-drop
  345.     m_pDropTarget=new CDropTarget(this);
  346.  
  347.     if (NULL!=m_pDropTarget)
  348.         {
  349.         m_pDropTarget->AddRef();
  350.         CoLockObjectExternal(m_pDropTarget, TRUE, FALSE);
  351.         RegisterDragDrop(m_hWnd, m_pDropTarget);
  352.         }
  353.     //End CHAPTER13MOD
  354.  
  355.     m_pIStorage=pIStorage;
  356.     Rename(pszFile);
  357.  
  358.     //Do initial setup if new file, otherwise Pages handles things.
  359.     if (NULL==pszFile)
  360.         {
  361.         //Go initialize the Pages for the default printer.
  362.         if (!PrinterSetup(NULL, TRUE))
  363.             return DOCERR_COULDNOTOPEN;
  364.  
  365.         //Go create an initial page.
  366.         m_pPG->PageInsert(0);
  367.         }
  368.     else
  369.         {
  370.         //Can't change an already saved configuration
  371.         m_fPrintSetup=FALSE;
  372.         }
  373.  
  374.     FDirtySet(FALSE);
  375.     return DOCERR_NONE;
  376.     }
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384. /*
  385.  * CPatronDoc::Save
  386.  *
  387.  * Purpose:
  388.  *  Writes the file to a known filename, requiring that the user
  389.  *  has previously used FileOpen or FileSaveAs in order to have
  390.  *  a filename.
  391.  *
  392.  * Parameters:
  393.  *  uType           UINT indicating the type of file the user
  394.  *                  requested to save in the File Save As dialog.
  395.  *  pszFile         LPTSTR under which to save.  If NULL, use the
  396.  *                  current name.
  397.  *
  398.  * Return Value:
  399.  *  UINT            An error value from DOCERR_*
  400.  */
  401.  
  402. UINT CPatronDoc::Save(UINT uType, LPTSTR pszFile)
  403.     {
  404.     HRESULT     hr;
  405.     LPSTORAGE   pIStorage;
  406.  
  407.     //Save or Save As with the same file is just a commit.
  408.     if (NULL==pszFile
  409.         || (NULL!=pszFile && 0==lstrcmpi(pszFile, m_szFile)))
  410.         {
  411.         WriteFmtUserTypeStg(m_pIStorage, m_cf
  412.             , PSZ(IDS_CLIPBOARDFORMAT));
  413.  
  414.         //Insure pages are up to date.
  415.         m_pPG->StorageUpdate(FALSE);
  416.  
  417.         //Commit everyting
  418.         m_pIStorage->Commit(STGC_DEFAULT);
  419.  
  420.         FDirtySet(FALSE);
  421.         return DOCERR_NONE;
  422.         }
  423.  
  424.     /*
  425.      * When we're given a name, open the storage, creating it new
  426.      * if it does not exist or overwriting the old one.  Then CopyTo
  427.      * from the current to the new, Commit the new, Release the old.
  428.      */
  429.  
  430.     hr=StgCreateDocfile(pszFile, STGM_TRANSACTED | STGM_READWRITE
  431.         | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  432.  
  433.     if (FAILED(hr))
  434.         return DOCERR_COULDNOTOPEN;
  435.  
  436.     WriteClassStg(pIStorage, CLSID_PatronPages);
  437.     WriteFmtUserTypeStg(pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
  438.  
  439.     //Insure all pages are up-to-date.
  440.     m_pPG->StorageUpdate(TRUE);
  441.  
  442.     //This also copies the CLSID we stuff in here on file creation.
  443.     hr=m_pIStorage->CopyTo(NULL, NULL, NULL, pIStorage);
  444.  
  445.     if (FAILED(hr))
  446.         {
  447.         SCODE       sc;
  448.  
  449.         pIStorage->Release();
  450.         sc=GetScode(hr);
  451.  
  452.         /*
  453.          * If we failed because of low memory, use IRootStorage
  454.          * to switch into the new file.
  455.          */
  456.         if (E_OUTOFMEMORY==sc)
  457.             {
  458.             LPROOTSTORAGE        pIRoot;
  459.  
  460.             //Delete file we already created
  461.             DeleteFile(pszFile);
  462.  
  463.             if (FAILED(m_pIStorage->QueryInterface
  464.                 (IID_IRootStorage, (PPVOID)&pIRoot)))
  465.                 return DOCERR_WRITEFAILURE;
  466.  
  467.            #ifdef WIN32ANSI
  468.             OLECHAR     szTemp[MAX_PATH];
  469.  
  470.             MultiByteToWideChar(CP_ACP, 0, pszFile, -1, szTemp, MAX_PATH);
  471.             hr=pIRoot->SwitchToFile(szTemp);
  472.            #else
  473.             hr=pIRoot->SwitchToFile(pszFile);
  474.            #endif
  475.             pIRoot->Release();
  476.  
  477.             if (FAILED(hr))
  478.                 return DOCERR_WRITEFAILURE;
  479.  
  480.             //If successful, the Commit below finishes the save.
  481.             pIStorage=m_pIStorage;
  482.             m_pIStorage->AddRef();    //Matches Release below
  483.             }
  484.         }
  485.  
  486.     pIStorage->Commit(STGC_DEFAULT);
  487.  
  488.     /*
  489.      * Revert changes on the original storage.  If this was a temp
  490.      * file, it's deleted since we used STGM_DELETEONRELEASE.
  491.      */
  492.     m_pIStorage->Release();
  493.  
  494.     //Make this new storage current
  495.     m_pIStorage=pIStorage;
  496.     m_pPG->StorageSet(pIStorage, TRUE, FALSE);
  497.  
  498.     FDirtySet(FALSE);
  499.     Rename(pszFile);    //Update caption bar.
  500.  
  501.     return DOCERR_NONE;
  502.     }
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511. /*
  512.  * CPatronDoc::Clip
  513.  *
  514.  * Purpose:
  515.  *  Places a private format, a metafile, and a bitmap of the display
  516.  *  on the clipboard, optionally implementing Cut by deleting the
  517.  *  data in the current window after rendering.
  518.  *
  519.  * Parameters:
  520.  *  hWndFrame       HWND of the main window.
  521.  *  fCut            BOOL indicating cut (TRUE) or copy (FALSE).
  522.  *
  523.  * Return Value:
  524.  *  BOOL            TRUE if successful, FALSE otherwise.
  525.  */
  526.  
  527. BOOL CPatronDoc::Clip(HWND hWndFrame, BOOL fCut)
  528.     {
  529.     if (NULL==m_pPG)
  530.         return FALSE;
  531.  
  532.     return m_pPG->TenantClip(fCut);
  533.     }
  534.  
  535.  
  536.  
  537.  
  538.  
  539. /*
  540.  * CPatronDoc::Paste
  541.  *
  542.  * Purpose:
  543.  *  Retrieves the private data format from the clipboard and sets it
  544.  *  to the current figure in the editor window.
  545.  *
  546.  *  Note that if this function is called, then the clipboard format
  547.  *  is available because the Paste menu item is only enabled if the
  548.  *  format is present.
  549.  *
  550.  * Parameters:
  551.  *  hWndFrame       HWND of the main window.
  552.  *
  553.  * Return Value:
  554.  *  BOOL            TRUE if successful, FALSE otherwise.
  555.  */
  556.  
  557. BOOL CPatronDoc::Paste(HWND hWndFrame)
  558.     {
  559.     LPDATAOBJECT    pIDataObject;
  560.     BOOL            fRet=FALSE;
  561.     FORMATETC       fe;
  562.     TENANTTYPE      tType;
  563.  
  564.     if (NULL==m_pPG)
  565.         return FALSE;
  566.  
  567.     if (FAILED(OleGetClipboard(&pIDataObject)))
  568.         return FALSE;
  569.  
  570.     //Go get type and format we *can* paste, then actually paste it.
  571.     if (FQueryPasteFromData(pIDataObject, &fe, &tType))
  572.         fRet=PasteFromData(pIDataObject, &fe, tType, NULL, 0L);
  573.  
  574.     pIDataObject->Release();
  575.     return fRet;
  576.     }
  577.  
  578.  
  579.  
  580.  
  581. /*
  582.  * CPatronDoc::FQueryPaste
  583.  *
  584.  * Purpose:
  585.  *  Determines if we can paste data from the clipboard.
  586.  *
  587.  * Parameters:
  588.  *  None
  589.  *
  590.  * Return Value:
  591.  *  BOOL            TRUE if data is available, FALSE otherwise.
  592.  */
  593.  
  594. BOOL CPatronDoc::FQueryPaste(void)
  595.     {
  596.     LPDATAOBJECT    pIDataObject;
  597.     BOOL            fRet;
  598.  
  599.     if (FAILED(OleGetClipboard(&pIDataObject)))
  600.         return FALSE;
  601.  
  602.     fRet=FQueryPasteFromData(pIDataObject, NULL, NULL);
  603.     pIDataObject->Release();
  604.     return fRet;
  605.     }
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612. /*
  613.  * CPatronDoc::PasteSpecial
  614.  *
  615.  * Purpose:
  616.  *  Retrieves a specific data format from the clipboard and sends
  617.  *  it to the editor window appropriately.
  618.  *
  619.  *  Note that if this function is called, then the appropriate
  620.  *  format is available because the Paste menu item is only
  621.  *  enabled if the format is present.
  622.  *
  623.  * Parameters:
  624.  *  hWndFrame       HWND of the main window
  625.  *
  626.  * Return Value:
  627.  *  BOOL            TRUE if successful, FALSE otherwise.
  628.  */
  629.  
  630. BOOL CPatronDoc::PasteSpecial(HWND hWndFrame)
  631.     {
  632.     OLEUIPASTESPECIAL   ps;
  633.     OLEUIPASTEENTRY     rgPaste[4];
  634.     UINT                uTemp;
  635.     BOOL                fRet=FALSE;
  636.  
  637.     if (NULL==m_pPG)
  638.         return FALSE;
  639.  
  640.     memset(&ps, 0, sizeof(ps));
  641.  
  642.     if (FAILED(OleGetClipboard(&ps.lpSrcDataObj)))
  643.         return FALSE;
  644.  
  645.     ps.cbStruct=sizeof(ps);
  646.     ps.hWndOwner=hWndFrame;
  647.  
  648.     ps.dwFlags=PSF_SELECTPASTE;
  649.  
  650.     ps.arrPasteEntries=rgPaste;
  651.     ps.cPasteEntries=4;
  652.  
  653.     //Set up Paste Special descriptor arrays.
  654.     SETDefFormatEtc(rgPaste[0].fmtetc, m_cf, TYMED_HGLOBAL);
  655.     rgPaste[0].lpstrFormatName=PSZ(IDS_CLIPBOARDFORMAT);
  656.     rgPaste[0].lpstrResultText=PSZ(IDS_PASTEASPATRON);
  657.     rgPaste[0].dwFlags=OLEUIPASTE_PASTEONLY;
  658.  
  659.     SETDefFormatEtc(rgPaste[1].fmtetc,CF_METAFILEPICT,TYMED_MFPICT);
  660.     rgPaste[1].lpstrFormatName=PSZ(IDS_PASTEMETAFILE);
  661.     rgPaste[1].lpstrResultText=PSZ(IDS_PASTEASMETAFILE);
  662.     rgPaste[1].dwFlags=OLEUIPASTE_PASTEONLY;
  663.  
  664.     SETDefFormatEtc(rgPaste[2].fmtetc, CF_DIB, TYMED_HGLOBAL);
  665.     rgPaste[2].lpstrFormatName=PSZ(IDS_PASTEDIB);
  666.     rgPaste[2].lpstrResultText=PSZ(IDS_PASTEASDIB);
  667.     rgPaste[2].dwFlags=OLEUIPASTE_PASTEONLY;
  668.  
  669.     SETDefFormatEtc(rgPaste[3].fmtetc, CF_BITMAP, TYMED_GDI);
  670.     rgPaste[3].lpstrFormatName=PSZ(IDS_PASTEBITMAP);
  671.     rgPaste[3].lpstrResultText=PSZ(IDS_PASTEASBITMAP);
  672.     rgPaste[3].dwFlags=OLEUIPASTE_PASTEONLY;
  673.  
  674.     uTemp=OleUIPasteSpecial(&ps);
  675.  
  676.     if (OLEUI_OK==uTemp)
  677.         {
  678.         fRet=PasteFromData(ps.lpSrcDataObj
  679.             , &rgPaste[ps.nSelectedIndex].fmtetc
  680.             , TENANTTYPE_STATIC, NULL, 0L);
  681.         }
  682.  
  683.     ps.lpSrcDataObj->Release();
  684.     return fRet;
  685.     }
  686.  
  687.  
  688.  
  689.  
  690. /*
  691.  * CPatronDoc::FQueryPasteFromData
  692.  * (Protected)
  693.  *
  694.  * Purpose:
  695.  *  Determines if we can paste data from a data object.
  696.  *
  697.  * Parameters:
  698.  *  pIDataObject    LPDATAOBJECT from which we might want to paste.
  699.  *  pFE             LPFORMATETC in which to return the first format
  700.  *                  we can use.  Ignored if NULL.
  701.  *  ptType          PTENANTTYPE in which to store the type of
  702.  *                  object we can paste.  Ignored if NULL.
  703.  *
  704.  * Return Value:
  705.  *  BOOL            TRUE if data is available, FALSE otherwise.
  706.  */
  707.  
  708. BOOL CPatronDoc::FQueryPasteFromData(LPDATAOBJECT pIDataObject
  709.     , LPFORMATETC pFE, PTENANTTYPE ptType)
  710.     {
  711.     FORMATETC       fe;
  712.     HRESULT         hr;
  713.  
  714.     if (NULL!=(LPVOID)ptType)
  715.         *ptType=TENANTTYPE_STATIC;
  716.  
  717.     //Any of our specific data here?
  718.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  719.     hr=pIDataObject->QueryGetData(&fe);
  720.  
  721.     if (NOERROR!=hr)
  722.         {
  723.         //Try metafile, DIB, then bitmap, setting fe each time
  724.         SETDefFormatEtc(fe, CF_METAFILEPICT, TYMED_MFPICT);
  725.         hr=pIDataObject->QueryGetData(&fe);
  726.  
  727.         if (NOERROR!=hr)
  728.             {
  729.             SETDefFormatEtc(fe, CF_DIB, TYMED_HGLOBAL);
  730.             hr=pIDataObject->QueryGetData(&fe);
  731.  
  732.             if (NOERROR!=hr)
  733.                 {
  734.                 SETDefFormatEtc(fe, CF_BITMAP, TYMED_GDI);
  735.                 hr=pIDataObject->QueryGetData(&fe);
  736.                 }
  737.             }
  738.         }
  739.  
  740.     if (NOERROR==hr && NULL!=pFE)
  741.         *pFE=fe;
  742.  
  743.     return (NOERROR==hr);
  744.     }
  745.  
  746.  
  747.  
  748.  
  749.  
  750. /*
  751.  * CPatronDoc::PasteFromData
  752.  * (Protected)
  753.  *
  754.  * Purpose:
  755.  *  Retrieves the private data format from a data object and sets
  756.  *  it to the current figure in the editor window.
  757.  *
  758.  * Parameters:
  759.  *  pIDataObject    LPDATAOBJECT from which to paste.
  760.  *  pFE             LPFORMATETC to use in the paste. Cannot be NULL.
  761.  *  tType           TENANTTYPE to paste.
  762.  *  ppo             PPATRONOBJECT containing placement data.
  763.  *  dwData          DWORD extra data sensitive to tType
  764.  *
  765.  * Return Value:
  766.  *  BOOL            TRUE if successful, FALSE otherwise.
  767.  */
  768.  
  769. BOOL CPatronDoc::PasteFromData(LPDATAOBJECT pIDataObject
  770.     , LPFORMATETC pFE, TENANTTYPE tType, PPATRONOBJECT ppo
  771.     , DWORD dwData)
  772.     {
  773.     BOOL            fRet;
  774.     HRESULT         hr;
  775.     PATRONOBJECT    po;
  776.     STGMEDIUM       stm;
  777.  
  778.     if (NULL==pFE)
  779.         return FALSE;
  780.  
  781.     //If not given any placement data, see if we can retrieve it
  782.     if (pFE->cfFormat==m_cf && NULL==ppo)
  783.         {
  784.         hr=pIDataObject->GetData(pFE, &stm);
  785.  
  786.         if (SUCCEEDED(hr))
  787.             {
  788.             ppo=(PPATRONOBJECT)GlobalLock(stm.hGlobal);
  789.  
  790.             po=*ppo;
  791.             ppo=&po;
  792.  
  793.             GlobalUnlock(stm.hGlobal);
  794.             ReleaseStgMedium(&stm);
  795.             }
  796.         }
  797.  
  798.     fRet=m_pPG->TenantCreate(tType, pIDataObject, pFE, ppo, dwData);
  799.  
  800.     if (fRet)
  801.         {
  802.         //Disable Printer Setup once we've created a tenant.
  803.         m_fPrintSetup=FALSE;
  804.         FDirtySet(TRUE);
  805.         }
  806.  
  807.     return fRet;
  808.     }
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815. /*
  816.  * CPatronDoc::NewPage
  817.  *
  818.  * Purpose:
  819.  *  Creates a new page in the document's pages control after the
  820.  *  current page.
  821.  *
  822.  * Parameters:
  823.  *  None
  824.  *
  825.  * Return Value:
  826.  *  UINT            Index of the new page.
  827.  */
  828.  
  829. UINT CPatronDoc::NewPage(void)
  830.     {
  831.     FDirtySet(TRUE);
  832.     return m_pPG->PageInsert(0);
  833.     }
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841. /*
  842.  * CPatronDoc::DeletePage
  843.  *
  844.  * Purpose:
  845.  *  Deletes the current page from the document.
  846.  *
  847.  * Parameters:
  848.  *  None
  849.  *
  850.  * Return Value:
  851.  *  UINT            Index of the now current page.
  852.  */
  853.  
  854. UINT CPatronDoc::DeletePage(void)
  855.     {
  856.     FDirtySet(TRUE);
  857.     return m_pPG->PageDelete(0);
  858.     }
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.  
  866. /*
  867.  * CPatronDoc::NextPage
  868.  *
  869.  * Purpose:
  870.  *  Shows the next page in the pages window.
  871.  *
  872.  * Parameters:
  873.  *  None
  874.  *
  875.  * Return Value:
  876.  *  UINT            Index of the new page.
  877.  */
  878.  
  879. UINT CPatronDoc::NextPage(void)
  880.     {
  881.     UINT        iPage;
  882.  
  883.     iPage=m_pPG->CurPageGet();
  884.     return m_pPG->CurPageSet(++iPage);
  885.     }
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893. /*
  894.  * CPatronDoc::PreviousPage
  895.  *
  896.  * Purpose:
  897.  *  Shows the previous page in the pages window.
  898.  *
  899.  * Parameters:
  900.  *  None
  901.  *
  902.  * Return Value:
  903.  *  UINT            Index of the new page.
  904.  */
  905.  
  906. UINT CPatronDoc::PreviousPage(void)
  907.     {
  908.     UINT        iPage;
  909.  
  910.     //If iPage is zero, then we wrap around to the end.
  911.     iPage=m_pPG->CurPageGet();
  912.     return m_pPG->CurPageSet(--iPage);
  913.     }
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920. /*
  921.  * CPatronDoc::FirstPage
  922.  *
  923.  * Purpose:
  924.  *  Shows the first page page in the pages window.
  925.  *
  926.  * Parameters:
  927.  *  None
  928.  *
  929.  * Return Value:
  930.  *  UINT            Index of the new page.
  931.  */
  932.  
  933. UINT CPatronDoc::FirstPage(void)
  934.     {
  935.     return m_pPG->CurPageSet(0);
  936.     }
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943. /*
  944.  * CPatronDoc::LastPage
  945.  *
  946.  * Purpose:
  947.  *  Shows the last page in the pages window.
  948.  *
  949.  * Parameters:
  950.  *  None
  951.  *
  952.  * Return Value:
  953.  *  UINT            Index of the last page.
  954.  */
  955.  
  956. UINT CPatronDoc::LastPage(void)
  957.     {
  958.     return m_pPG->CurPageSet(NOVALUE);
  959.     }
  960.