home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / OLEDOCOB.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-06  |  24.4 KB  |  916 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef _DEBUG
  14. #undef THIS_FILE
  15. static char BASED_CODE THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. #define new DEBUG_NEW
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CDocObjectServer
  22.  
  23. IMPLEMENT_DYNAMIC(CDocObjectServer, CCmdTarget)
  24.  
  25. BEGIN_MESSAGE_MAP(CDocObjectServer, CCmdTarget)
  26.     //{{AFX_MSG_MAP(CDocObjectServer)
  27.         // NOTE - the ClassWizard will add and remove mapping macros here.
  28.     //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30.  
  31. BEGIN_INTERFACE_MAP(CDocObjectServer, CCmdTarget)
  32.     INTERFACE_PART(CDocObjectServer, IID_IOleObject, OleObject)
  33.     INTERFACE_PART(CDocObjectServer, IID_IOleDocument, OleDocument)
  34.     INTERFACE_PART(CDocObjectServer, IID_IOleDocumentView, OleDocumentView)
  35.     INTERFACE_PART(CDocObjectServer, IID_IOleCommandTarget, OleCommandTarget)
  36.     INTERFACE_PART(CDocObjectServer, IID_IPrint, Print)
  37. END_INTERFACE_MAP()
  38.  
  39.  
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CDocObjectServer implementation
  42.  
  43. CDocObjectServer::CDocObjectServer(COleServerDoc* pDoc,
  44.     LPOLEDOCUMENTSITE pDocSite /* = NULL */)
  45. {
  46.     // Initialize DocObject data
  47.     m_pDocSite  = pDocSite;
  48.     m_pViewSite = NULL;
  49.  
  50.     m_pOwner = pDoc;
  51.     ASSERT(m_pOwner != NULL);
  52.  
  53.     m_nFirstPage = 1;
  54.  
  55.     // All Binder-Compatible documents use Compound Files as their
  56.     // storage mechanism
  57.     m_pOwner->EnableCompoundFile(TRUE);
  58.  
  59.     m_nFirstPage = -1;
  60. }
  61.  
  62. CDocObjectServer::~CDocObjectServer()
  63. {
  64.     ReleaseDocSite();
  65. }
  66.  
  67. void CDocObjectServer::ReleaseDocSite()
  68. {
  69.     if (m_pDocSite != NULL)
  70.     {
  71.         m_pDocSite->Release();
  72.         m_pDocSite = NULL;
  73.     }
  74. }
  75.  
  76. void CDocObjectServer::SetDocSite(LPOLEDOCUMENTSITE pNewSite)
  77. {
  78.     ReleaseDocSite();
  79.     m_pDocSite = pNewSite;
  80. }
  81.  
  82. void CDocObjectServer::OnCloseDocument()
  83. {
  84.     // Clean up pointer to document site, if any
  85.     ReleaseDocSite();
  86.     m_pOwner->OnCloseDocument();
  87. }
  88.  
  89. void CDocObjectServer::ActivateDocObject()
  90. {
  91.     ASSERT(m_pOwner != NULL);
  92.     if (m_pOwner->IsDocObject())
  93.     {
  94.         ASSERT(m_pDocSite != NULL);
  95.         m_pDocSite->ActivateMe(NULL);
  96.     }
  97. }
  98.  
  99. STDMETHODIMP CDocObjectServer::OnExecOleCmd(
  100.    const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  101.    VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
  102. {
  103.     ASSERT(m_pOwner != NULL);
  104.     if (m_pOwner == NULL)
  105.         return E_NOTIMPL;
  106.     else
  107.         return m_pOwner->OnExecOleCmd(pguidCmdGroup, nCmdID,
  108.             nCmdExecOpt, pvarargIn, pvarargOut);
  109. }
  110.  
  111. COleDocIPFrameWnd* CDocObjectServer::GetControllingFrame() const
  112. {
  113.     COleDocIPFrameWnd* pFrame = NULL;
  114.     POSITION pos = m_pOwner->GetFirstViewPosition();
  115.     if (pos != NULL)
  116.     {
  117.         CView* pView = m_pOwner->GetNextView(pos);
  118.         if (pView != NULL)
  119.         {
  120.             CWnd* pParent = pView->GetParent();
  121.             pFrame = DYNAMIC_DOWNCAST(COleDocIPFrameWnd, pParent);
  122.         }
  123.     }
  124.  
  125. #ifdef _DEBUG
  126.     // This TRACE will trip if you've not converted your application to
  127.     // use a COleDocIPFrameWnd, or if you've incorrectly hooked up
  128.     // DocObject support in your application.
  129.  
  130.     if (pFrame == NULL)
  131.         TRACE0("Error: An appropriate DocObject frame could not be found.\n");
  132. #endif
  133.  
  134.     return pFrame;
  135. }
  136.  
  137. BOOL CDocObjectServer::DoPreparePrinting(CView* pView, CPrintInfo* printInfo)
  138. {
  139.     return pView->OnPreparePrinting(printInfo);
  140. }
  141.  
  142. void CDocObjectServer::DoPrepareDC(CView* pView, CDC* pdcPrint,
  143.     CPrintInfo* pprintInfo)
  144. {
  145.     pView->OnPrepareDC(pdcPrint, pprintInfo);
  146. }
  147.  
  148. void CDocObjectServer::DoPrint(CView* pView, CDC* pdcPrint,
  149.     CPrintInfo* pprintInfo)
  150. {
  151.     pView->OnPrint(pdcPrint, pprintInfo);
  152. }
  153.  
  154. void CDocObjectServer::DoBeginPrinting(CView* pView,
  155.     CDC* pDC, CPrintInfo* pprintInfo)
  156. {
  157.     pView->OnBeginPrinting(pDC, pprintInfo);
  158. }
  159.  
  160. void CDocObjectServer::DoEndPrinting(CView* pView,
  161.     CDC* pDC, CPrintInfo* pprintInfo)
  162. {
  163.     pView->OnEndPrinting(pDC, pprintInfo);
  164. }
  165.  
  166.  
  167. /////////////////////////////////////////////////////////////////////////////
  168. // IPrint interface
  169.  
  170. extern BOOL CALLBACK _AfxAbortProc(HDC, int);   // from VIEWPRNT.CPP
  171.  
  172. STDMETHODIMP_(ULONG) CDocObjectServer::XPrint::AddRef()
  173. {
  174.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  175.     return pThis->m_pOwner->ExternalAddRef();
  176. }
  177.  
  178. STDMETHODIMP_(ULONG) CDocObjectServer::XPrint::Release()
  179. {
  180.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  181.     return pThis->m_pOwner->ExternalRelease();
  182. }
  183.  
  184. STDMETHODIMP CDocObjectServer::XPrint::QueryInterface(
  185.     REFIID iid, LPVOID* ppvObj)
  186. {
  187.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  188.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  189. }
  190.  
  191. STDMETHODIMP CDocObjectServer::XPrint::SetInitialPageNum(
  192.    LONG nFirstPage)
  193. {
  194.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  195.     ASSERT_VALID(pThis);
  196.     pThis->m_nFirstPage = nFirstPage;
  197.  
  198.     return S_OK;
  199. }
  200.  
  201. STDMETHODIMP CDocObjectServer::XPrint::GetPageInfo(
  202.    LPLONG pnFirstPage, LPLONG pcPages)
  203. {
  204.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  205.     ASSERT_VALID(pThis);
  206.  
  207.     CPrintInfo printInfo;
  208.     ASSERT(printInfo.m_pPD != NULL);    // must be set
  209.     printInfo.m_bDocObject = TRUE;
  210.  
  211.     printInfo.m_pPD->m_pd.hDC = NULL;
  212.     if (printInfo.m_pPD->m_pd.hDC == NULL)
  213.         return E_UNEXPECTED;
  214.  
  215.     if (pThis->m_nFirstPage == -1)
  216.         *pnFirstPage = printInfo.GetMinPage();
  217.     else
  218.         *pnFirstPage = pThis->m_nFirstPage;
  219.  
  220.     if (printInfo.GetToPage() == 0xFFFF)
  221.         *pcPages = 0xFFFF;
  222.     else
  223.         *pcPages = printInfo.GetToPage() - printInfo.GetFromPage() +1;
  224.  
  225.     return S_OK;
  226. }
  227.  
  228. STDMETHODIMP CDocObjectServer::XPrint::Print(
  229.    DWORD grfFlags, DVTARGETDEVICE** ppTD, PAGESET** ppPageSet,
  230.    LPSTGMEDIUM pstgmOptions, LPCONTINUECALLBACK pCallback, LONG nFirstPage,
  231.    LPLONG pcPagesPrinted, LPLONG pnLastPage)
  232. {
  233.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  234.     ASSERT_VALID(pThis);
  235.     UNUSED_ALWAYS(pstgmOptions);
  236.     UNUSED_ALWAYS(pnLastPage);
  237.  
  238.     // try to get out of this without doing any work
  239.  
  240.     if (pcPagesPrinted == NULL || ppTD == NULL || ppPageSet == NULL)
  241.         return E_POINTER;
  242.  
  243.     if (*ppTD == NULL)
  244.         return E_INVALIDARG;
  245.  
  246.     // get initialized
  247.  
  248.     DVTARGETDEVICE* ptd = *ppTD;
  249.     pThis->m_nFirstPage = nFirstPage;
  250.     *pcPagesPrinted = 0;
  251.  
  252.     // find the view we need to print
  253.  
  254.     CView* pView = NULL;
  255.     POSITION pos = pThis->m_pOwner->GetFirstViewPosition();
  256.     if (pos != NULL)
  257.         pView = pThis->m_pOwner->GetNextView(pos);
  258.  
  259.     if (pView == NULL)
  260.         return E_UNEXPECTED;
  261.  
  262.     // get default print info
  263.     CPrintInfo printInfo;
  264.     ASSERT(printInfo.m_pPD != NULL);    // must be set
  265.     printInfo.m_bDocObject = TRUE;
  266.     printInfo.m_dwFlags = grfFlags;
  267.     printInfo.m_nOffsetPage = nFirstPage;
  268.  
  269.     printInfo.m_pPD->m_pd.hDC = _AfxOleCreateDC(*ppTD);
  270.     if (printInfo.m_pPD->m_pd.hDC == NULL)
  271.     {
  272.         if (grfFlags & PRINTFLAG_MAYBOTHERUSER)
  273.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  274.         return E_UNEXPECTED;
  275.     }
  276.  
  277.     if (pThis->DoPreparePrinting(pView, &printInfo))
  278.     {
  279.         // hDC must be set (did you remember to call DoPreparePrinting?)
  280.         ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
  281.  
  282.         // set file to print to if print-to-file selected
  283.         CString strOutput;
  284.         if (grfFlags & PRINTFLAG_PRINTTOFILE)
  285.             strOutput = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  286.  
  287.         // if we were to prompt, we'll need to copy info from the
  288.         // user back to the client
  289.  
  290.         if (grfFlags & PRINTFLAG_PROMPTUSER)
  291.         {
  292.             if (grfFlags & PRINTFLAG_USERMAYCHANGEPRINTER)
  293.             {
  294.                 LPDEVNAMES lpDevNames =
  295.                     (LPDEVNAMES) GlobalLock(printInfo.m_pPD->m_pd.hDevNames);
  296.                 LPDEVMODE lpDevMode =
  297.                     (LPDEVMODE) GlobalLock(printInfo.m_pPD->m_pd.hDevMode);
  298.  
  299.                 if (lpDevNames == NULL || lpDevMode == NULL)
  300.                     *ppTD = NULL;
  301.                 else
  302.                     *ppTD = _AfxOleCreateTargetDevice(lpDevNames, lpDevMode);
  303.  
  304.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevNames);
  305.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevMode);
  306.             }
  307.  
  308.             // MFC page ranges (for now) only have one PAGERANGE
  309.  
  310.             LPMALLOC pMalloc = NULL;
  311.  
  312.             // if the caller didn't supply a buffer, allocate one
  313.             // else, make sure the buffer is big enough
  314.  
  315.             if (*ppPageSet == NULL)
  316.             {
  317.                 HRESULT hrCopying = CoGetMalloc(1, &pMalloc);
  318.                 if (FAILED(hrCopying))
  319.                     return hrCopying;
  320.  
  321.                 *ppPageSet =
  322.                     (PAGESET*) pMalloc->Alloc(sizeof(PAGESET) + sizeof(PAGERANGE));
  323.             }
  324.             else
  325.             {
  326.                 if ((*ppPageSet)->cPageRange < 1 ||
  327.                     (*ppPageSet)->cbStruct != sizeof(PAGESET))
  328.                 {
  329.                     return E_INVALIDARG;
  330.                 }
  331.             }
  332.  
  333.             if (*ppPageSet != NULL)
  334.             {
  335.                 (*ppPageSet)->cbStruct = sizeof(PAGESET);
  336.                 (*ppPageSet)->fOddPages = TRUE;
  337.                 (*ppPageSet)->fEvenPages = TRUE;
  338.                 (*ppPageSet)->cPageRange = 1;
  339.  
  340.                 (*ppPageSet)->rgPages[0].nFromPage = printInfo.GetFromPage();
  341.                 (*ppPageSet)->rgPages[0].nToPage = printInfo.GetToPage();
  342.             }
  343.  
  344.             RELEASE(pMalloc);
  345.  
  346.             if (*ppTD == NULL || *ppPageSet == NULL)
  347.                 return E_UNEXPECTED;
  348.         }
  349.  
  350.         // if the client didn't really want to print,
  351.         // we've collected all the information we need
  352.         if (grfFlags & PRINTFLAG_DONTACTUALLYPRINT)
  353.             return S_OK;
  354.  
  355.         // set up document info and start the document printing process
  356.         CString strTitle;
  357.         CDocument* pDoc = pThis->m_pOwner;
  358.         if (pDoc != NULL)
  359.             strTitle = pDoc->GetTitle();
  360.         else
  361.             pView->GetParentFrame()->GetWindowText(strTitle);
  362.  
  363.         if (strTitle.GetLength() > 31)
  364.             strTitle.ReleaseBuffer(31);
  365.  
  366.         DOCINFO docInfo;
  367.         memset(&docInfo, 0, sizeof(DOCINFO));
  368.         docInfo.cbSize = sizeof(DOCINFO);
  369.         docInfo.lpszDocName = strTitle;
  370.         CString strPortName;
  371.         int nFormatID;
  372.         if (strOutput.IsEmpty())
  373.         {
  374.             docInfo.lpszOutput = NULL;
  375.             strPortName = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  376.             nFormatID = AFX_IDS_PRINTONPORT;
  377.         }
  378.         else
  379.         {
  380.             docInfo.lpszOutput = strOutput;
  381.             AfxGetFileTitle(strOutput,
  382.                 strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
  383.             nFormatID = AFX_IDS_PRINTTOFILE;
  384.         }
  385.  
  386.         // setup the printing DC
  387.         CDC dcPrint;
  388.         dcPrint.Attach(printInfo.m_pPD->m_pd.hDC);  // attach printer dc
  389.         dcPrint.m_bPrinting = TRUE;
  390.         pThis->DoBeginPrinting(pView, &dcPrint, &printInfo);
  391.         dcPrint.SetAbortProc(_AfxAbortProc);
  392.  
  393.         // disable main window while printing & init printing status dialog
  394.         AfxGetMainWnd()->EnableWindow(FALSE);
  395.  
  396.         CString strTemp;
  397.  
  398.         // start document printing process
  399.         if (dcPrint.StartDoc(&docInfo) == SP_ERROR)
  400.         {
  401.             // enable main window before proceeding
  402.             AfxGetMainWnd()->EnableWindow(TRUE);
  403.  
  404.             // cleanup and show error message
  405.             pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  406.             dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  407.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  408.             return E_UNEXPECTED;
  409.         }
  410.  
  411.         // Guarantee values are in the valid range
  412.         UINT nEndPage = printInfo.GetToPage();
  413.         UINT nStartPage = printInfo.GetFromPage();
  414.  
  415.         if (nEndPage < printInfo.GetMinPage())
  416.             nEndPage = printInfo.GetMinPage();
  417.         if (nEndPage > printInfo.GetMaxPage())
  418.             nEndPage = printInfo.GetMaxPage();
  419.  
  420.         if (nStartPage < printInfo.GetMinPage())
  421.             nStartPage = printInfo.GetMinPage();
  422.         if (nStartPage > printInfo.GetMaxPage())
  423.             nStartPage = printInfo.GetMaxPage();
  424.  
  425.         int nStep = (nEndPage >= nStartPage) ? 1 : -1;
  426.         nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep;
  427.  
  428.         VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));
  429.  
  430.         // begin page printing loop
  431.         BOOL bError = FALSE;
  432.         HRESULT hrContinue = S_OK;
  433.  
  434.         for (printInfo.m_nCurPage = nStartPage;
  435.             printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep)
  436.         {
  437.             if (printInfo.m_nCurPage % 2 == 1 && !(*ppPageSet)->fOddPages)
  438.                 continue;
  439.             if (printInfo.m_nCurPage % 2 == 0 && !(*ppPageSet)->fEvenPages)
  440.                 continue;
  441.  
  442.             pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  443.  
  444.             // check for end of print
  445.             if (!printInfo.m_bContinuePrinting)
  446.                 break;
  447.  
  448.             // set up drawing rect to entire page (in logical coordinates)
  449.             printInfo.m_rectDraw.SetRect(0, 0,
  450.                 dcPrint.GetDeviceCaps(HORZRES),
  451.                 dcPrint.GetDeviceCaps(VERTRES));
  452.             dcPrint.DPtoLP(&printInfo.m_rectDraw);
  453.  
  454.             // attempt to start the current page
  455.             if (dcPrint.StartPage() < 0)
  456.             {
  457.                 bError = TRUE;
  458.                 break;
  459.             }
  460.  
  461.             // must call OnPrepareDC on newer versions of Windows because
  462.             // StartPage now resets the device attributes.
  463.             if (afxData.bMarked4)
  464.                 pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  465.  
  466.             ASSERT(printInfo.m_bContinuePrinting);
  467.  
  468.             hrContinue = pCallback->FContinuePrinting(printInfo.m_nCurPage,
  469.                 printInfo.m_nCurPage + printInfo.m_nOffsetPage, NULL);
  470.  
  471.             // page successfully started, so now render the page
  472.             pThis->DoPrint(pView, &dcPrint, &printInfo);
  473.             if (dcPrint.EndPage() < 0 ||
  474.                 !_AfxAbortProc(dcPrint.m_hDC, 0) ||
  475.                 hrContinue != S_OK)
  476.             {
  477.                 bError = TRUE;
  478.                 break;
  479.             }
  480.  
  481.             // increment count
  482.             (*pcPagesPrinted)++;
  483.         }
  484.  
  485.         // cleanup document printing process
  486.         if (!bError)
  487.             dcPrint.EndDoc();
  488.         else
  489.             dcPrint.AbortDoc();
  490.  
  491.         AfxGetMainWnd()->EnableWindow();    // enable main window
  492.  
  493.         // clean up after printing
  494.         pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  495.         dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  496.  
  497. #ifdef _MAC
  498.         // It's common for the user to click on the printing status dialog
  499.         // and not have the click be registered because the abort proc
  500.         // wasn't called often enough. For this reason we call _FlushEvents
  501.         // after printing is done so that those events don't get sent
  502.         // through to the document window and cause unintended changes to
  503.         // the document.
  504.  
  505.         FlushEvents(everyEvent, 0);
  506. #endif
  507.  
  508.         if (bError == TRUE)
  509.         {
  510.             if (hrContinue != S_OK)
  511.                 return PRINT_E_CANCELLED;
  512.             else
  513.                 return E_UNEXPECTED;
  514.         }
  515.     }
  516.  
  517.     return S_OK;
  518. }
  519.  
  520. /////////////////////////////////////////////////////////////////////////////
  521. // IOleDocument interface
  522.  
  523. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::AddRef()
  524. {
  525.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  526.     return pThis->m_pOwner->ExternalAddRef();
  527. }
  528.  
  529. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::Release()
  530. {
  531.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  532.     return pThis->m_pOwner->ExternalRelease();
  533. }
  534.  
  535. STDMETHODIMP CDocObjectServer::XOleDocument::QueryInterface(
  536.     REFIID iid, LPVOID* ppvObj)
  537. {
  538.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  539.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  540. }
  541.  
  542. STDMETHODIMP CDocObjectServer::XOleDocument::CreateView(
  543.    LPOLEINPLACESITE pipsite, LPSTREAM pstm,
  544.    DWORD dwReserved, LPOLEDOCUMENTVIEW* ppview)
  545. {
  546.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  547.    ASSERT_VALID(pThis);
  548.  
  549.    *ppview = NULL;
  550.  
  551.    HRESULT hr = E_FAIL;
  552.  
  553.    if (dwReserved == 0 && pThis->m_pDocSite != NULL)
  554.    {
  555.       // We only support a single view...so if view site is already
  556.       // set, fail.
  557.       if (pThis->m_pViewSite == NULL)
  558.       {
  559.          LPOLEDOCUMENTVIEW pView =
  560.             (LPOLEDOCUMENTVIEW)pThis->GetInterface(&IID_IOleDocumentView);
  561.          ASSERT(pView != NULL);
  562.  
  563.          // Set the site for the view
  564.          hr = pView->SetInPlaceSite(pipsite);
  565.          if (hr == NOERROR)
  566.          {
  567.             // Return the IOleDocumentView pointer
  568.             pView->AddRef();
  569.             *ppview = pView;
  570.          }
  571.  
  572.          // If a saved view state is provided, restore the view state
  573.          if (pstm)
  574.             hr = pView->ApplyViewState(pstm);
  575.       }
  576.       else
  577.          TRACE0("CDocObjectServer::XOleDocument::CreateView view already exists!\n");
  578.    }
  579.  
  580.    return hr;
  581. }
  582.  
  583. STDMETHODIMP CDocObjectServer::XOleDocument::GetDocMiscStatus(
  584.    LPDWORD pdwStatus)
  585. {
  586.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  587.    ASSERT_VALID(pThis);
  588.    ASSERT(pdwStatus != NULL);
  589.  
  590.    // Our implementation of DocObjects can't create multiple views,
  591.    // does not support complex rectangles, supports open editing,
  592.    // and supports read/write to a file. Thus DOCMISC == 0.
  593.    *pdwStatus = 0;
  594.  
  595.    return NOERROR;
  596. }
  597.  
  598. STDMETHODIMP CDocObjectServer::XOleDocument::EnumViews(
  599.    LPENUMOLEDOCUMENTVIEWS* ppEnumView, LPOLEDOCUMENTVIEW* ppView)
  600. {
  601.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  602.    ASSERT_VALID(pThis);
  603.    ASSERT(ppEnumView != NULL);
  604.    ASSERT(ppView != NULL);
  605.  
  606.    // We only support a single view
  607.    *ppEnumView = NULL;
  608.    HRESULT hr = QueryInterface(IID_IOleDocumentView, (LPVOID*)ppView);
  609.    return hr;
  610. }
  611.  
  612. /////////////////////////////////////////////////////////////////////////////
  613. // IOleObject interface
  614.  
  615. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::AddRef()
  616. {
  617.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  618.     return pThis->m_pOwner->ExternalAddRef();
  619. }
  620.  
  621. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::Release()
  622. {
  623.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  624.     return pThis->m_pOwner->ExternalRelease();
  625. }
  626.  
  627. STDMETHODIMP CDocObjectServer::XOleObject::QueryInterface(
  628.     REFIID iid, LPVOID* ppvObj)
  629. {
  630.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  631.     return pThis->m_pOwner->ExternalQueryInterface(&iid, ppvObj);
  632. }
  633.  
  634. STDMETHODIMP CDocObjectServer::XOleObject::SetClientSite(
  635.     LPOLECLIENTSITE pClientSite)
  636. {
  637.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  638.     ASSERT_VALID(pThis);
  639.     HRESULT hr = NOERROR;
  640.  
  641.     // Perform normal SetClientSite processing.
  642.     hr = pThis->m_pOwner->m_xOleObject.SetClientSite(pClientSite);
  643.     if (hr != S_OK)
  644.         return hr;
  645.  
  646.     // If we currently have a document site pointer,
  647.     // release it.
  648.  
  649.     pThis->ReleaseDocSite();
  650.  
  651.     // Check to see whether this object should act
  652.     // as a document object by querying for
  653.     // IOleDocumentSite.
  654.     if (pClientSite != NULL)
  655.         hr = pClientSite->QueryInterface(IID_IOleDocumentSite,
  656.             (LPVOID*)&pThis->m_pDocSite);
  657.     return hr;
  658. }
  659.  
  660. STDMETHODIMP CDocObjectServer::XOleObject::GetClientSite(
  661.     LPOLECLIENTSITE* ppClientSite)
  662. {
  663.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  664.     ASSERT_VALID(pThis);
  665.     return pThis->m_pOwner->m_xOleObject.GetClientSite(ppClientSite);
  666. }
  667.  
  668. STDMETHODIMP CDocObjectServer::XOleObject::SetHostNames(
  669.     LPCOLESTR lpszContainerApp, LPCOLESTR lpszContainerObj)
  670. {
  671.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  672.     ASSERT_VALID(pThis);
  673.     return pThis->m_pOwner->m_xOleObject.SetHostNames(lpszContainerApp,
  674.                                            lpszContainerObj);
  675. }
  676.  
  677. STDMETHODIMP CDocObjectServer::XOleObject::Close(DWORD dwSaveOption)
  678. {
  679.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  680.     ASSERT_VALID(pThis);
  681.     return pThis->m_pOwner->m_xOleObject.Close(dwSaveOption);
  682. }
  683.  
  684. STDMETHODIMP CDocObjectServer::XOleObject::SetMoniker(
  685.     DWORD dwWhichMoniker, LPMONIKER pmk)
  686. {
  687.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  688.     ASSERT_VALID(pThis);
  689.     return pThis->m_pOwner->m_xOleObject.SetMoniker(dwWhichMoniker, pmk);
  690. }
  691.  
  692. STDMETHODIMP CDocObjectServer::XOleObject::GetMoniker(
  693.     DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
  694. {
  695.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  696.     ASSERT_VALID(pThis);
  697.     return pThis->m_pOwner->m_xOleObject.GetMoniker(dwAssign, dwWhichMoniker,
  698.                                          ppMoniker);
  699. }
  700.  
  701. STDMETHODIMP CDocObjectServer::XOleObject::InitFromData(
  702.     LPDATAOBJECT pDataObject, BOOL bCreation, DWORD dwReserved)
  703. {
  704.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  705.     ASSERT_VALID(pThis);
  706.     return pThis->m_pOwner->m_xOleObject.InitFromData(pDataObject, bCreation,
  707.                                            dwReserved);
  708. }
  709.  
  710. STDMETHODIMP CDocObjectServer::XOleObject::GetClipboardData(
  711.     DWORD dwReserved, LPDATAOBJECT* ppDataObject)
  712. {
  713.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  714.     ASSERT_VALID(pThis);
  715.     return pThis->m_pOwner->m_xOleObject.GetClipboardData(dwReserved,
  716.                                                ppDataObject);
  717.  
  718. }
  719.  
  720. STDMETHODIMP CDocObjectServer::XOleObject::DoVerb(
  721.     LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex,
  722.     HWND hwndParent, LPCRECT lpPosRect)
  723. {
  724.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  725.     ASSERT_VALID(pThis);
  726.     return pThis->m_pOwner->m_xOleObject.DoVerb(iVerb, lpmsg,
  727.         pActiveSite, lindex, hwndParent, lpPosRect);
  728. }
  729.  
  730. STDMETHODIMP CDocObjectServer::XOleObject::EnumVerbs(
  731.     IEnumOLEVERB** ppenumOleVerb)
  732. {
  733.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  734.     ASSERT_VALID(pThis);
  735.     return pThis->m_pOwner->m_xOleObject.EnumVerbs(ppenumOleVerb);
  736. }
  737.  
  738. STDMETHODIMP CDocObjectServer::XOleObject::Update()
  739. {
  740.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  741.     ASSERT_VALID(pThis);
  742.     return pThis->m_pOwner->m_xOleObject.Update();
  743. }
  744.  
  745. STDMETHODIMP CDocObjectServer::XOleObject::IsUpToDate()
  746. {
  747.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  748.     ASSERT_VALID(pThis);
  749.     return pThis->m_pOwner->m_xOleObject.IsUpToDate();
  750. }
  751.  
  752. STDMETHODIMP CDocObjectServer::XOleObject::GetUserClassID(CLSID* lpClassID)
  753. {
  754.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  755.     ASSERT_VALID(pThis);
  756.     return pThis->m_pOwner->m_xOleObject.GetUserClassID(lpClassID);
  757. }
  758.  
  759. STDMETHODIMP CDocObjectServer::XOleObject::GetUserType(
  760.     DWORD dwFormOfType, LPOLESTR* ppszUserType)
  761. {
  762.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  763.     ASSERT_VALID(pThis);
  764.     return pThis->m_pOwner->m_xOleObject.GetUserType(dwFormOfType, ppszUserType);
  765. }
  766.  
  767. STDMETHODIMP CDocObjectServer::XOleObject::SetExtent(
  768.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  769. {
  770.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  771.     ASSERT_VALID(pThis);
  772.  
  773.     // DocObjects ignore SetExtent calls, so returne E_FAIL
  774.     if (pThis->m_pOwner->IsDocObject())
  775.         return E_FAIL;
  776.  
  777.     // Otherwise, just do the normal processing
  778.     return pThis->m_pOwner->m_xOleObject.SetExtent(dwDrawAspect, lpsizel);
  779. }
  780.  
  781. STDMETHODIMP CDocObjectServer::XOleObject::GetExtent(
  782.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  783. {
  784.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  785.     ASSERT_VALID(pThis);
  786.     return pThis->m_pOwner->m_xOleObject.GetExtent(dwDrawAspect, lpsizel);
  787. }
  788.  
  789. STDMETHODIMP CDocObjectServer::XOleObject::Advise(
  790.     LPADVISESINK pAdvSink, DWORD* pdwConnection)
  791. {
  792.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  793.     ASSERT_VALID(pThis);
  794.     return pThis->m_pOwner->m_xOleObject.Advise(pAdvSink, pdwConnection);
  795. }
  796.  
  797. STDMETHODIMP CDocObjectServer::XOleObject::Unadvise(DWORD dwConnection)
  798. {
  799.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  800.     ASSERT_VALID(pThis);
  801.     return pThis->m_pOwner->m_xOleObject.Unadvise(dwConnection);
  802. }
  803.  
  804. STDMETHODIMP CDocObjectServer::XOleObject::EnumAdvise(
  805.     LPENUMSTATDATA* ppenumStatData)
  806. {
  807.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  808.     ASSERT_VALID(pThis);
  809.     return pThis->m_pOwner->m_xOleObject.EnumAdvise(ppenumStatData);
  810. }
  811.  
  812. STDMETHODIMP CDocObjectServer::XOleObject::GetMiscStatus(
  813.     DWORD dwAspect, DWORD* pdwStatus)
  814. {
  815.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  816.     ASSERT_VALID(pThis);
  817.     return pThis->m_pOwner->m_xOleObject.GetMiscStatus(dwAspect, pdwStatus);
  818. }
  819.  
  820. STDMETHODIMP CDocObjectServer::XOleObject::SetColorScheme(LPLOGPALETTE lpLogpal)
  821. {
  822.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  823.     ASSERT_VALID(pThis);
  824.     return pThis->m_pOwner->m_xOleObject.SetColorScheme(lpLogpal);
  825. }
  826.  
  827.  
  828. /////////////////////////////////////////////////////////////////////////////
  829. // CDocObjectServer diagnostics
  830.  
  831. #ifdef _DEBUG
  832. void CDocObjectServer::AssertValid() const
  833. {
  834.     ASSERT(m_pOwner != NULL);
  835.     CCmdTarget::AssertValid();
  836. }
  837.  
  838. void CDocObjectServer::Dump(CDumpContext& dc) const
  839. {
  840.     CCmdTarget::Dump(dc);
  841.     dc << "m_pDocSite = " << m_pDocSite << "\n";
  842.     dc << "m_pViewSite = " << m_pViewSite << "\n";
  843. }
  844. #endif //_DEBUG
  845.  
  846.  
  847. /////////////////////////////////////////////////////////////////////////////
  848. // CDocObjectServerItem implementation
  849.  
  850. IMPLEMENT_DYNAMIC(CDocObjectServerItem, COleServerItem)
  851.  
  852. CDocObjectServerItem::CDocObjectServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete)
  853.     : COleServerItem(pServerDoc, bAutoDelete)
  854. {
  855. }
  856.  
  857. CDocObjectServerItem::~CDocObjectServerItem()
  858. {
  859. }
  860.  
  861. void CDocObjectServerItem::OnDoVerb(LONG iVerb)
  862. {
  863.    COleServerDoc* pDoc = GetDocument();
  864.    ASSERT_VALID(pDoc);
  865.  
  866.    if (pDoc->IsDocObject() && iVerb == OLEIVERB_INPLACEACTIVATE)
  867.       OnShow();
  868.    else
  869.       COleServerItem::OnDoVerb(iVerb);
  870. }
  871.  
  872. void CDocObjectServerItem::OnHide()
  873. {
  874.    COleServerDoc* pDoc = GetDocument();
  875.    ASSERT_VALID(pDoc);
  876.  
  877.    if (pDoc->IsDocObject())
  878.       AfxThrowOleException(OLEOBJ_E_INVALIDVERB);
  879.    else
  880.       COleServerItem::OnHide();
  881. }
  882.  
  883. void CDocObjectServerItem::OnOpen()
  884. {
  885.    COleServerDoc* pDoc = GetDocument();
  886.    ASSERT_VALID(pDoc);
  887.  
  888.    if (pDoc->IsDocObject())
  889.       pDoc->ActivateDocObject();
  890.    else
  891.       COleServerItem::OnOpen();
  892. }
  893.  
  894. void CDocObjectServerItem::OnShow()
  895. {
  896.    COleServerDoc* pDoc = GetDocument();
  897.    ASSERT_VALID(pDoc);
  898.  
  899.    if (pDoc->IsDocObject())
  900.       pDoc->ActivateDocObject();
  901.    else
  902.       COleServerItem::OnShow();
  903. }
  904.  
  905. #ifdef _DEBUG
  906. void CDocObjectServerItem::AssertValid() const
  907. {
  908.     COleServerItem::AssertValid();
  909. }
  910.  
  911. void CDocObjectServerItem::Dump(CDumpContext& dc) const
  912. {
  913.     COleServerItem::Dump(dc);
  914. }
  915. #endif
  916.