home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / oledocob.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  26KB  |  952 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 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->GetParentFrame();
  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.     // find the view we need to print
  208.  
  209.     CView* pView = NULL;
  210.     POSITION pos = pThis->m_pOwner->GetFirstViewPosition();
  211.     if (pos != NULL)
  212.         pView = pThis->m_pOwner->GetNextView(pos);
  213.  
  214.     if (pView == NULL)
  215.         return E_UNEXPECTED;
  216.  
  217.     // tell the view that we're not actually printing
  218.     // and just need to measure the print job
  219.  
  220.     CPrintInfo printInfo;
  221.     printInfo.m_bDocObject = TRUE;
  222.     printInfo.m_dwFlags = PRINTFLAG_DONTACTUALLYPRINT;
  223.  
  224.     // ask the view about it
  225.  
  226.     if (!pThis->DoPreparePrinting(pView, &printInfo))
  227.         return E_UNEXPECTED;
  228.  
  229.     // pnFirstPage and pcPages are allowed to be NULL
  230.     // if NULL, don't return results to caller
  231.  
  232.     if (pnFirstPage != NULL)
  233.     {
  234.         if (pThis->m_nFirstPage == -1)
  235.             *pnFirstPage = printInfo.GetMinPage();
  236.         else
  237.             *pnFirstPage = pThis->m_nFirstPage;
  238.     }
  239.  
  240.     if (pcPages != NULL)
  241.     {
  242.         if (printInfo.GetToPage() == 0xFFFF)
  243.             *pcPages = 0xFFFF;
  244.         else
  245.             *pcPages = printInfo.GetToPage() - printInfo.GetFromPage() +1;
  246.     }
  247.  
  248.     return S_OK;
  249. }
  250.  
  251. STDMETHODIMP CDocObjectServer::XPrint::Print(
  252.    DWORD grfFlags, DVTARGETDEVICE** ppTD, PAGESET** ppPageSet,
  253.    LPSTGMEDIUM pstgmOptions, LPCONTINUECALLBACK pCallback, LONG nFirstPage,
  254.    LPLONG pcPagesPrinted, LPLONG pnLastPage)
  255. {
  256.     METHOD_PROLOGUE_EX(CDocObjectServer, Print)
  257.     ASSERT_VALID(pThis);
  258.     UNUSED_ALWAYS(pstgmOptions);
  259.     UNUSED_ALWAYS(pnLastPage);
  260.  
  261.     // try to get out of this without doing any work
  262.  
  263.     if (pcPagesPrinted == NULL || ppTD == NULL || ppPageSet == NULL)
  264.         return E_POINTER;
  265.  
  266.     if (*ppTD == NULL)
  267.         return E_INVALIDARG;
  268.  
  269.     // get initialized
  270.  
  271.     DVTARGETDEVICE* ptd = *ppTD;
  272.     pThis->m_nFirstPage = nFirstPage;
  273.     *pcPagesPrinted = 0;
  274.  
  275.     // find the view we need to print
  276.  
  277.     CView* pView = NULL;
  278.     POSITION pos = pThis->m_pOwner->GetFirstViewPosition();
  279.     if (pos != NULL)
  280.         pView = pThis->m_pOwner->GetNextView(pos);
  281.  
  282.     if (pView == NULL)
  283.         return E_UNEXPECTED;
  284.  
  285.     // get default print info
  286.     CPrintInfo printInfo;
  287.     ASSERT(printInfo.m_pPD != NULL);    // must be set
  288.     printInfo.m_bDocObject = TRUE;
  289.     printInfo.m_dwFlags = grfFlags;
  290.     printInfo.m_nOffsetPage = nFirstPage;
  291.  
  292.     printInfo.m_pPD->m_pd.hDC = _AfxOleCreateDC(*ppTD);
  293.     if (printInfo.m_pPD->m_pd.hDC == NULL)
  294.     {
  295.         if (grfFlags & PRINTFLAG_MAYBOTHERUSER)
  296.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  297.         return E_UNEXPECTED;
  298.     }
  299.  
  300.     if (pThis->DoPreparePrinting(pView, &printInfo))
  301.     {
  302.         // hDC must be set (did you remember to call DoPreparePrinting?)
  303.         ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
  304.  
  305.         // set file to print to if print-to-file selected
  306.         CString strOutput;
  307.         if (grfFlags & PRINTFLAG_PRINTTOFILE)
  308.             strOutput = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  309.  
  310.         // if we were to prompt, we'll need to copy info from the
  311.         // user back to the client
  312.  
  313.         if (grfFlags & PRINTFLAG_PROMPTUSER)
  314.         {
  315.             if (grfFlags & PRINTFLAG_USERMAYCHANGEPRINTER)
  316.             {
  317.                 LPDEVNAMES lpDevNames =
  318.                     (LPDEVNAMES) GlobalLock(printInfo.m_pPD->m_pd.hDevNames);
  319.                 LPDEVMODE lpDevMode =
  320.                     (LPDEVMODE) GlobalLock(printInfo.m_pPD->m_pd.hDevMode);
  321.  
  322.                 if (lpDevNames == NULL || lpDevMode == NULL)
  323.                     *ppTD = NULL;
  324.                 else
  325.                     *ppTD = _AfxOleCreateTargetDevice(lpDevNames, lpDevMode);
  326.  
  327.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevNames);
  328.                 GlobalUnlock(printInfo.m_pPD->m_pd.hDevMode);
  329.             }
  330.  
  331.             // MFC page ranges (for now) only have one PAGERANGE
  332.  
  333.             LPMALLOC pMalloc = NULL;
  334.  
  335.             // if the caller didn't supply a buffer, allocate one
  336.             // else, make sure the buffer is big enough
  337.  
  338.             if (*ppPageSet == NULL)
  339.             {
  340.                 HRESULT hrCopying = CoGetMalloc(1, &pMalloc);
  341.                 if (FAILED(hrCopying))
  342.                     return hrCopying;
  343.  
  344.                 *ppPageSet =
  345.                     (PAGESET*) pMalloc->Alloc(sizeof(PAGESET) + sizeof(PAGERANGE));
  346.             }
  347.             else
  348.             {
  349.                 if ((*ppPageSet)->cPageRange < 1 ||
  350.                     (*ppPageSet)->cbStruct != sizeof(PAGESET))
  351.                 {
  352.                     return E_INVALIDARG;
  353.                 }
  354.             }
  355.  
  356.             if (*ppPageSet != NULL)
  357.             {
  358.                 (*ppPageSet)->cbStruct = sizeof(PAGESET);
  359.                 (*ppPageSet)->fOddPages = TRUE;
  360.                 (*ppPageSet)->fEvenPages = TRUE;
  361.                 (*ppPageSet)->cPageRange = 1;
  362.  
  363.                 (*ppPageSet)->rgPages[0].nFromPage = printInfo.GetFromPage();
  364.                 (*ppPageSet)->rgPages[0].nToPage = printInfo.GetToPage();
  365.             }
  366.  
  367.             RELEASE(pMalloc);
  368.  
  369.             if (*ppTD == NULL || *ppPageSet == NULL)
  370.                 return E_UNEXPECTED;
  371.         }
  372.  
  373.         // if the client didn't really want to print,
  374.         // we've collected all the information we need
  375.         if (grfFlags & PRINTFLAG_DONTACTUALLYPRINT)
  376.             return S_OK;
  377.  
  378.         // set up document info and start the document printing process
  379.         CString strTitle;
  380.         CDocument* pDoc = pThis->m_pOwner;
  381.         if (pDoc != NULL)
  382.             strTitle = pDoc->GetTitle();
  383.         else
  384.             pView->GetParentFrame()->GetWindowText(strTitle);
  385.  
  386.         if (strTitle.GetLength() > 31)
  387.             strTitle.ReleaseBuffer(31);
  388.  
  389.         DOCINFO docInfo;
  390.         memset(&docInfo, 0, sizeof(DOCINFO));
  391.         docInfo.cbSize = sizeof(DOCINFO);
  392.         docInfo.lpszDocName = strTitle;
  393.         CString strPortName;
  394.         int nFormatID;
  395.         if (strOutput.IsEmpty())
  396.         {
  397.             docInfo.lpszOutput = NULL;
  398.             strPortName = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  399.             nFormatID = AFX_IDS_PRINTONPORT;
  400.         }
  401.         else
  402.         {
  403.             docInfo.lpszOutput = strOutput;
  404.             AfxGetFileTitle(strOutput,
  405.                 strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
  406.             nFormatID = AFX_IDS_PRINTTOFILE;
  407.         }
  408.  
  409.         // setup the printing DC
  410.         CDC dcPrint;
  411.         dcPrint.Attach(printInfo.m_pPD->m_pd.hDC);  // attach printer dc
  412.         dcPrint.m_bPrinting = TRUE;
  413.         pThis->DoBeginPrinting(pView, &dcPrint, &printInfo);
  414.         dcPrint.SetAbortProc(_AfxAbortProc);
  415.  
  416.         // disable main window while printing & init printing status dialog
  417.         AfxGetMainWnd()->EnableWindow(FALSE);
  418.  
  419.         CString strTemp;
  420.  
  421.         // start document printing process
  422.         if (dcPrint.StartDoc(&docInfo) == SP_ERROR)
  423.         {
  424.             // enable main window before proceeding
  425.             AfxGetMainWnd()->EnableWindow(TRUE);
  426.  
  427.             // cleanup and show error message
  428.             pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  429.             dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  430.             AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
  431.             return E_UNEXPECTED;
  432.         }
  433.  
  434.         // Guarantee values are in the valid range
  435.         UINT nEndPage = printInfo.GetToPage();
  436.         UINT nStartPage = printInfo.GetFromPage();
  437.  
  438.         if (nEndPage < printInfo.GetMinPage())
  439.             nEndPage = printInfo.GetMinPage();
  440.         if (nEndPage > printInfo.GetMaxPage())
  441.             nEndPage = printInfo.GetMaxPage();
  442.  
  443.         if (nStartPage < printInfo.GetMinPage())
  444.             nStartPage = printInfo.GetMinPage();
  445.         if (nStartPage > printInfo.GetMaxPage())
  446.             nStartPage = printInfo.GetMaxPage();
  447.  
  448.         int nStep = (nEndPage >= nStartPage) ? 1 : -1;
  449.         nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep;
  450.  
  451.         VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));
  452.  
  453.         // begin page printing loop
  454.         BOOL bError = FALSE;
  455.         HRESULT hrContinue = S_OK;
  456.  
  457.         for (printInfo.m_nCurPage = nStartPage;
  458.             printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep)
  459.         {
  460.             // check even/odd filter
  461.             if (printInfo.m_nCurPage % 2 == 1 && !(*ppPageSet)->fOddPages)
  462.                 continue;
  463.             if (printInfo.m_nCurPage % 2 == 0 && !(*ppPageSet)->fEvenPages)
  464.                 continue;
  465.  
  466.             // check PAGERANGE if supplied
  467.             if (ppPageSet != NULL && (*ppPageSet)->cPageRange > 0)
  468.             {
  469.                 ULONG nCheckRange;
  470.                 BOOL bFound = FALSE;
  471.                 for (nCheckRange = 0; (nCheckRange < (*ppPageSet)->cPageRange) && !bFound; nCheckRange++)
  472.                 {
  473.                     if ( ((*ppPageSet)->rgPages[nCheckRange].nFromPage <= (LONG) printInfo.m_nCurPage ) &&
  474.                          ((*ppPageSet)->rgPages[nCheckRange].nToPage >= (LONG) printInfo.m_nCurPage) )
  475.                     {
  476.                         bFound = TRUE;
  477.                     }
  478.                 }
  479.  
  480.                 if (!bFound)
  481.                     continue;
  482.             }
  483.  
  484.             pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  485.  
  486.             // check for end of print
  487.             if (!printInfo.m_bContinuePrinting)
  488.                 break;
  489.  
  490.             // set up drawing rect to entire page (in logical coordinates)
  491.             printInfo.m_rectDraw.SetRect(0, 0,
  492.                 dcPrint.GetDeviceCaps(HORZRES),
  493.                 dcPrint.GetDeviceCaps(VERTRES));
  494.             dcPrint.DPtoLP(&printInfo.m_rectDraw);
  495.  
  496.             // attempt to start the current page
  497.             if (dcPrint.StartPage() < 0)
  498.             {
  499.                 bError = TRUE;
  500.                 break;
  501.             }
  502.  
  503.             // must call OnPrepareDC on newer versions of Windows because
  504.             // StartPage now resets the device attributes.
  505.             if (afxData.bMarked4)
  506.                 pThis->DoPrepareDC(pView, &dcPrint, &printInfo);
  507.  
  508.             ASSERT(printInfo.m_bContinuePrinting);
  509.  
  510.             hrContinue = S_OK;
  511.  
  512.             if (pCallback != NULL)
  513.             {
  514.                 hrContinue = pCallback->FContinuePrinting(printInfo.m_nCurPage,
  515.                     printInfo.m_nCurPage + printInfo.m_nOffsetPage, NULL);
  516.             }
  517.  
  518.             // page successfully started, so now render the page
  519.             pThis->DoPrint(pView, &dcPrint, &printInfo);
  520.             if (dcPrint.EndPage() < 0 ||
  521.                 !_AfxAbortProc(dcPrint.m_hDC, 0) ||
  522.                 hrContinue != S_OK)
  523.             {
  524.                 bError = TRUE;
  525.                 break;
  526.             }
  527.  
  528.             // increment count
  529.             (*pcPagesPrinted)++;
  530.         }
  531.  
  532.         // cleanup document printing process
  533.         if (!bError)
  534.             dcPrint.EndDoc();
  535.         else
  536.             dcPrint.AbortDoc();
  537.  
  538.         AfxGetMainWnd()->EnableWindow();    // enable main window
  539.  
  540.         // clean up after printing
  541.         pThis->DoEndPrinting(pView, &dcPrint, &printInfo);
  542.         dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
  543.  
  544.         if (bError)
  545.         {
  546.             if (hrContinue != S_OK)
  547.                 return PRINT_E_CANCELLED;
  548.             else
  549.                 return E_UNEXPECTED;
  550.         }
  551.     }
  552.  
  553.     return S_OK;
  554. }
  555.  
  556. /////////////////////////////////////////////////////////////////////////////
  557. // IOleDocument interface
  558.  
  559. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::AddRef()
  560. {
  561.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  562.     return pThis->m_pOwner->ExternalAddRef();
  563. }
  564.  
  565. STDMETHODIMP_(ULONG) CDocObjectServer::XOleDocument::Release()
  566. {
  567.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  568.     return pThis->m_pOwner->ExternalRelease();
  569. }
  570.  
  571. STDMETHODIMP CDocObjectServer::XOleDocument::QueryInterface(
  572.     REFIID iid, LPVOID* ppvObj)
  573. {
  574.     METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  575.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  576. }
  577.  
  578. STDMETHODIMP CDocObjectServer::XOleDocument::CreateView(
  579.    LPOLEINPLACESITE pipsite, LPSTREAM pstm,
  580.    DWORD dwReserved, LPOLEDOCUMENTVIEW* ppview)
  581. {
  582.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  583.    ASSERT_VALID(pThis);
  584.  
  585.    *ppview = NULL;
  586.  
  587.    HRESULT hr = E_FAIL;
  588.  
  589.    if (dwReserved == 0 && pThis->m_pDocSite != NULL)
  590.    {
  591.       // We only support a single view...so if view site is already
  592.       // set, fail.
  593.       if (pThis->m_pViewSite == NULL)
  594.       {
  595.          LPOLEDOCUMENTVIEW pView =
  596.             (LPOLEDOCUMENTVIEW)pThis->GetInterface(&IID_IOleDocumentView);
  597.          ASSERT(pView != NULL);
  598.  
  599.          // Set the site for the view
  600.          hr = pView->SetInPlaceSite(pipsite);
  601.          if (hr == NOERROR)
  602.          {
  603.             // Return the IOleDocumentView pointer
  604.             pView->AddRef();
  605.             *ppview = pView;
  606.          }
  607.  
  608.          // If a saved view state is provided, restore the view state
  609.          if (pstm)
  610.             hr = pView->ApplyViewState(pstm);
  611.       }
  612.       else
  613.          TRACE0("CDocObjectServer::XOleDocument::CreateView view already exists!\n");
  614.    }
  615.  
  616.    return hr;
  617. }
  618.  
  619. STDMETHODIMP CDocObjectServer::XOleDocument::GetDocMiscStatus(
  620.    LPDWORD pdwStatus)
  621. {
  622.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  623.    ASSERT_VALID(pThis);
  624.    ASSERT(pdwStatus != NULL);
  625.  
  626.    // Our implementation of DocObjects can't create multiple views,
  627.    // does not support complex rectangles, supports open editing,
  628.    // and supports read/write to a file. Thus DOCMISC == 0.
  629.    *pdwStatus = 0;
  630.  
  631.    return NOERROR;
  632. }
  633.  
  634. STDMETHODIMP CDocObjectServer::XOleDocument::EnumViews(
  635.    LPENUMOLEDOCUMENTVIEWS* ppEnumView, LPOLEDOCUMENTVIEW* ppView)
  636. {
  637.    METHOD_PROLOGUE_EX(CDocObjectServer, OleDocument)
  638.    ASSERT_VALID(pThis);
  639.    ASSERT(ppEnumView != NULL);
  640.    ASSERT(ppView != NULL);
  641.  
  642.    // We only support a single view
  643.    *ppEnumView = NULL;
  644.    HRESULT hr = QueryInterface(IID_IOleDocumentView, (LPVOID*)ppView);
  645.    return hr;
  646. }
  647.  
  648. /////////////////////////////////////////////////////////////////////////////
  649. // IOleObject interface
  650.  
  651. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::AddRef()
  652. {
  653.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  654.     return pThis->m_pOwner->ExternalAddRef();
  655. }
  656.  
  657. STDMETHODIMP_(ULONG) CDocObjectServer::XOleObject::Release()
  658. {
  659.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  660.     return pThis->m_pOwner->ExternalRelease();
  661. }
  662.  
  663. STDMETHODIMP CDocObjectServer::XOleObject::QueryInterface(
  664.     REFIID iid, LPVOID* ppvObj)
  665. {
  666.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  667.     return pThis->m_pOwner->ExternalQueryInterface(&iid, ppvObj);
  668. }
  669.  
  670. STDMETHODIMP CDocObjectServer::XOleObject::SetClientSite(
  671.     LPOLECLIENTSITE pClientSite)
  672. {
  673.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  674.     ASSERT_VALID(pThis);
  675.     HRESULT hr = NOERROR;
  676.  
  677.     // Perform normal SetClientSite processing.
  678.     hr = pThis->m_pOwner->m_xOleObject.SetClientSite(pClientSite);
  679.     if (hr != S_OK)
  680.         return hr;
  681.  
  682.     // If we currently have a document site pointer,
  683.     // release it.
  684.  
  685.     pThis->ReleaseDocSite();
  686.  
  687.     // Check to see whether this object should act
  688.     // as a document object by querying for
  689.     // IOleDocumentSite.
  690.     if (pClientSite != NULL)
  691.         hr = pClientSite->QueryInterface(IID_IOleDocumentSite,
  692.             (LPVOID*)&pThis->m_pDocSite);
  693.     return hr;
  694. }
  695.  
  696. STDMETHODIMP CDocObjectServer::XOleObject::GetClientSite(
  697.     LPOLECLIENTSITE* ppClientSite)
  698. {
  699.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  700.     ASSERT_VALID(pThis);
  701.     return pThis->m_pOwner->m_xOleObject.GetClientSite(ppClientSite);
  702. }
  703.  
  704. STDMETHODIMP CDocObjectServer::XOleObject::SetHostNames(
  705.     LPCOLESTR lpszContainerApp, LPCOLESTR lpszContainerObj)
  706. {
  707.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  708.     ASSERT_VALID(pThis);
  709.     return pThis->m_pOwner->m_xOleObject.SetHostNames(lpszContainerApp,
  710.                                            lpszContainerObj);
  711. }
  712.  
  713. STDMETHODIMP CDocObjectServer::XOleObject::Close(DWORD dwSaveOption)
  714. {
  715.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  716.     ASSERT_VALID(pThis);
  717.     return pThis->m_pOwner->m_xOleObject.Close(dwSaveOption);
  718. }
  719.  
  720. STDMETHODIMP CDocObjectServer::XOleObject::SetMoniker(
  721.     DWORD dwWhichMoniker, LPMONIKER pmk)
  722. {
  723.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  724.     ASSERT_VALID(pThis);
  725.     return pThis->m_pOwner->m_xOleObject.SetMoniker(dwWhichMoniker, pmk);
  726. }
  727.  
  728. STDMETHODIMP CDocObjectServer::XOleObject::GetMoniker(
  729.     DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER* ppMoniker)
  730. {
  731.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  732.     ASSERT_VALID(pThis);
  733.     return pThis->m_pOwner->m_xOleObject.GetMoniker(dwAssign, dwWhichMoniker,
  734.                                          ppMoniker);
  735. }
  736.  
  737. STDMETHODIMP CDocObjectServer::XOleObject::InitFromData(
  738.     LPDATAOBJECT pDataObject, BOOL bCreation, DWORD dwReserved)
  739. {
  740.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  741.     ASSERT_VALID(pThis);
  742.     return pThis->m_pOwner->m_xOleObject.InitFromData(pDataObject, bCreation,
  743.                                            dwReserved);
  744. }
  745.  
  746. STDMETHODIMP CDocObjectServer::XOleObject::GetClipboardData(
  747.     DWORD dwReserved, LPDATAOBJECT* ppDataObject)
  748. {
  749.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  750.     ASSERT_VALID(pThis);
  751.     return pThis->m_pOwner->m_xOleObject.GetClipboardData(dwReserved,
  752.                                                ppDataObject);
  753.  
  754. }
  755.  
  756. STDMETHODIMP CDocObjectServer::XOleObject::DoVerb(
  757.     LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex,
  758.     HWND hwndParent, LPCRECT lpPosRect)
  759. {
  760.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  761.     ASSERT_VALID(pThis);
  762.     return pThis->m_pOwner->m_xOleObject.DoVerb(iVerb, lpmsg,
  763.         pActiveSite, lindex, hwndParent, lpPosRect);
  764. }
  765.  
  766. STDMETHODIMP CDocObjectServer::XOleObject::EnumVerbs(
  767.     IEnumOLEVERB** ppenumOleVerb)
  768. {
  769.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  770.     ASSERT_VALID(pThis);
  771.     return pThis->m_pOwner->m_xOleObject.EnumVerbs(ppenumOleVerb);
  772. }
  773.  
  774. STDMETHODIMP CDocObjectServer::XOleObject::Update()
  775. {
  776.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  777.     ASSERT_VALID(pThis);
  778.     return pThis->m_pOwner->m_xOleObject.Update();
  779. }
  780.  
  781. STDMETHODIMP CDocObjectServer::XOleObject::IsUpToDate()
  782. {
  783.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  784.     ASSERT_VALID(pThis);
  785.     return pThis->m_pOwner->m_xOleObject.IsUpToDate();
  786. }
  787.  
  788. STDMETHODIMP CDocObjectServer::XOleObject::GetUserClassID(CLSID* lpClassID)
  789. {
  790.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  791.     ASSERT_VALID(pThis);
  792.     return pThis->m_pOwner->m_xOleObject.GetUserClassID(lpClassID);
  793. }
  794.  
  795. STDMETHODIMP CDocObjectServer::XOleObject::GetUserType(
  796.     DWORD dwFormOfType, LPOLESTR* ppszUserType)
  797. {
  798.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  799.     ASSERT_VALID(pThis);
  800.     return pThis->m_pOwner->m_xOleObject.GetUserType(dwFormOfType, ppszUserType);
  801. }
  802.  
  803. STDMETHODIMP CDocObjectServer::XOleObject::SetExtent(
  804.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  805. {
  806.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  807.     ASSERT_VALID(pThis);
  808.  
  809.     // DocObjects ignore SetExtent calls, so returne E_FAIL
  810.     if (pThis->m_pOwner->IsDocObject())
  811.         return E_FAIL;
  812.  
  813.     // Otherwise, just do the normal processing
  814.     return pThis->m_pOwner->m_xOleObject.SetExtent(dwDrawAspect, lpsizel);
  815. }
  816.  
  817. STDMETHODIMP CDocObjectServer::XOleObject::GetExtent(
  818.     DWORD dwDrawAspect, LPSIZEL lpsizel)
  819. {
  820.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  821.     ASSERT_VALID(pThis);
  822.     return pThis->m_pOwner->m_xOleObject.GetExtent(dwDrawAspect, lpsizel);
  823. }
  824.  
  825. STDMETHODIMP CDocObjectServer::XOleObject::Advise(
  826.     LPADVISESINK pAdvSink, DWORD* pdwConnection)
  827. {
  828.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  829.     ASSERT_VALID(pThis);
  830.     return pThis->m_pOwner->m_xOleObject.Advise(pAdvSink, pdwConnection);
  831. }
  832.  
  833. STDMETHODIMP CDocObjectServer::XOleObject::Unadvise(DWORD dwConnection)
  834. {
  835.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  836.     ASSERT_VALID(pThis);
  837.     return pThis->m_pOwner->m_xOleObject.Unadvise(dwConnection);
  838. }
  839.  
  840. STDMETHODIMP CDocObjectServer::XOleObject::EnumAdvise(
  841.     LPENUMSTATDATA* ppenumStatData)
  842. {
  843.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  844.     ASSERT_VALID(pThis);
  845.     return pThis->m_pOwner->m_xOleObject.EnumAdvise(ppenumStatData);
  846. }
  847.  
  848. STDMETHODIMP CDocObjectServer::XOleObject::GetMiscStatus(
  849.     DWORD dwAspect, DWORD* pdwStatus)
  850. {
  851.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  852.     ASSERT_VALID(pThis);
  853.     return pThis->m_pOwner->m_xOleObject.GetMiscStatus(dwAspect, pdwStatus);
  854. }
  855.  
  856. STDMETHODIMP CDocObjectServer::XOleObject::SetColorScheme(LPLOGPALETTE lpLogpal)
  857. {
  858.     METHOD_PROLOGUE_EX(CDocObjectServer, OleObject)
  859.     ASSERT_VALID(pThis);
  860.     return pThis->m_pOwner->m_xOleObject.SetColorScheme(lpLogpal);
  861. }
  862.  
  863.  
  864. /////////////////////////////////////////////////////////////////////////////
  865. // CDocObjectServer diagnostics
  866.  
  867. #ifdef _DEBUG
  868. void CDocObjectServer::AssertValid() const
  869. {
  870.     ASSERT(m_pOwner != NULL);
  871.     CCmdTarget::AssertValid();
  872. }
  873.  
  874. void CDocObjectServer::Dump(CDumpContext& dc) const
  875. {
  876.     CCmdTarget::Dump(dc);
  877.     dc << "m_pDocSite = " << m_pDocSite << "\n";
  878.     dc << "m_pViewSite = " << m_pViewSite << "\n";
  879. }
  880. #endif //_DEBUG
  881.  
  882.  
  883. /////////////////////////////////////////////////////////////////////////////
  884. // CDocObjectServerItem implementation
  885.  
  886. IMPLEMENT_DYNAMIC(CDocObjectServerItem, COleServerItem)
  887.  
  888. CDocObjectServerItem::CDocObjectServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete)
  889.     : COleServerItem(pServerDoc, bAutoDelete)
  890. {
  891. }
  892.  
  893. CDocObjectServerItem::~CDocObjectServerItem()
  894. {
  895. }
  896.  
  897. void CDocObjectServerItem::OnDoVerb(LONG iVerb)
  898. {
  899.    COleServerDoc* pDoc = GetDocument();
  900.    ASSERT_VALID(pDoc);
  901.  
  902.    if (pDoc->IsDocObject() && (iVerb == OLEIVERB_INPLACEACTIVATE || iVerb == OLEIVERB_SHOW) )
  903.       OnShow();
  904.    else
  905.       COleServerItem::OnDoVerb(iVerb);
  906. }
  907.  
  908. void CDocObjectServerItem::OnHide()
  909. {
  910.    COleServerDoc* pDoc = GetDocument();
  911.    ASSERT_VALID(pDoc);
  912.  
  913.    if (pDoc->IsDocObject())
  914.       AfxThrowOleException(OLEOBJ_E_INVALIDVERB);
  915.    else
  916.       COleServerItem::OnHide();
  917. }
  918.  
  919. void CDocObjectServerItem::OnOpen()
  920. {
  921.    COleServerDoc* pDoc = GetDocument();
  922.    ASSERT_VALID(pDoc);
  923.  
  924.    if (pDoc->IsDocObject())
  925.       pDoc->ActivateDocObject();
  926.    else
  927.       COleServerItem::OnOpen();
  928. }
  929.  
  930. void CDocObjectServerItem::OnShow()
  931. {
  932.    COleServerDoc* pDoc = GetDocument();
  933.    ASSERT_VALID(pDoc);
  934.  
  935.    if (pDoc->IsDocObject())
  936.       pDoc->ActivateDocObject();
  937.    else
  938.       COleServerItem::OnShow();
  939. }
  940.  
  941. #ifdef _DEBUG
  942. void CDocObjectServerItem::AssertValid() const
  943. {
  944.     COleServerItem::AssertValid();
  945. }
  946.  
  947. void CDocObjectServerItem::Dump(CDumpContext& dc) const
  948. {
  949.     COleServerItem::Dump(dc);
  950. }
  951. #endif
  952.