Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2204 lines
60 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // File: srs.cxx
  4. //
  5. // Contents: OLE2 Server Class code
  6. //
  7. // Classes:
  8. // SRCtrl
  9. // SRInPlace
  10. // SRDV
  11. //
  12. //------------------------------------------------------------------------
  13. #include <stdlib.h>
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <commdlg.h> // common dialog boxes
  17. #include <ole2.h>
  18. #include <o2base.hxx> // the base classes and utilities
  19. #include "srecids.h" // for resources
  20. #include "srs.hxx"
  21. // Our class factory
  22. extern SRFactory *gpSRFactory;
  23. extern "C" HINSTANCE ghInst;
  24. DWORD gdwRegROT = 0L; // Registered on the running object table?
  25. LPMONIKER gpFileMoniker = NULL; // Application wide file moniker for linking
  26. LPXBAG gpXBagOnClipboard = NULL;
  27. BOOL gfXBagOnClipboard = FALSE;
  28. LPSRCTRL gpCtrlThis = NULL;
  29. // Glue functions for the C code
  30. //===============================
  31. //
  32. void
  33. FlushOleClipboard(void)
  34. {
  35. if (!gfOleInitialized)
  36. return;
  37. if(gfXBagOnClipboard)
  38. {
  39. if(OleIsCurrentClipboard(gpXBagOnClipboard) == NOERROR)
  40. {
  41. DOUT(TEXT("\\\\Soundrec: OleFlushClipboard()\r\n"));
  42. //
  43. // Keep the data object on the clipboard for object pasting
  44. //
  45. OleFlushClipboard();
  46. gpXBagOnClipboard->Detach();
  47. gpXBagOnClipboard = NULL;
  48. }
  49. gfXBagOnClipboard = FALSE;
  50. }
  51. }
  52. // copied from pbrush
  53. void
  54. TransferToClipboard(void)
  55. {
  56. DOUT(TEXT("TransferToClipboard\r\n"));
  57. if(gpCtrlThis != NULL)
  58. {
  59. LPXBAG pXBag;
  60. HRESULT hr = CXBag::Create(&pXBag, gpCtrlThis, NULL);
  61. if(hr == NOERROR)
  62. {
  63. if(gfXBagOnClipboard)
  64. OleSetClipboard(NULL);
  65. hr = OleSetClipboard(pXBag);
  66. gfXBagOnClipboard = (hr == NOERROR) ? TRUE : FALSE;
  67. if(hr == NOERROR)
  68. {
  69. gpXBagOnClipboard = pXBag;
  70. }
  71. else
  72. {
  73. DOUT(TEXT("TransferToClipboard FAILED!\r\n"));
  74. }
  75. }
  76. }
  77. else
  78. {
  79. DOUT(TEXT("TransferToClipboard called with a NULL gpCtrlThis!\r\n"));
  80. }
  81. }
  82. void AdviseDataChange(void)
  83. {
  84. if(gpCtrlThis)
  85. {
  86. gpCtrlThis->_pDV->OnDataChange();
  87. gpCtrlThis->MarkAsLoaded();
  88. }
  89. }
  90. void AdviseRename(LPTSTR lpname)
  91. {
  92. if(gpCtrlThis)
  93. {
  94. if (gpCtrlThis->_pOleAdviseHolder != NULL)
  95. {
  96. LPMONIKER pmk = NULL;
  97. #if !defined(UNICODE) && !defined(OLE2ANSI)
  98. LPOLESTR lpstr = ConvertMBToOLESTR(lpname,-1);
  99. if(NOERROR == CreateFileMoniker(lpstr, &pmk))
  100. #else
  101. if(NOERROR == CreateFileMoniker(lpname, &pmk))
  102. #endif
  103. {
  104. gpCtrlThis->_pOleAdviseHolder->SendOnRename(pmk);
  105. pmk->Release();
  106. }
  107. #if !defined(UNICODE) && !defined(OLE2ANSI)
  108. TaskFreeMem(lpstr);
  109. #endif
  110. }
  111. }
  112. }
  113. void AdviseSaved(void)
  114. {
  115. if(gpCtrlThis)
  116. {
  117. if (gpCtrlThis->_pOleAdviseHolder != NULL)
  118. {
  119. gpCtrlThis->_pOleAdviseHolder->SendOnSave();
  120. }
  121. }
  122. }
  123. void AdviseClosed(void)
  124. {
  125. if(gpCtrlThis)
  126. {
  127. if (gpCtrlThis->_pOleAdviseHolder != NULL)
  128. {
  129. gpCtrlThis->_pOleAdviseHolder->SendOnClose();
  130. }
  131. }
  132. }
  133. void DoOleSave(void)
  134. {
  135. if(!gfStandalone && gpCtrlThis && gpCtrlThis->_pClientSite)
  136. {
  137. gpCtrlThis->_pClientSite->SaveObject();
  138. }
  139. }
  140. void DoOleClose(BOOL fSave)
  141. {
  142. if(gpCtrlThis)
  143. {
  144. DOUT(TEXT("SoundRec: DoOleClose\r\n"));
  145. if (gfStandalone)
  146. {
  147. RevokeAsRunning(&gdwRegROT);
  148. if(gpFileMoniker != NULL)
  149. {
  150. gpFileMoniker->Release();
  151. gpFileMoniker = NULL;
  152. }
  153. gfClosing = TRUE;
  154. gpCtrlThis->UnLock();
  155. // This release will cause a fatal recursion in SRCtrl::~SRCtrl on
  156. // objects that were created due to link conversations.
  157. if (gfEmbedded)
  158. gpCtrlThis->Release();
  159. }
  160. else
  161. gpCtrlThis->Close(fSave ? OLECLOSE_SAVEIFDIRTY: OLECLOSE_NOSAVE);
  162. }
  163. }
  164. void WriteObjectIfEmpty()
  165. {
  166. if (gpCtrlThis)
  167. {
  168. if (!gpCtrlThis->IsLoaded())
  169. {
  170. AdviseDataChange();
  171. }
  172. }
  173. }
  174. void OleObjGetHostNames(
  175. LPTSTR *ppCntr,
  176. LPTSTR *ppObj)
  177. {
  178. if (gpCtrlThis)
  179. {
  180. #if !defined(UNICODE) && !defined(OLE2ANSI)
  181. *ppCntr = gpCtrlThis->_lpstrCntrAppA;
  182. *ppObj = gpCtrlThis->_lpstrCntrObjA;
  183. #else
  184. *ppCntr = gpCtrlThis->_lpstrCntrApp;
  185. *ppObj = gpCtrlThis->_lpstrCntrObj;
  186. #endif
  187. }
  188. }
  189. //
  190. // Data Transfer Object
  191. //========================
  192. //
  193. //
  194. // List of formats offered by our data transfer object via EnumFormatEtc
  195. // NOTE: OleClipFormat is a global array of stock formats defined in
  196. // o2base\dvutils.cxx and initialized via RegisterOleClipFormats()
  197. // in our class factory.
  198. //
  199. static FORMATETC g_aGetFmtEtcs[] = {
  200. //
  201. //Other formats go here..
  202. //{ CF_WHATEVER, NULL, DVASPECT_ALL, -1L, TYMED_HGLOBAL }
  203. //
  204. // put the embed source first so containers recognize this is an object
  205. //
  206. { (unsigned short)-OCF_EMBEDSOURCE, NULL, DVASPECT_CONTENT, -1L, TYMED_ISTORAGE },
  207. //
  208. // everything else
  209. //
  210. { (unsigned short)-OCF_OBJECTDESCRIPTOR, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  211. { CF_WAVE, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  212. { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1L, TYMED_MFPICT },
  213. { CF_DIB, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  214. //
  215. // I am reserving the *LAST TWO* for the links. We can prevent a
  216. // link from being offered
  217. //
  218. { (unsigned short)-OCF_LINKSOURCE, NULL, DVASPECT_CONTENT, -1L, TYMED_ISTREAM | TYMED_HGLOBAL },
  219. { (unsigned short)-OCF_LINKSRCDESCRIPTOR, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL }
  220. };
  221. //+---------------------------------------------------------------
  222. //
  223. // Member: CXBag::Create, static
  224. //
  225. // Synopsis: Create a new, initialized transfer object
  226. //
  227. //---------------------------------------------------------------
  228. HRESULT
  229. CXBag::Create(LPXBAG *ppXBag, LPSRCTRL pHost, LPPOINT pptSelected)
  230. {
  231. // Assert(ppXBag != NULL && pHost != NULL && pptSelected != NULL);
  232. LPXBAG pXBag = new CXBag(pHost);
  233. if((*ppXBag = pXBag) == NULL)
  234. return E_OUTOFMEMORY;
  235. return NOERROR;
  236. }
  237. //+---------------------------------------------------------------
  238. //
  239. // Member: CXBag::CXBag
  240. //
  241. // Synopsis: constructor
  242. //
  243. //---------------------------------------------------------------
  244. CXBag::CXBag(LPSRCTRL pHost)
  245. {
  246. _pHost = pHost;
  247. _ulRefs = 1;
  248. _pStgBag = NULL;
  249. }
  250. //+---------------------------------------------------------------
  251. //
  252. // Member: CXBag::~CXBag
  253. //
  254. // Synopsis: destructor
  255. //
  256. //---------------------------------------------------------------
  257. CXBag::~CXBag()
  258. {
  259. _pHost = NULL;
  260. if(_pStgBag != NULL)
  261. _pStgBag->Release();
  262. }
  263. //+---------------------------------------------------------------
  264. //
  265. // Member: CXBag::SnapShotAndDetach
  266. //
  267. // Synopsis: Save a snapshot then detach from Host
  268. //
  269. //---------------------------------------------------------------
  270. HRESULT
  271. CXBag::SnapShotAndDetach(void)
  272. {
  273. STGMEDIUM medium;
  274. medium.pUnkForRelease = NULL; // transfer ownership to caller
  275. medium.hGlobal = NULL;
  276. medium.tymed = TYMED_ISTORAGE;
  277. HRESULT hr = BagItInStorage(&medium, FALSE);
  278. _pHost = NULL;
  279. return hr;
  280. }
  281. //+---------------------------------------------------------------
  282. //
  283. // Member: CXBag::BagItInStorage, private
  284. //
  285. // Synopsis: Save or copy a snapshot into specified stg
  286. //
  287. //---------------------------------------------------------------
  288. HRESULT
  289. CXBag::BagItInStorage(LPSTGMEDIUM pmedium, BOOL fStgProvided)
  290. {
  291. HRESULT hr = NOERROR;
  292. LPPERSISTSTORAGE pPStg = NULL;
  293. LPSTORAGE pStg = fStgProvided ? pmedium->pstg: NULL;
  294. if(!fStgProvided)
  295. {
  296. //
  297. // allocate a temp docfile that will delete on last release
  298. //
  299. hr = StgCreateDocfile(
  300. NULL,
  301. STGM_READWRITE | STGM_DIRECT | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE,
  302. 0,
  303. &pStg);
  304. pmedium->tymed = TYMED_ISTORAGE;
  305. pmedium->pstg = pStg;
  306. }
  307. if(pStg == NULL)
  308. goto LExit;
  309. if(_pStgBag == NULL)
  310. {
  311. if(_pHost == NULL)
  312. {
  313. hr = E_UNEXPECTED; // We got prematurely detached!
  314. goto LExit;
  315. }
  316. _pHost->QueryInterface(IID_IPersistStorage, (LPVOID FAR*)&pPStg);
  317. Assert(pPStg != NULL);
  318. hr = OleSave(pPStg, pStg, FALSE /* fSameAsLoad */);
  319. pPStg->SaveCompleted(NULL);
  320. }
  321. else
  322. {
  323. _pStgBag->CopyTo(NULL, NULL, NULL, pStg);
  324. }
  325. LExit:
  326. if(pPStg != NULL)
  327. pPStg->Release();
  328. return hr;
  329. }
  330. IMPLEMENT_STANDARD_IUNKNOWN(CXBag)
  331. //+---------------------------------------------------------------
  332. //
  333. // Member: CXBag::QueryInterface, public
  334. //
  335. // Synopsis: Expose our IFaces
  336. //
  337. //---------------------------------------------------------------
  338. STDMETHODIMP
  339. CXBag::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  340. {
  341. if (IsEqualIID(riid,IID_IUnknown))
  342. {
  343. *ppv = (LPVOID)this;
  344. }
  345. else if (IsEqualIID(riid,IID_IDataObject))
  346. {
  347. *ppv = (LPVOID)(LPDATAOBJECT)this;
  348. }
  349. else
  350. {
  351. *ppv = NULL;
  352. return E_NOINTERFACE;
  353. }
  354. ((IUnknown FAR*) *ppv)->AddRef();
  355. return NOERROR;
  356. }
  357. //+---------------------------------------------------------------
  358. //
  359. // Member: CXBag::QueryGetData
  360. //
  361. // OLE: IDataObject
  362. //
  363. // Synopsis: Answer whether a request for this format might suceed
  364. //
  365. //---------------------------------------------------------------
  366. STDMETHODIMP
  367. CXBag::QueryGetData(LPFORMATETC pformatetc)
  368. {
  369. HRESULT hr = DV_E_FORMATETC;
  370. //
  371. // Pick out the formats we are willing to offer on IStorage
  372. //
  373. if ( (pformatetc->cfFormat == OleClipFormat[OCF_EMBEDSOURCE]) &&
  374. (pformatetc->dwAspect == DVASPECT_CONTENT) &&
  375. (pformatetc->tymed == TYMED_ISTORAGE) )
  376. {
  377. hr = NOERROR;
  378. }
  379. //
  380. // Pick out the formats we are willing to offer on TYMED_ISTREAM
  381. //
  382. else if (pformatetc->tymed == TYMED_ISTREAM)
  383. {
  384. DOUT(TEXT("CXBag::QueryGetData[ISTREAM]\r\n"));
  385. //
  386. // Do not offer a static link if we don't have a filename
  387. //
  388. if (pformatetc->cfFormat == OleClipFormat[OCF_LINKSOURCE] )
  389. {
  390. hr = NOERROR;
  391. }
  392. }
  393. //
  394. // Pick out the formats we are willing to offer on HGLOBAL
  395. //
  396. else if (pformatetc->tymed == TYMED_HGLOBAL)
  397. {
  398. DOUT(TEXT("CXBag::QueryGetData[HGLOBAL]"));
  399. if (pformatetc->cfFormat == OleClipFormat[OCF_OBJECTDESCRIPTOR])
  400. {
  401. hr = NOERROR;
  402. }
  403. else if (pformatetc->cfFormat == OleClipFormat[OCF_LINKSRCDESCRIPTOR])
  404. {
  405. hr = NOERROR;
  406. }
  407. else if (pformatetc->cfFormat == CF_DIB)
  408. {
  409. DOUT(TEXT("CXBag::QueryGetData[DIB]"));
  410. hr = NOERROR;
  411. }
  412. }
  413. else if ( (pformatetc->tymed == TYMED_MFPICT) &&
  414. ( pformatetc->cfFormat == CF_METAFILEPICT) )
  415. {
  416. DOUT(TEXT("CXBag::QueryGetData[MFPICT]"));
  417. hr = NOERROR;
  418. }
  419. return hr;
  420. }
  421. //+---------------------------------------------------------------
  422. //
  423. // Member: CXBag::EnumFormatEtc
  424. //
  425. // OLE: IDataObject
  426. //
  427. // Synopsis: Answer an enumerator over supported formats
  428. //
  429. //---------------------------------------------------------------
  430. STDMETHODIMP
  431. CXBag::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
  432. {
  433. HRESULT hr = E_NOTIMPL;
  434. *ppenumFormatEtc = NULL;
  435. if (dwDirection == DATADIR_GET)
  436. {
  437. BOOL fNoLink = IsDocUntitled();
  438. ULONG cFormats = ARRAY_SIZE(g_aGetFmtEtcs);
  439. /* Don't enumerate the link support */
  440. if (fNoLink)
  441. cFormats -= 2;
  442. hr = CreateFORMATETCEnum(g_aGetFmtEtcs, cFormats,
  443. ppenumFormatEtc);
  444. }
  445. return hr;
  446. }
  447. //+---------------------------------------------------------------
  448. //
  449. // Member: CXBag::GetData
  450. //
  451. // OLE: IDataObject
  452. //
  453. // Synopsis: Deliver data in requested format
  454. //
  455. //---------------------------------------------------------------
  456. STDMETHODIMP
  457. CXBag::GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium)
  458. {
  459. pmedium->pUnkForRelease = NULL; // transfer ownership to caller
  460. pmedium->hGlobal = NULL;
  461. HRESULT hr = DV_E_FORMATETC;
  462. if ( (pformatetcIn->cfFormat == OleClipFormat[OCF_EMBEDSOURCE]) &&
  463. (pformatetcIn->dwAspect == DVASPECT_CONTENT) &&
  464. (pformatetcIn->tymed == TYMED_ISTORAGE) )
  465. {
  466. DOUT(TEXT("CXBag::GetData:OCF_EMBEDSOURCE\r\n"));
  467. hr = BagItInStorage(pmedium,FALSE);
  468. }
  469. else if(pformatetcIn->tymed & TYMED_ISTREAM)
  470. {
  471. if ( pformatetcIn->cfFormat == OleClipFormat[OCF_LINKSOURCE] )
  472. {
  473. DOUT(TEXT("CXBag::GetData OCF_LINKSOURCE on STREAM\r\n"));
  474. if(_pHost != NULL)
  475. {
  476. hr = _pHost->_pDV->GetLINKSOURCE( (LPSRVRDV)(_pHost->_pDV),
  477. pformatetcIn,
  478. pmedium,
  479. FALSE /* fHere */ );
  480. }
  481. }
  482. }
  483. else if((pformatetcIn->tymed & TYMED_HGLOBAL) && (_pHost != NULL))
  484. {
  485. pmedium->tymed = TYMED_HGLOBAL;
  486. if ( pformatetcIn->cfFormat == OleClipFormat[OCF_OBJECTDESCRIPTOR] )
  487. {
  488. DOUT(TEXT("CXBag::GetData OCF_OBJECTDESCRIPTOR on HGLOBAL\r\n"));
  489. hr = _pHost->_pDV->GetOBJECTDESCRIPTOR( (LPSRVRDV)(_pHost->_pDV),
  490. pformatetcIn,
  491. pmedium,
  492. FALSE /* fHere */ );
  493. }
  494. else if (pformatetcIn->cfFormat == OleClipFormat[OCF_LINKSRCDESCRIPTOR])
  495. {
  496. DOUT(TEXT("CXBag::GetData OCF_LINKSRCDESCRIPTOR on HGLOBAL\r\n"));
  497. hr = _pHost->_pDV->GetOBJECTDESCRIPTOR( (LPSRVRDV)(_pHost->_pDV),
  498. pformatetcIn,
  499. pmedium,
  500. FALSE /* fHere */ );
  501. }
  502. else if ( pformatetcIn->cfFormat == CF_WAVE )
  503. {
  504. DOUT(TEXT("CXBag::GetData CF_WAVE on HGLOBAL\r\n"));
  505. if ((pmedium->hGlobal = GetNativeData()) != NULL)
  506. hr = NOERROR;
  507. }
  508. else if ( pformatetcIn->cfFormat == CF_DIB )
  509. {
  510. DOUT(TEXT("CXBag::GetData CF_DIB on HGLOBAL\r\n"));
  511. if ((pmedium->hGlobal = ::GetDIB(NULL)) != NULL)
  512. hr = NOERROR;
  513. }
  514. }
  515. else if (pformatetcIn->tymed & TYMED_MFPICT)
  516. {
  517. pmedium->tymed = TYMED_MFPICT;
  518. if (pformatetcIn->cfFormat == CF_METAFILEPICT)
  519. {
  520. DOUT(TEXT("CXBag::GetData CF_METAFILEPICT\r\n"));
  521. if (_pHost != NULL)
  522. {
  523. if ((pmedium->hGlobal = GetPicture())!= NULL)
  524. hr = NOERROR;
  525. }
  526. }
  527. }
  528. return hr;
  529. }
  530. //+---------------------------------------------------------------
  531. //
  532. // Member: CXBag::GetDataHere
  533. //
  534. // OLE: IDataObject
  535. //
  536. // Synopsis: Deliver requested format in specified medium
  537. //
  538. //---------------------------------------------------------------
  539. STDMETHODIMP
  540. CXBag::GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
  541. {
  542. HRESULT hr = DV_E_FORMATETC;
  543. if ( (pformatetc->cfFormat == OleClipFormat[OCF_EMBEDSOURCE]) &&
  544. (pformatetc->dwAspect == DVASPECT_CONTENT) &&
  545. (pformatetc->tymed == TYMED_ISTORAGE) )
  546. {
  547. DOUT(TEXT("CXBag::GetDataHere:OCF_EMBEDSOURCE\r\n"));
  548. hr = BagItInStorage(pmedium,TRUE);
  549. }
  550. else if(pformatetc->tymed & TYMED_ISTREAM)
  551. {
  552. if (pformatetc->cfFormat = (WORD)OleClipFormat[OCF_LINKSOURCE])
  553. {
  554. DOUT(TEXT("CXBag::GetDataHere:OCF_LINKSOURCE\r\n"));
  555. if (_pHost != NULL)
  556. {
  557. hr = _pHost->_pDV->GetLINKSOURCE((LPSRVRDV)(_pHost->_pDV)
  558. ,pformatetc
  559. ,pmedium
  560. ,TRUE);
  561. }
  562. }
  563. }
  564. else if ((pformatetc->tymed & TYMED_HGLOBAL) && (_pHost != NULL))
  565. {
  566. if ( pformatetc->cfFormat == OleClipFormat[OCF_OBJECTDESCRIPTOR] )
  567. {
  568. DOUT(TEXT("CXBag::GetDataHere:OCF_OBJECTDESCRIPTOR\r\n"));
  569. hr = _pHost->_pDV->GetOBJECTDESCRIPTOR( _pHost->_pDV,
  570. pformatetc,
  571. pmedium,
  572. TRUE /* fHere */ );
  573. }
  574. else if ( pformatetc->cfFormat == OleClipFormat[OCF_LINKSRCDESCRIPTOR])
  575. {
  576. DOUT(TEXT("CXBag::GetDataHere:OCF_LINKSRCDESCRIPTOR\r\n"));
  577. hr = _pHost->_pDV->GetOBJECTDESCRIPTOR( _pHost->_pDV,
  578. pformatetc,
  579. pmedium,
  580. TRUE /* fHere */ );
  581. }
  582. else if ( pformatetc->cfFormat == CF_WAVE )
  583. {
  584. DOUT(TEXT("CXBag::GetDataHere CF_WAVE on HGLOBAL\r\n"));
  585. if ((pmedium->hGlobal = GetNativeData()) != NULL)
  586. hr = NOERROR;
  587. }
  588. else if ( pformatetc->cfFormat == CF_DIB )
  589. {
  590. DOUT(TEXT("CXBag::GetDataHere CF_DIB on HGLOBAL\r\n"));
  591. if ((pmedium->hGlobal = ::GetDIB(pmedium->hGlobal)) != NULL)
  592. hr = NOERROR;
  593. }
  594. }
  595. else if (pformatetc->tymed & TYMED_MFPICT)
  596. {
  597. pmedium->tymed = TYMED_MFPICT;
  598. if (pformatetc->cfFormat == CF_METAFILEPICT)
  599. {
  600. DOUT(TEXT("CXBag::GetData CF_METAFILEPICT\r\n"));
  601. if (_pHost != NULL)
  602. {
  603. if ((pmedium->hGlobal = GetPicture()) != NULL)
  604. hr = NOERROR;
  605. }
  606. }
  607. }
  608. #if 0
  609. //
  610. // Replace with appropriate format handlers...
  611. //
  612. else if ( pformatetc->cfFormat == g_cfSourceList )
  613. {
  614. hr = _pBaggedList->Copy(pmedium->hGlobal);
  615. }
  616. #endif
  617. return hr;
  618. }
  619. //
  620. // (Open-Editing) Server Object for SoundRec
  621. //==========================================
  622. //
  623. //+---------------------------------------------------------------
  624. //
  625. // Member: SRCtrl::ClassInit, public
  626. //
  627. // Synopsis: Initializes the SRCtrl class
  628. //
  629. // Arguments: [pClass] -- our class descriptor
  630. //
  631. // Returns: TRUE iff the class could be initialized successfully
  632. //
  633. // Notes: This method initializes the verb tables in the
  634. // class descriptor.
  635. //
  636. //---------------------------------------------------------------
  637. static OLECHAR lpszPlay[64];
  638. static OLECHAR lpszEdit[64];
  639. static OLECHAR lpszOpen[64];
  640. BOOL
  641. SRCtrl::ClassInit(LPCLASSDESCRIPTOR pClass)
  642. {
  643. // These are our verb tables. They are used by the base class
  644. // in implementing methods of the IOleObject interface.
  645. // NOTE: the verb table must be in ascending, consecutive order
  646. static OLEVERB OleVerbs[] =
  647. {
  648. // { lVerb, lpszVerbName, fuFlags, grfAttribs },
  649. { OLEIVERB_INPLACEACTIVATE, NULL, 0, 0 },
  650. { OLEIVERB_UIACTIVATE, NULL, 0, 0 },
  651. { OLEIVERB_HIDE, NULL, 0, 0 },
  652. { OLEIVERB_OPEN, NULL, 0, 0 },
  653. { OLEIVERB_SHOW, NULL, 0, 0 },
  654. { OLEIVERB_PRIMARY, lpszPlay, MF_ENABLED, OLEVERBATTRIB_ONCONTAINERMENU },
  655. { 1, lpszEdit, MF_ENABLED, OLEVERBATTRIB_ONCONTAINERMENU },
  656. { 2, lpszOpen, MF_ENABLED, OLEVERBATTRIB_ONCONTAINERMENU }
  657. };
  658. #if !defined(UNICODE) && !defined(OLE2ANSI)
  659. TCHAR sz[64];
  660. LoadString(ghInst, IDS_PLAYVERB, sz, ARRAY_SIZE(sz));
  661. MultiByteToWideChar(CP_ACP, 0, sz, -1, lpszPlay, ARRAY_SIZE(lpszPlay));
  662. LoadString(ghInst, IDS_EDITVERB, sz, ARRAY_SIZE(sz));
  663. MultiByteToWideChar(CP_ACP, 0, sz, -1, lpszEdit, ARRAY_SIZE(lpszEdit));
  664. LoadString(ghInst, IDS_OPENVERB, sz, ARRAY_SIZE(sz));
  665. MultiByteToWideChar(CP_ACP, 0, sz, -1, lpszOpen, ARRAY_SIZE(lpszOpen));
  666. #else
  667. LoadString(ghInst, IDS_PLAYVERB, lpszPlay, ARRAY_SIZE(lpszPlay));
  668. LoadString(ghInst, IDS_EDITVERB, lpszEdit, ARRAY_SIZE(lpszEdit));
  669. LoadString(ghInst, IDS_OPENVERB, lpszOpen, ARRAY_SIZE(lpszOpen));
  670. #endif
  671. pClass->_pVerbTable = OleVerbs;
  672. pClass->_cVerbTable = ARRAY_SIZE(OleVerbs);
  673. return TRUE;
  674. }
  675. //+---------------------------------------------------------------
  676. //
  677. // Member: SRCtrl::Create, public
  678. //
  679. // Synopsis: Creates and initializes an SRCtrl object
  680. //
  681. // Arguments: [pUnkOuter] -- A controlling unknown. NULL if we are not
  682. // being created as part of an aggregation
  683. // [pClass] -- The OlePad class descriptor
  684. // [ppUnkCtrl] -- Where we return our controlling unknown
  685. // [ppObj] -- Pointer to the SRCtrl object created
  686. //
  687. // Returns: Success if the object could be successfully created and
  688. // initialized.
  689. //
  690. //---------------------------------------------------------------
  691. HRESULT
  692. SRCtrl::Create( LPUNKNOWN pUnkOuter,
  693. LPCLASSDESCRIPTOR pClass,
  694. LPUNKNOWN FAR* ppUnkCtrl,
  695. LPSRCTRL FAR* ppObj)
  696. {
  697. // set out parameters to NULL
  698. *ppUnkCtrl = NULL;
  699. *ppObj = NULL;
  700. if(gpCtrlThis)
  701. {
  702. DOUT(TEXT("SRCtrl::Create non-NULL gpCtrlThis!"));
  703. return E_FAIL;
  704. }
  705. // create an object
  706. HRESULT hr = E_OUTOFMEMORY;
  707. LPSRCTRL pObj = new SRCtrl(pUnkOuter);
  708. if (pObj != NULL)
  709. {
  710. // initialize it
  711. if (OK(hr = pObj->Init(pClass)))
  712. {
  713. // return the object and its controlling unknown
  714. *ppUnkCtrl = &pObj->_PrivUnk;
  715. *ppObj = gpCtrlThis = pObj;
  716. }
  717. }
  718. return hr;
  719. }
  720. //+---------------------------------------------------------------
  721. //
  722. // Member: SRCtrl::SRCtrl, protected
  723. //
  724. // Synopsis: Constructor for the SRCtrl class
  725. //
  726. // Arguments: [pUnkOuter] -- the controlling unknown or NULL if we are
  727. // not being created as part of an aggregate
  728. //
  729. // Notes: This is the first part of a two-stage construction process.
  730. // The second part is in the Init method. Use the static
  731. // Create method to properly instantiate an SRCtrl object
  732. //
  733. //---------------------------------------------------------------
  734. #pragma warning(disable:4355) // `this' argument to base-member init. list.
  735. SRCtrl::SRCtrl(LPUNKNOWN pUnkOuter):
  736. _PrivUnk(this) // the controlling unknown holds a pointer to the object
  737. {
  738. static SrvrCtrl::LPFNDOVERB VerbFuncs[] =
  739. {
  740. &SrvrCtrl::DoInPlaceActivate, // OLEIVERB_INPLACEACTIVATE
  741. &SrvrCtrl::DoUIActivate, // OLEIVERB_UIACTIVATE
  742. &SrvrCtrl::DoHide, // OLEIVERB_HIDE
  743. &SRCtrl::DoOpen, // OLEIVERB_OPEN
  744. &SRCtrl::DoShow, // OLEIVERB_SHOW
  745. &SRCtrl::DoPlay, // Play, OLEIVERB_PRIMARY
  746. &SRCtrl::DoOpen, // Edit
  747. &SRCtrl::DoOpen // Open
  748. };
  749. _pUnkOuter = (pUnkOuter != NULL) ? pUnkOuter : (LPUNKNOWN)&_PrivUnk;
  750. _pDVCtrlUnk = NULL;
  751. _pIPCtrlUnk = NULL;
  752. _pVerbFuncs = VerbFuncs;
  753. _cLock = 0;
  754. _fLoaded = FALSE;
  755. }
  756. #pragma warning(default:4355)
  757. //+---------------------------------------------------------------
  758. //
  759. // Member: SRCtrl::DoPlay, public, static
  760. //
  761. // Synopsis: Implementation of the play verb.
  762. // This verb results in a transition to the open state.
  763. //
  764. //---------------------------------------------------------------
  765. HRESULT
  766. SRCtrl::DoPlay(LPVOID pv,
  767. LONG iVerb,
  768. LPMSG lpmsg,
  769. LPOLECLIENTSITE pActiveSite,
  770. LONG lindex,
  771. HWND hwndParent,
  772. LPCRECT lprcPosRect)
  773. {
  774. DOUT(TEXT("SrvrCtrl::DoPlay\r\n"));
  775. LPSRCTRL pCtrl = (LPSRCTRL)pv;
  776. BOOL fClose = FALSE;
  777. /* if we are already open, just play it.
  778. * if we aren't, play it and close.
  779. */
  780. if (!gfStandalone)
  781. {
  782. fClose = pCtrl->State() != OS_OPEN;
  783. /* We've never been loaded. This means someone (Project 4.0) is
  784. * calling our primary verb incorrectly on Insert->Object. They
  785. * really want us to DoOpen.
  786. */
  787. if (!pCtrl->IsLoaded())
  788. return (pCtrl->DoOpen(pv, iVerb, lpmsg, pActiveSite, lindex,
  789. hwndParent,lprcPosRect));
  790. }
  791. if (IsWindowVisible(ghwndApp))
  792. SetForegroundWindow(ghwndApp);
  793. AppPlay(fClose);
  794. return pCtrl->TransitionTo(OS_OPEN);
  795. }
  796. //+---------------------------------------------------------------
  797. //
  798. // Member: SRCtrl::DoShow, public
  799. //
  800. // Synopsis: Implementation of the standard verb OLEIVERB_SHOW.
  801. // This verb results in a transition to the open state.
  802. //
  803. //---------------------------------------------------------------
  804. HRESULT
  805. SRCtrl::DoShow(LPVOID pv,
  806. LONG iVerb,
  807. LPMSG lpmsg,
  808. LPOLECLIENTSITE pActiveSite,
  809. LONG lindex,
  810. HWND hwndParent,
  811. LPCRECT lprcPosRect)
  812. {
  813. DOUT(TEXT("SrvrCtrl::DoShow\r\n"));
  814. LPSRCTRL pCtrl = (LPSRCTRL)pv;
  815. if(pCtrl->State() == OS_OPEN)
  816. {
  817. HWND hwnd = NULL;
  818. if(pCtrl->_pInPlace)
  819. pCtrl->_pInPlace->GetWindow(&hwnd);
  820. if(hwnd != NULL)
  821. SetForegroundWindow(hwnd);
  822. }
  823. WriteObjectIfEmpty();
  824. return pCtrl->TransitionTo(OS_OPEN);
  825. }
  826. //+---------------------------------------------------------------
  827. //
  828. // Member: SRCtrl::DoOpen, public
  829. //
  830. // Synopsis: Implementation of the standard verb OLEIVERB_OPEN.
  831. // This verb results in a transition to the open state.
  832. //
  833. //---------------------------------------------------------------
  834. HRESULT
  835. SRCtrl::DoOpen(LPVOID pv,
  836. LONG iVerb,
  837. LPMSG lpmsg,
  838. LPOLECLIENTSITE pActiveSite,
  839. LONG lindex,
  840. HWND hwndParent,
  841. LPCRECT lprcPosRect)
  842. {
  843. DOUT(TEXT("SRCtrl::DoOpen\r\n"));
  844. LPSRVRCTRL pCtrl = (LPSRVRCTRL)pv;
  845. if(pCtrl->State() == OS_OPEN)
  846. {
  847. HWND hwnd = NULL;
  848. if(pCtrl->_pInPlace)
  849. pCtrl->_pInPlace->GetWindow(&hwnd);
  850. if(hwnd != NULL)
  851. SetForegroundWindow(hwnd);
  852. if (IsWindowVisible(ghwndApp))
  853. SetForegroundWindow(ghwndApp);
  854. }
  855. return pCtrl->TransitionTo(OS_OPEN);
  856. }
  857. //+---------------------------------------------------------------
  858. //
  859. // Member: SRCtrl::Init, protected
  860. //
  861. // Synopsis: Initializes an SRCtrl object
  862. //
  863. // Arguments: [pClass] -- the class descriptor
  864. //
  865. // Returns: SUCCESS iff the class could be initialized
  866. //
  867. // Notes: This is the second part of a two-stage construction
  868. // process. Use the static Create method to properly
  869. // instantiate an SRCtrl object.
  870. //
  871. //---------------------------------------------------------------
  872. HRESULT
  873. SRCtrl::Init(LPCLASSDESCRIPTOR pClass)
  874. {
  875. HRESULT hr = NOERROR;
  876. if (OK(hr = SrvrCtrl::Init(pClass)))
  877. {
  878. LPSRDV pSRDV;
  879. LPUNKNOWN pDVCtrlUnk;
  880. if (OK(hr = SRDV::Create(this, pClass, &pDVCtrlUnk, &pSRDV)))
  881. {
  882. LPSRINPLACE pSRInPlace;
  883. LPUNKNOWN pIPCtrlUnk;
  884. if (OK(hr = SRInPlace::Create(this,
  885. pClass,
  886. &pIPCtrlUnk,
  887. &pSRInPlace)))
  888. {
  889. _pDVCtrlUnk = pDVCtrlUnk;
  890. _pDV = pSRDV;
  891. _pIPCtrlUnk = pIPCtrlUnk;
  892. _pInPlace = pSRInPlace;
  893. pDVCtrlUnk->AddRef();
  894. // This was in paintbrush. I expect it's because standalone objects don't
  895. // do state transitions correctly
  896. // Lock();
  897. }
  898. pDVCtrlUnk->Release(); // on failure this will free DV subobject
  899. }
  900. }
  901. return hr;
  902. }
  903. //+---------------------------------------------------------------
  904. //
  905. // Member: SRCtrl::~SRCtrl
  906. //
  907. // Synopsis: Destructor for the SRCtrl class
  908. //
  909. //---------------------------------------------------------------
  910. SRCtrl::~SRCtrl(void)
  911. {
  912. DOUT(TEXT("SRCtrl::~SRCtrl\r\n"));
  913. if(_state > OS_PASSIVE)
  914. {
  915. // make sure we are back to the loaded state
  916. TransitionTo(OS_LOADED);
  917. }
  918. //
  919. // If we are not being shut down by the user (via FILE:EXIT etc.,)
  920. // then we must cause app shutdown here...
  921. //
  922. // This AddRef is necessary to prevent a reentrancy within
  923. // TerminateServer because it does a QI and Release to get a storage
  924. // if an uncommitted object is on the clipboard at exit time.
  925. AddRef();
  926. if (!gfUserClose && !gfTerminating)
  927. TerminateServer();
  928. if (gpFileMoniker != NULL)
  929. gpFileMoniker->Release();
  930. //
  931. // release the controlling unknowns of our subobjects, which should
  932. // free them...
  933. //
  934. DOUT(TEXT("~SRCtrl: DV->Release\r\n"));
  935. if (_pDVCtrlUnk != NULL)
  936. {
  937. _pDVCtrlUnk->Release();
  938. }
  939. DOUT(TEXT("~SRCtrl: IP->Release\r\n"));
  940. if (_pIPCtrlUnk != NULL)
  941. {
  942. _pIPCtrlUnk->Release();
  943. }
  944. gpCtrlThis = NULL;
  945. }
  946. // the standard IUnknown methods all delegate to the controlling unknown.
  947. IMPLEMENT_DELEGATING_IUNKNOWN(SRCtrl)
  948. IMPLEMENT_PRIVATE_IUNKNOWN(SRCtrl)
  949. //+---------------------------------------------------------------
  950. //
  951. // Member: SRCtrl::PrivateUnknown::QueryInterface
  952. //
  953. // Synopsis: QueryInterface on our controlling unknown
  954. //
  955. //---------------------------------------------------------------
  956. STDMETHODIMP
  957. SRCtrl::PrivateUnknown::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  958. {
  959. #if DBG
  960. TCHAR achBuffer[256];
  961. wsprintf(achBuffer,
  962. TEXT("SRCtrl::PrivateUnknown::QueryInterface (%lx)\r\n"),
  963. riid.Data1);
  964. DOUT(achBuffer);
  965. #endif
  966. if (IsEqualIID(riid, IID_IUnknown))
  967. {
  968. *ppv = (void FAR *)this;
  969. }
  970. else if (IsEqualIID(riid, IID_IOleObject))
  971. {
  972. *ppv = (void FAR *) (LPOLEOBJECT)_pSRCtrl;
  973. }
  974. else // try each of our delegate subobjects until one succeeds
  975. {
  976. HRESULT hr;
  977. if (!OK(hr = _pSRCtrl->_pDVCtrlUnk->QueryInterface(riid, ppv)))
  978. hr = _pSRCtrl->_pIPCtrlUnk->QueryInterface(riid, ppv);
  979. return hr;
  980. }
  981. //
  982. // Important: we must addref on the pointer that we are returning,
  983. // because that pointer is what will be released!
  984. //
  985. ((IUnknown FAR*) *ppv)->AddRef();
  986. return NOERROR;
  987. }
  988. //+---------------------------------------------------------------
  989. //
  990. // Member: SRCtrl::GetMoniker
  991. //
  992. // Synopsis: Method of IOleObject interface
  993. //
  994. // Notes: Our overide creates a file moniker for the Standalone case
  995. //
  996. //---------------------------------------------------------------
  997. STDMETHODIMP
  998. SRCtrl::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, LPMONIKER FAR* ppmk)
  999. {
  1000. DOUT(TEXT("SRCtrl::GetMoniker\r\n"));
  1001. HRESULT hr = E_INVALIDARG;
  1002. if (ppmk == NULL)
  1003. {
  1004. DOUT(TEXT("SRCtrl::GetMoniker E_INVALIDARG\r\n"));
  1005. return hr;
  1006. }
  1007. *ppmk = NULL; // set out parameters to NULL
  1008. if(gfStandalone || gfLinked) // set by FlagEmbededObject()
  1009. {
  1010. if(gpFileMoniker != NULL)
  1011. {
  1012. *ppmk = gpFileMoniker;
  1013. gpFileMoniker->AddRef();
  1014. hr = NOERROR;
  1015. }
  1016. else
  1017. {
  1018. #if !defined(UNICODE) && !defined(OLE2ANSI)
  1019. LPOLESTR lpLinkFilename = ConvertMBToOLESTR(gachLinkFilename, -1);
  1020. if((hr = CreateFileMoniker(lpLinkFilename, &gpFileMoniker)) == NOERROR)
  1021. {
  1022. gpFileMoniker->AddRef(); //because we are keeping this pointer
  1023. *ppmk = gpFileMoniker;
  1024. RegisterAsRunning((LPUNKNOWN)this, *ppmk, &gdwRegROT);
  1025. }
  1026. else
  1027. {
  1028. DOUT(TEXT("SRCtrl::GetMoniker CreateFileMoniker FAILED!\r\n"));
  1029. }
  1030. TaskFreeMem(lpLinkFilename);
  1031. #else
  1032. if((hr = CreateFileMoniker(gachLinkFilename, &gpFileMoniker)) == NOERROR)
  1033. {
  1034. gpFileMoniker->AddRef(); //because we are keeping this pointer
  1035. *ppmk = gpFileMoniker;
  1036. RegisterAsRunning((LPUNKNOWN)this, *ppmk, &gdwRegROT);
  1037. }
  1038. else
  1039. {
  1040. DOUT(TEXT("SRCtrl::GetMoniker CreateFileMoniker FAILED!\r\n"));
  1041. }
  1042. #endif
  1043. }
  1044. }
  1045. else
  1046. {
  1047. return SrvrCtrl::GetMoniker(dwAssign, dwWhichMoniker, ppmk);
  1048. }
  1049. return hr;
  1050. }
  1051. //+---------------------------------------------------------------
  1052. //
  1053. // Member: SRCtrl::IsUpToDate
  1054. //
  1055. // Synopsis: Method of IOleObject interface
  1056. //
  1057. // Notes: Return S_FALSE if we are dirty (not up-to-date)
  1058. //
  1059. //---------------------------------------------------------------
  1060. STDMETHODIMP
  1061. SRCtrl::IsUpToDate(void)
  1062. {
  1063. DOUT(TEXT("SRCtrl::IsUpToDate\r\n"));
  1064. return gfDirty ? S_FALSE : S_OK;
  1065. }
  1066. #if 0
  1067. //+---------------------------------------------------------------
  1068. //
  1069. // Member: SRCtrl::GetHostNames, public
  1070. //
  1071. // Synopsis: Returns any host names set by the container
  1072. //
  1073. // Arguments: [plpstrCntrApp] -- location for string indicating the top-level
  1074. // container application.
  1075. // [plpstrCntrObj] -- location for string indicating the top-level
  1076. // document.
  1077. //
  1078. // Notes: The method makes available the strings originally set by the
  1079. // container using IOleObject::SetHostNames. These strings are
  1080. // used in the title bar of an open-edited object. It is useful
  1081. // to containers that need to forward this information to their
  1082. // embeddings. The returned strings are allocated using the
  1083. // standard task allocator and should be freed appropriately by
  1084. // the caller.
  1085. //
  1086. //---------------------------------------------------------------
  1087. void
  1088. SRCtrl::GetHostNames(LPTSTR FAR* plpstrCntrApp, LPTSTR FAR* plpstrCntrObj)
  1089. {
  1090. if (_lpstrCntrApp != NULL)
  1091. {
  1092. TaskAllocString(_lpstrCntrApp, plpstrCntrApp);
  1093. }
  1094. else
  1095. {
  1096. *plpstrCntrApp = NULL;
  1097. }
  1098. if (_lpstrCntrObj != NULL)
  1099. {
  1100. TaskAllocString(_lpstrCntrObj, plpstrCntrObj);
  1101. }
  1102. else
  1103. {
  1104. *plpstrCntrObj = NULL;
  1105. }
  1106. }
  1107. #endif
  1108. void
  1109. SRCtrl::Lock(void)
  1110. {
  1111. ++_cLock;
  1112. #if DBG
  1113. TCHAR achBuffer[256];
  1114. wsprintf(achBuffer, TEXT("\\\\SRCtrl::Lock (%d)\r\n"), _cLock);
  1115. DOUT(achBuffer);
  1116. #endif
  1117. CoLockObjectExternal((LPUNKNOWN)&_PrivUnk, TRUE, TRUE);
  1118. }
  1119. void
  1120. SRCtrl::UnLock(void)
  1121. {
  1122. --_cLock;
  1123. #if DBG
  1124. TCHAR achBuffer[256];
  1125. wsprintf(achBuffer, TEXT("\\\\SRCtrl::UnLock (%d)\r\n"), _cLock);
  1126. DOUT(achBuffer);
  1127. #endif
  1128. Assert(_cLock >= 0);
  1129. CoLockObjectExternal((LPUNKNOWN)&_PrivUnk, FALSE, TRUE);
  1130. }
  1131. BOOL
  1132. SRCtrl::IsLoaded(void)
  1133. {
  1134. return _fLoaded;
  1135. }
  1136. void
  1137. SRCtrl::MarkAsLoaded(void)
  1138. {
  1139. _fLoaded = TRUE;
  1140. }
  1141. HRESULT
  1142. SRCtrl::PassiveToLoaded()
  1143. {
  1144. DOUT(TEXT("=== SRCtrl::PassiveToLoaded\r\n"));
  1145. Lock();
  1146. return SrvrCtrl::PassiveToLoaded();
  1147. }
  1148. HRESULT
  1149. SRCtrl::LoadedToPassive()
  1150. {
  1151. DOUT(TEXT("=== SRCtrl::LoadedToPassive\r\n"));
  1152. HRESULT hr = SrvrCtrl::LoadedToPassive();
  1153. UnLock();
  1154. return hr;
  1155. }
  1156. //+---------------------------------------------------------------
  1157. //
  1158. // Member: SRCtrl::RunningToOpened
  1159. //
  1160. // Synopsis: Effects the running to open state transition
  1161. //
  1162. // Returns: SUCCESS in all but catastrophic circumstances
  1163. //
  1164. //---------------------------------------------------------------
  1165. HRESULT
  1166. SRCtrl::RunningToOpened()
  1167. {
  1168. DOUT(TEXT("SRCtrl::RunningToOpened\r\n"));
  1169. // ... show open editing window
  1170. if (!gfStandalone)
  1171. {
  1172. FixMenus();
  1173. if (gfShowWhilePlaying)
  1174. ShowWindow(ghwndApp, SW_SHOW | SW_SHOWNORMAL);
  1175. if (IsWindowVisible(ghwndApp))
  1176. SetForegroundWindow(ghwndApp);
  1177. }
  1178. OleNoteObjectVisible((LPUNKNOWN)&_PrivUnk, TRUE);
  1179. //
  1180. // notify our container so it can hatch-shade our object
  1181. // indicating that it is open-edited...
  1182. //
  1183. if (_pClientSite != NULL)
  1184. _pClientSite->OnShowWindow(TRUE);
  1185. SetFocus(ghwndApp);
  1186. return NOERROR;
  1187. }
  1188. //+---------------------------------------------------------------
  1189. //
  1190. // Member: SRCtrl::OpenedToRunning
  1191. //
  1192. // Synopsis: Effects the open to running state transition
  1193. //
  1194. // Returns: SUCCESS in all but catastrophic circumstances
  1195. //
  1196. //---------------------------------------------------------------
  1197. HRESULT
  1198. SRCtrl::OpenedToRunning()
  1199. {
  1200. DOUT(TEXT("SRCtrl::OpenedToRunning\r\n"));
  1201. //
  1202. // If we are transitioning to a standalone app, we don't want the app
  1203. // to disappear.
  1204. //
  1205. ShowWindow(ghwndApp,SW_HIDE);
  1206. HRESULT hr = SrvrCtrl::OpenedToRunning();
  1207. OleNoteObjectVisible((LPUNKNOWN)&_PrivUnk, FALSE);
  1208. return hr;
  1209. }
  1210. const OLECHAR szContentsStrm[] = OLETEXT("contents");
  1211. const OLECHAR szOLE1Strm[] = OLETEXT("\1Ole10Native");
  1212. //---------------------------------------------------------------
  1213. //
  1214. // The Format Tables
  1215. //
  1216. //---------------------------------------------------------------
  1217. //
  1218. // GetData format information
  1219. // note: the LINKSRCDESCRIPTOR and OBJECTDESCRIPTOR are identical structures
  1220. // so we use the OBJECTDESCRIPTOR get/set fns for both.
  1221. //
  1222. static FORMATETC SRGetFormatEtc[] =
  1223. {// { cfFormat, ptd, dwAspect, lindex, tymed },
  1224. #if 0
  1225. // NTBUG # 11225: CorelDraw 5.0 does not like our implementation of
  1226. // CF_EMBEDDEDOBJECT and cannot save our data in the
  1227. // Insert->Object->CreateFromFile scenerio
  1228. { (unsigned short)-OCF_EMBEDDEDOBJECT, NULL, DVASPECT_CONTENT, -1L, TYMED_ISTORAGE },
  1229. #else
  1230. { (unsigned short)-OCF_EMBEDSOURCE, NULL, DVASPECT_CONTENT, -1L, TYMED_ISTORAGE },
  1231. #endif
  1232. { CF_METAFILEPICT, DVTARGETIGNORE, DVASPECT_CONTENT, -1L, TYMED_MFPICT },
  1233. { CF_DIB, DVTARGETIGNORE, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  1234. { (unsigned short)-OCF_OBJECTDESCRIPTOR, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  1235. { (unsigned short)-OCF_LINKSRCDESCRIPTOR, NULL, DVASPECT_CONTENT, -1L, TYMED_HGLOBAL },
  1236. { (unsigned short)-OCF_LINKSOURCE, NULL, DVASPECT_CONTENT, -1L, TYMED_ISTREAM }
  1237. };
  1238. static SrvrDV::LPFNGETDATA SRGetFormatFuncs[] =
  1239. { &SRDV::GetEMBEDDEDOBJECT,
  1240. &SRDV::GetMETAFILEPICT,
  1241. &SRDV::GetDIB,
  1242. &SRDV::GetOBJECTDESCRIPTOR,
  1243. &SRDV::GetOBJECTDESCRIPTOR,
  1244. &SRDV::GetLINKSOURCE
  1245. };
  1246. //+---------------------------------------------------------------
  1247. //
  1248. // Member: SRDV::ClassInit (static)
  1249. //
  1250. // Synopsis: Initializes the SRDV class
  1251. //
  1252. // Arguments: [pClass] -- our class descriptor
  1253. //
  1254. // Returns: TRUE iff the class could be initialized successfully
  1255. //
  1256. // Notes: This method initializes the format tables in the
  1257. // class descriptor.
  1258. //
  1259. //---------------------------------------------------------------
  1260. BOOL
  1261. SRDV::ClassInit(LPCLASSDESCRIPTOR pClass)
  1262. {
  1263. // fill in the class descriptor structure with the format tables
  1264. pClass->_pGetFmtTable = SRGetFormatEtc;
  1265. pClass->_cGetFmtTable = ARRAY_SIZE(SRGetFormatEtc);
  1266. pClass->_pSetFmtTable = NULL;
  1267. pClass->_cSetFmtTable = 0;
  1268. //
  1269. // walk our format tables and complete the cfFormat field from
  1270. // the array of standard OLE clipboard formats.
  1271. //
  1272. LPFORMATETC pfe = SRGetFormatEtc;
  1273. int c = ARRAY_SIZE(SRGetFormatEtc);
  1274. for (int i = 0; i < c; i++, pfe++)
  1275. {
  1276. // if the clipformat is negative, then it really is an index into
  1277. // our table of standard OLECLIPFORMATS
  1278. int j = - (short)pfe->cfFormat;
  1279. if (j >= 0 && j <= OCF_LAST)
  1280. pfe->cfFormat = (WORD)OleClipFormat[j];
  1281. }
  1282. pfe = g_aGetFmtEtcs;
  1283. c = ARRAY_SIZE(g_aGetFmtEtcs);
  1284. for (i = 0; i < c; i++, pfe++)
  1285. {
  1286. // if the clipformat is negative, then it really is an index into
  1287. // our table of standard OLECLIPFORMATS
  1288. int j = - (short)pfe->cfFormat;
  1289. if (j >= 0 && j <= OCF_LAST)
  1290. {
  1291. pfe->cfFormat = (WORD)OleClipFormat[j];
  1292. }
  1293. }
  1294. return TRUE;
  1295. }
  1296. HRESULT
  1297. SRDV::GetDIB( LPSRVRDV pDV,
  1298. LPFORMATETC pformatetc,
  1299. LPSTGMEDIUM pmedium,
  1300. BOOL fHere)
  1301. {
  1302. HRESULT hr = NOERROR;
  1303. LPVIEWOBJECT pView = (LPVIEWOBJECT)pDV;
  1304. HANDLE hDIB;
  1305. if (!fHere)
  1306. {
  1307. // fill in the pmedium structure
  1308. pmedium->tymed = TYMED_HGLOBAL;
  1309. }
  1310. hDIB = ::GetDIB(pmedium->hGlobal);
  1311. if (hDIB)
  1312. pmedium->hGlobal = hDIB;
  1313. else
  1314. hr = E_OUTOFMEMORY;
  1315. return hr;
  1316. }
  1317. //+---------------------------------------------------------------
  1318. //
  1319. // Member: SRDV::Create, public
  1320. //
  1321. // Synopsis: Creates and initializes an SRDV object
  1322. //
  1323. // Arguments: [pCtrl] -- our control subobject
  1324. // [pClass] -- The class descriptor
  1325. // [ppUnkCtrl] -- Where we return our controlling unknown
  1326. // [ppObj] -- where the created object is returned
  1327. //
  1328. // Returns: Success if the object could be successfully created and
  1329. // initialized.
  1330. //
  1331. //---------------------------------------------------------------
  1332. HRESULT
  1333. SRDV::Create(LPSRCTRL pCtrl,
  1334. LPCLASSDESCRIPTOR pClass,
  1335. LPUNKNOWN FAR* ppUnkCtrl,
  1336. LPSRDV FAR* ppObj)
  1337. {
  1338. // set out parameters to NULL
  1339. *ppUnkCtrl = NULL;
  1340. *ppObj = NULL;
  1341. // create an object
  1342. HRESULT hr;
  1343. LPSRDV pObj;
  1344. pObj = new SRDV((LPUNKNOWN)(LPOLEOBJECT)pCtrl);
  1345. if (pObj == NULL)
  1346. {
  1347. hr = E_OUTOFMEMORY;
  1348. }
  1349. else
  1350. {
  1351. // initialize it
  1352. if (OK(hr = pObj->Init(pCtrl, pClass)))
  1353. {
  1354. // return the object and its controlling unknown
  1355. *ppUnkCtrl = &pObj->_PrivUnk;
  1356. *ppObj = pObj;
  1357. }
  1358. else
  1359. {
  1360. pObj->_PrivUnk.Release(); //hari-kari
  1361. }
  1362. }
  1363. return hr;
  1364. }
  1365. //+---------------------------------------------------------------
  1366. //
  1367. // Member: SRDV::SRDV, protected
  1368. //
  1369. // Synopsis: Constructor for the SRDV class
  1370. //
  1371. // Arguments: [pUnkOuter] -- the controlling unknown. This is either
  1372. // a SRCtrl subobject or NULL we are being
  1373. // created as a transfer object.
  1374. //
  1375. // Notes: This is the first part of a two-stage construction process.
  1376. // The second part is in the Init method. Use the static
  1377. // Create method to properly instantiate an SRDV object
  1378. //
  1379. //---------------------------------------------------------------
  1380. #pragma warning(disable:4355) // `this' argument to base-member init. list.
  1381. SRDV::SRDV(LPUNKNOWN pUnkOuter):
  1382. _PrivUnk(this) // the controlling unknown holds a pointer to the object
  1383. {
  1384. _pUnkOuter = (pUnkOuter != NULL) ? pUnkOuter : (LPUNKNOWN)&_PrivUnk;
  1385. _pGetFuncs = SRGetFormatFuncs;
  1386. _pSetFuncs = NULL;
  1387. _sizel = _header._sizel;
  1388. }
  1389. #pragma warning(default:4355)
  1390. //+---------------------------------------------------------------
  1391. //
  1392. // Member: SRDV::Init, protected
  1393. //
  1394. // Synopsis: Initializes an SRDV object
  1395. //
  1396. // Arguments: [pCtrl] -- our controlling SRCtrl subobject
  1397. // [pClass] -- the class descriptor
  1398. //
  1399. // Returns: SUCCESS iff the class could be initialized
  1400. //
  1401. // Notes: This is the second part of a two-stage construction
  1402. // process. Use the static Create method to properly
  1403. // instantiate an SRDV object.
  1404. //
  1405. //---------------------------------------------------------------
  1406. HRESULT
  1407. SRDV::Init(LPSRCTRL pCtrl, LPCLASSDESCRIPTOR pClass)
  1408. {
  1409. HRESULT hr = SrvrDV::Init(pClass, pCtrl);
  1410. //
  1411. //do our own xtra init here...
  1412. //
  1413. return hr;
  1414. }
  1415. //+---------------------------------------------------------------
  1416. //
  1417. // Member: SRDV::~SRDV
  1418. //
  1419. // Synopsis: Destructor for the SRDV class
  1420. //
  1421. //---------------------------------------------------------------
  1422. SRDV::~SRDV(void)
  1423. {
  1424. //
  1425. // TODO: check on anything we may have to clean up here...
  1426. //
  1427. }
  1428. // the standard IUnknown methods all delegate to a controlling unknown.
  1429. IMPLEMENT_DELEGATING_IUNKNOWN(SRDV)
  1430. IMPLEMENT_PRIVATE_IUNKNOWN(SRDV)
  1431. //+---------------------------------------------------------------
  1432. //
  1433. // Member: SRDV::PrivateUnknown::QueryInterface
  1434. //
  1435. // Synopsis: QueryInterface on our controlling unknown
  1436. //
  1437. //---------------------------------------------------------------
  1438. STDMETHODIMP
  1439. SRDV::PrivateUnknown::QueryInterface (REFIID riid, LPVOID FAR* ppv)
  1440. {
  1441. if (IsEqualIID(riid,IID_IUnknown))
  1442. {
  1443. *ppv = (LPVOID)this;
  1444. }
  1445. else if (IsEqualIID(riid,IID_IDataObject))
  1446. {
  1447. *ppv = (LPVOID)(LPDATAOBJECT)_pSRDV;
  1448. }
  1449. else if (IsEqualIID(riid,IID_IViewObject))
  1450. {
  1451. *ppv = (LPVOID)(LPVIEWOBJECT)_pSRDV;
  1452. }
  1453. else if (IsEqualIID(riid,IID_IPersist))
  1454. {
  1455. //
  1456. // The standard handler wants this
  1457. //
  1458. *ppv = (LPVOID)(LPPERSIST)(LPPERSISTSTORAGE)_pSRDV;
  1459. }
  1460. else if (IsEqualIID(riid,IID_IPersistStorage))
  1461. {
  1462. *ppv = (LPVOID)(LPPERSISTSTORAGE)_pSRDV;
  1463. }
  1464. else if (IsEqualIID(riid,IID_IPersistFile))
  1465. {
  1466. *ppv = (LPVOID)(LPPERSISTFILE)_pSRDV;
  1467. }
  1468. else
  1469. {
  1470. *ppv = NULL;
  1471. return E_NOINTERFACE;
  1472. }
  1473. //
  1474. // Important: we must addref on the pointer that we are returning,
  1475. // because that pointer is what will be released!
  1476. //
  1477. ((IUnknown FAR*) *ppv)->AddRef();
  1478. return NOERROR;
  1479. }
  1480. //+---------------------------------------------------------------
  1481. //
  1482. // Member: SRDV::RenderContent, public
  1483. //
  1484. // Synopsis: Draws our contents into a display context
  1485. //
  1486. // Arguments: The arguments are the same as to the IViewObject::Draw method
  1487. //
  1488. // Returns: SUCCESS if the content was rendered
  1489. //
  1490. // Notes: This virtual method of the base class is called to implement
  1491. // IViewObject::Draw for the DVASPECT_CONTENT aspect.
  1492. //
  1493. //----------------------------------------------------------------
  1494. HRESULT
  1495. SRDV::RenderContent(DWORD dwDrawAspect,
  1496. LONG lindex,
  1497. void FAR* pvAspect,
  1498. DVTARGETDEVICE FAR * ptd,
  1499. HDC hicTargetDev,
  1500. HDC hdcDraw,
  1501. LPCRECTL lprectl,
  1502. LPCRECTL lprcWBounds,
  1503. BOOL (CALLBACK *pfnContinue) (ULONG_PTR),
  1504. ULONG_PTR dwContinue)
  1505. {
  1506. DOUT(TEXT("SoundRec: RenderContent\r\n"));
  1507. int x = GetSystemMetrics(SM_CXICON);
  1508. int y = GetSystemMetrics(SM_CYICON);
  1509. HDC hdc = GetDC(ghwndApp);
  1510. HDC hdcMem = CreateCompatibleDC(hdc);
  1511. HBITMAP hbm = CreateCompatibleBitmap(hdc, x, y);
  1512. HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
  1513. PatBlt(hdcMem, 0, 0, x, y, WHITENESS);
  1514. DrawIcon(hdcMem, 0, 0, ghiconApp);
  1515. StretchBlt(hdcDraw, lprectl->left, lprectl->top,
  1516. lprectl->right - lprectl->left, lprectl->bottom - lprectl->top,
  1517. hdcMem, 0, 0, x, y, SRCCOPY);
  1518. hbm = (HBITMAP)SelectObject(hdcMem, hbmOld);
  1519. if (hdcMem)
  1520. DeleteDC(hdcMem);
  1521. if (hbm)
  1522. DeleteObject(hbm);
  1523. if (hdc)
  1524. ReleaseDC(ghwndApp, hdc);
  1525. return NOERROR;
  1526. }
  1527. /*
  1528. * SRDV::Load
  1529. * Implements IPersistFile::Load
  1530. *
  1531. * Side effects: gfLinked - we know we are linked.
  1532. */
  1533. STDMETHODIMP
  1534. SRDV::Load (LPCOLESTR lpstrFile, DWORD grfMode)
  1535. {
  1536. DOUT(TEXT("SoundRec:SRDV::Load\r\n"));
  1537. #if !defined(UNICODE) && !defined(OLE2ANSI)
  1538. LPTSTR lpszFileName = ConvertOLESTRToMB(lpstrFile,-1);
  1539. FileLoad(lpszFileName);
  1540. TaskFreeMem(lpszFileName);
  1541. #else
  1542. TCHAR szFileName[256];
  1543. lstrcpy(szFileName,lpstrFile);
  1544. FileLoad(szFileName);
  1545. #endif
  1546. gfLinked = TRUE;
  1547. if (gpCtrlThis)
  1548. gpCtrlThis->MarkAsLoaded();
  1549. return ResultFromScode( S_OK );
  1550. }
  1551. //+---------------------------------------------------------------
  1552. //
  1553. // Member: LoadFromStorage
  1554. //
  1555. // Synopsis: Loads our data from a storage
  1556. //
  1557. // Arguments: [pStg] -- storage to load from
  1558. //
  1559. // Returns: SUCCESS if our native data was loaded
  1560. //
  1561. // Notes: This is a virtual method in our base class that is called
  1562. // on an IPersistStorage::Load and an IPersistFile::Load when
  1563. // the file is a docfile. We override this method to
  1564. // do our server-specific loading.
  1565. //
  1566. //----------------------------------------------------------------
  1567. HRESULT
  1568. SRDV::LoadFromStorage(LPSTORAGE pStg)
  1569. {
  1570. DOUT(TEXT("SoundRec: LoadFromStorage\r\n"));
  1571. LPSTREAM pStrm;
  1572. // Open the OLE 1 Stream.
  1573. HRESULT hr = pStg->OpenStream(szOLE1Strm, NULL, STGM_SALL,0, &pStrm);
  1574. if (OK(hr))
  1575. {
  1576. DWORD cbSize = 0L;
  1577. pStrm->Read(&cbSize, sizeof(DWORD), NULL);
  1578. if (cbSize > 0L)
  1579. {
  1580. LPBYTE lpbData = NULL;
  1581. HANDLE hData = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, cbSize);
  1582. if(hData != NULL)
  1583. {
  1584. if ((lpbData = (LPBYTE)GlobalLock(hData)) != NULL)
  1585. {
  1586. pStrm->Read(lpbData, cbSize - sizeof(DWORD), NULL);
  1587. PutNativeData(lpbData, cbSize);
  1588. GlobalUnlock(hData);
  1589. GlobalFree(hData);
  1590. if (gpCtrlThis)
  1591. gpCtrlThis->MarkAsLoaded();
  1592. }
  1593. else
  1594. {
  1595. DOUT(TEXT("!Cannot Allocate Memory\r\n"));
  1596. }
  1597. }
  1598. }
  1599. pStrm->Release();
  1600. }
  1601. else
  1602. {
  1603. // There might be, in the future this ole2 stream, also, beta
  1604. // ole objects will break without this.
  1605. hr = pStg->OpenStream(szContentsStrm, NULL, STGM_SALL,0, &pStrm);
  1606. if (OK(hr))
  1607. {
  1608. // Read the whole contents stream into memory and use that as a stream
  1609. // to do our bits and pieces reads.
  1610. pStrm = ConvertToMemoryStream(pStrm);
  1611. hr = _header.Read(pStrm);
  1612. if (OK(hr))
  1613. {
  1614. _sizel = _header._sizel;
  1615. if(_header._dwNative > 0)
  1616. {
  1617. //
  1618. //TODO: this code needs to be optimized. It is bad to create
  1619. // three redundant copies of the wave data! At a minimum,
  1620. // the ReadWaveFile (file.c) function should get a
  1621. // companion MMIOProc capable of reading directly from
  1622. // the stream...
  1623. //
  1624. LPBYTE lpbData = NULL;
  1625. HANDLE hData = GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT, _header._dwNative);
  1626. if(hData != NULL)
  1627. {
  1628. if ((lpbData = (LPBYTE)GlobalLock(hData)) != NULL)
  1629. {
  1630. pStrm->Read(lpbData, _header._dwNative, NULL);
  1631. PutNativeData(lpbData, _header._dwNative);
  1632. GlobalUnlock(hData);
  1633. GlobalFree(hData);
  1634. if (gpCtrlThis)
  1635. gpCtrlThis->MarkAsLoaded();
  1636. }
  1637. }
  1638. else
  1639. {
  1640. DOUT(TEXT("!Cannot Allocate Memory\r\n"));
  1641. }
  1642. }
  1643. }
  1644. pStrm->Release();
  1645. }
  1646. else
  1647. {
  1648. DOUT(TEXT("!Cannot Open Stream\r\n"));
  1649. }
  1650. }
  1651. return hr;
  1652. }
  1653. //+---------------------------------------------------------------
  1654. //
  1655. // Member: SaveToStorage
  1656. //
  1657. // Synopsis: Saves our data to a storage
  1658. //
  1659. // Arguments: [pStg] -- storage to save to
  1660. // [fSameAsLoad] -- flag indicating whether this is the same
  1661. // storage that we originally loaded from
  1662. //
  1663. // Returns: SUCCESS if our native data was saved
  1664. //
  1665. // Notes: This is a virtual method in our base class that is called
  1666. // on an IPersistStorage::Save and IPersistFile::Save when the
  1667. // file is a docfile. We override this method to
  1668. // do our server-specific saving.
  1669. //
  1670. //----------------------------------------------------------------
  1671. HRESULT
  1672. SRDV::SaveToStorage(LPSTORAGE pStg, BOOL fSameAsLoad)
  1673. {
  1674. DOUT(TEXT("SoundRec: SaveToStorage\r\n"));
  1675. HRESULT hr;
  1676. // Mark our storage as OLE1
  1677. if (!OK(hr = WriteClassStg(pStg, CLSID_OLE1SOUNDREC)))
  1678. return hr;
  1679. // open or create the native data stream and write our native data
  1680. LPSTREAM pStrm;
  1681. hr = pStg->CreateStream(szOLE1Strm,
  1682. STGM_SALL | STGM_CREATE,
  1683. 0L,
  1684. 0L,
  1685. &pStrm);
  1686. if (!OK(hr))
  1687. return hr;
  1688. if (OK(hr))
  1689. {
  1690. HANDLE hNative = GetNativeData();
  1691. DWORD cbSize;
  1692. if (hNative != NULL && (cbSize = (DWORD)GlobalSize(hNative)) > 0)
  1693. {
  1694. hr = pStrm->Write(&cbSize, sizeof(cbSize), NULL);
  1695. if (OK(hr))
  1696. {
  1697. LPBYTE pNative = (LPBYTE)GlobalLock(hNative);
  1698. if(pNative != NULL)
  1699. {
  1700. hr = pStrm->Write(pNative, cbSize, NULL);
  1701. GlobalUnlock(hNative);
  1702. }
  1703. }
  1704. }
  1705. if (hNative)
  1706. GlobalFree(hNative);
  1707. }
  1708. pStrm->Release();
  1709. #ifdef OLE2ONLY
  1710. hr = pStg->CreateStream(szContentsStrm,
  1711. STGM_SALL | STGM_CREATE,
  1712. 0L,
  1713. 0L,
  1714. &pStrm);
  1715. if (OK(hr))
  1716. {
  1717. // update the members that may have changed
  1718. _header._sizel = _sizel;
  1719. HANDLE hNative = GetNativeData();
  1720. _header._dwNative = GlobalSize(hNative);
  1721. hr = _header.Write(pStrm);
  1722. if (OK(hr))
  1723. {
  1724. if(_header._dwNative > 0)
  1725. {
  1726. LPBYTE pNative = (LPBYTE)GlobalLock(hNative);
  1727. if(pNative != NULL)
  1728. {
  1729. hr = pStrm->Write(pNative, _header._dwNative, NULL);
  1730. GlobalUnlock(hNative);
  1731. }
  1732. }
  1733. }
  1734. GlobalFree(hNative);
  1735. pStrm->Release();
  1736. }
  1737. #endif
  1738. return hr;
  1739. }
  1740. #ifdef WE_SUPPORT_INPLACE
  1741. //+---------------------------------------------------------------
  1742. //
  1743. // Member: SRCtrl::RunningToInPlace
  1744. //
  1745. // Synopsis: Effects the running to inplace-active state transition
  1746. //
  1747. // Returns: SUCCESS if the object results in the in-place state
  1748. //
  1749. //---------------------------------------------------------------
  1750. HRESULT
  1751. SRCtrl::RunningToInPlace(void)
  1752. {
  1753. return SrvrCtrl::RunningToInPlace();
  1754. }
  1755. //+---------------------------------------------------------------
  1756. //
  1757. // Member: SRCtrl::InPlaceToRunning
  1758. //
  1759. // Synopsis: Effects the inplace-active to running state transition
  1760. //
  1761. // Returns: SUCCESS in all but catastrophic circumstances
  1762. //
  1763. //---------------------------------------------------------------
  1764. HRESULT
  1765. SRCtrl::InPlaceToRunning(void)
  1766. {
  1767. return SrvrCtrl::InPlaceToRunning();
  1768. }
  1769. //+---------------------------------------------------------------
  1770. //
  1771. // Member: SRCtrl::UIActiveToInPlace
  1772. //
  1773. // Synopsis: Effects the U.I. active to inplace-active state transition
  1774. //
  1775. // Returns: SUCCESS in all but catastrophic circumstances
  1776. //
  1777. //---------------------------------------------------------------
  1778. HRESULT
  1779. SRCtrl::UIActiveToInPlace(void)
  1780. {
  1781. return SrvrCtrl::UIActiveToInPlace();
  1782. }
  1783. #endif // WE_SUPPORT_INPLACE
  1784. //+---------------------------------------------------------------
  1785. //
  1786. // Member: SRInPlace::ClassInit (static)
  1787. //
  1788. // Synopsis: Load any static resources
  1789. //
  1790. // Arguments: [pClass] -- an initialized ClassDescriptor
  1791. //
  1792. // Returns: TRUE iff window class sucesfully registered
  1793. //
  1794. //---------------------------------------------------------------
  1795. BOOL
  1796. SRInPlace::ClassInit(LPCLASSDESCRIPTOR pClass)
  1797. {
  1798. HINSTANCE hinst = pClass->_hinst;
  1799. return TRUE;
  1800. }
  1801. //+---------------------------------------------------------------
  1802. //
  1803. // Member: SRInPlace::Create (static)
  1804. //
  1805. // Synopsis: Create a new, fully initialize sub-object
  1806. //
  1807. // Arguments: [pSRCtrl] -- pointer to control we are a part of
  1808. // [pClass] -- pointer to initialized class descriptor
  1809. // [ppUnkCtrl] -- (out parameter) pObj's controlling unknown
  1810. // [ppObj] -- (out parameter) the new sub-object
  1811. //
  1812. // Returns: NOERROR iff sucessful
  1813. //
  1814. //---------------------------------------------------------------
  1815. HRESULT
  1816. SRInPlace::Create( LPSRCTRL pSRCtrl,
  1817. LPCLASSDESCRIPTOR pClass,
  1818. LPUNKNOWN FAR* ppUnkCtrl,
  1819. LPSRINPLACE FAR* ppObj)
  1820. {
  1821. // set out parameters to NULL
  1822. *ppUnkCtrl = NULL;
  1823. *ppObj = NULL;
  1824. // create an object
  1825. HRESULT hr;
  1826. LPSRINPLACE pObj;
  1827. pObj = new SRInPlace((LPUNKNOWN)(LPOLEOBJECT)pSRCtrl);
  1828. if (pObj == NULL)
  1829. {
  1830. hr = E_OUTOFMEMORY;
  1831. }
  1832. else
  1833. {
  1834. // initialize it
  1835. if (OK(hr = pObj->Init(pSRCtrl, pClass)))
  1836. {
  1837. // return the object and its controlling unknown
  1838. *ppUnkCtrl = &pObj->_PrivUnk;
  1839. *ppObj = pObj;
  1840. }
  1841. else
  1842. {
  1843. pObj->_PrivUnk.Release(); //hari-kari
  1844. }
  1845. }
  1846. if(OK(hr))
  1847. {
  1848. hr = NOERROR;
  1849. }
  1850. return hr;
  1851. }
  1852. //+---------------------------------------------------------------
  1853. //
  1854. // Member: SRInPlace::SRInPlace
  1855. //
  1856. // Synopsis: Construct a new IP sub-object
  1857. //
  1858. // Arguments: [pUnkOuter] -- Unknown to aggregate with
  1859. //
  1860. //---------------------------------------------------------------
  1861. #pragma warning(disable:4355) // `this' argument to base-member init. list.
  1862. SRInPlace::SRInPlace(LPUNKNOWN pUnkOuter):
  1863. _PrivUnk(this) // controlling unknown holds a pointer to us
  1864. {
  1865. _pUnkOuter = (pUnkOuter != NULL) ? pUnkOuter : (LPUNKNOWN)&_PrivUnk;
  1866. }
  1867. #pragma warning(default:4355)
  1868. //+---------------------------------------------------------------
  1869. //
  1870. // Member: SRInPlace::~SRInPlace
  1871. //
  1872. // Synopsis: Destroy this sub-object
  1873. //
  1874. //---------------------------------------------------------------
  1875. SRInPlace::~SRInPlace(void)
  1876. {
  1877. }
  1878. //+---------------------------------------------------------------
  1879. //
  1880. // Member: SRInPlace::Init
  1881. //
  1882. // Synopsis: Initialize sub-object
  1883. //
  1884. // Arguments: [pSRCtrl] -- pointer to control we are a part of
  1885. // [pClass] -- pointer to an initialized class descriptor
  1886. //
  1887. // Returns: NOERROR if sucessful
  1888. //
  1889. //---------------------------------------------------------------
  1890. HRESULT
  1891. SRInPlace::Init(LPSRCTRL pSRCtrl, LPCLASSDESCRIPTOR pClass)
  1892. {
  1893. HRESULT hr = SrvrInPlace::Init(pClass, pSRCtrl);
  1894. return hr;
  1895. }
  1896. IMPLEMENT_DELEGATING_IUNKNOWN(SRInPlace)
  1897. IMPLEMENT_PRIVATE_IUNKNOWN(SRInPlace)
  1898. //+---------------------------------------------------------------
  1899. //
  1900. // Member: SRInPlace::QueryInterface, public
  1901. //
  1902. // OLE: IUnkown
  1903. //
  1904. //---------------------------------------------------------------
  1905. STDMETHODIMP
  1906. SRInPlace::PrivateUnknown::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  1907. {
  1908. if (IsEqualIID(riid,IID_IUnknown))
  1909. {
  1910. *ppv = (LPVOID)this;
  1911. }
  1912. else if (IsEqualIID(riid,IID_IOleInPlaceObject)
  1913. || IsEqualIID(riid,IID_IOleWindow))
  1914. {
  1915. *ppv = (LPVOID)(LPOLEINPLACEOBJECT)_pSRInPlace;
  1916. }
  1917. else if (IsEqualIID(riid,IID_IOleInPlaceActiveObject))
  1918. {
  1919. *ppv = (LPVOID)(LPOLEINPLACEACTIVEOBJECT)_pSRInPlace;
  1920. }
  1921. else
  1922. {
  1923. *ppv = NULL;
  1924. return E_NOINTERFACE;
  1925. }
  1926. //
  1927. // Important: we must addref on the pointer that we are returning,
  1928. // because that pointer is what will be released!
  1929. //
  1930. ((IUnknown FAR*) *ppv)->AddRef();
  1931. return NOERROR;
  1932. }
  1933. //+---------------------------------------------------------------
  1934. //
  1935. // Member: SRInPlace::AttachWin
  1936. //
  1937. // Synopsis: Create our InPlace window
  1938. //
  1939. // Arguments: [hwndParent] -- our container's hwnd
  1940. //
  1941. // Returns: hwnd of InPlace window, or NULL
  1942. //
  1943. //---------------------------------------------------------------
  1944. HWND
  1945. SRInPlace::AttachWin(HWND hwndParent)
  1946. {
  1947. return NULL;
  1948. }