oledocob.cpp 25 KB

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