Leaked source code of windows server 2003
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.

887 lines
21 KiB

  1. /*++
  2. Copyright (C) 1993-1999 Microsoft Corporation
  3. Module Name:
  4. ioleobj.cpp
  5. Abstract:
  6. Implementation of the IOleObject interface for Polyline. Some of
  7. these just pass through to the default handler which does default
  8. implementations.
  9. --*/
  10. #include "polyline.h"
  11. #include "unkhlpr.h"
  12. #include "utils.h"
  13. #include "unihelpr.h"
  14. void RegisterAsRunning(IUnknown *pUnk, IMoniker *pmk,
  15. DWORD dwFlags, LPDWORD pdwReg);
  16. /*
  17. * CImpIOleObject interface implementation
  18. */
  19. IMPLEMENT_CONTAINED_CONSTRUCTOR(CPolyline, CImpIOleObject)
  20. IMPLEMENT_CONTAINED_DESTRUCTOR(CImpIOleObject)
  21. IMPLEMENT_CONTAINED_QUERYINTERFACE(CImpIOleObject)
  22. IMPLEMENT_CONTAINED_ADDREF(CImpIOleObject)
  23. STDMETHODIMP_(ULONG) CImpIOleObject::Release(
  24. void
  25. )
  26. {
  27. --m_cRef;
  28. // Release cached site related interfaces
  29. #if 0
  30. if (m_cRef == 0) {
  31. ReleaseInterface(m_pObj->m_pIOleClientSite);
  32. ReleaseInterface(m_pObj->m_pIOleControlSite);
  33. ReleaseInterface(m_pObj->m_pIDispatchAmbients);
  34. }
  35. #endif
  36. return m_pUnkOuter->Release();
  37. }
  38. /*
  39. * CImpIOleObject::SetClientSite
  40. * CImpIOleObject::GetClientSite
  41. *
  42. * Purpose:
  43. * Manages the IOleClientSite pointer of our container.
  44. */
  45. STDMETHODIMP
  46. CImpIOleObject::SetClientSite(
  47. IN LPOLECLIENTSITE pIOleClientSite
  48. )
  49. {
  50. HRESULT hr = S_OK;
  51. if (pIOleClientSite == NULL) {
  52. return E_POINTER;
  53. }
  54. //
  55. // This is the only place where we change those cached pointers
  56. //
  57. ClearInterface(m_pObj->m_pIOleClientSite);
  58. ClearInterface(m_pObj->m_pIOleControlSite);
  59. ClearInterface(m_pObj->m_pIDispatchAmbients);
  60. m_pObj->m_pIOleClientSite = pIOleClientSite;
  61. try {
  62. if (NULL != m_pObj->m_pIOleClientSite) {
  63. LPMONIKER pmk;
  64. LPOLECONTAINER pIOleCont;
  65. m_pObj->m_pIOleClientSite->AddRef();
  66. /*
  67. * Within IRunnableObject::Run we're supposed to register
  68. * ourselves as running...however, the moniker has to come
  69. * from the container's IOleClientSite::GetMoniker. But
  70. * Run is called before SetClientSite here, so we have to
  71. * register now that we do have the client site as well
  72. * as lock the container.
  73. */
  74. hr = m_pObj->m_pIOleClientSite->GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
  75. OLEWHICHMK_OBJFULL,
  76. &pmk);
  77. if (SUCCEEDED(hr)) {
  78. RegisterAsRunning(m_pUnkOuter, pmk, 0, &m_pObj->m_dwRegROT);
  79. if ( NULL != pmk ) {
  80. pmk->Release();
  81. }
  82. }
  83. hr = m_pObj->m_pIOleClientSite->GetContainer(&pIOleCont);
  84. if (SUCCEEDED(hr)) {
  85. m_pObj->m_fLockContainer = TRUE;
  86. pIOleCont->LockContainer(TRUE);
  87. pIOleCont->Release();
  88. }
  89. /*
  90. * Go get the container's IDispatch for ambient
  91. * properties if it has one, and initilize ourself
  92. * with those properties.
  93. */
  94. hr = m_pObj->m_pIOleClientSite->QueryInterface(IID_IDispatch,
  95. (void **)&m_pObj->m_pIDispatchAmbients);
  96. if (SUCCEEDED(hr)) {
  97. m_pObj->AmbientsInitialize((ULONG)INITAMBIENT_ALL);
  98. }
  99. /*
  100. * Get the control site
  101. */
  102. hr = m_pObj->m_pIOleClientSite->QueryInterface(IID_IOleControlSite,
  103. (void **)&m_pObj->m_pIOleControlSite);
  104. }
  105. } catch (...) {
  106. hr = E_POINTER;
  107. }
  108. return hr;
  109. }
  110. STDMETHODIMP
  111. CImpIOleObject::GetClientSite(
  112. OUT LPOLECLIENTSITE *ppSite
  113. )
  114. {
  115. HRESULT hr = S_OK;
  116. if (ppSite == NULL) {
  117. return E_POINTER;
  118. }
  119. //Be sure to AddRef the new pointer you are giving away.
  120. try {
  121. *ppSite=m_pObj->m_pIOleClientSite;
  122. m_pObj->m_pIOleClientSite->AddRef();
  123. } catch (...) {
  124. hr = E_POINTER;
  125. }
  126. return hr;
  127. }
  128. /*
  129. * CImpIOleObject::SetHostNames
  130. *
  131. * Purpose:
  132. * Provides the object with names of the container application and
  133. * the object in the container to use in object user interface.
  134. *
  135. * Parameters:
  136. * pszApp LPCOLESTR of the container application.
  137. * pszObj LPCOLESTR of some name that is useful in window
  138. * titles.
  139. *
  140. * Return Value:
  141. * HRESULT NOERROR
  142. */
  143. STDMETHODIMP
  144. CImpIOleObject::SetHostNames(
  145. LPCOLESTR /* pszApp */,
  146. LPCOLESTR /* pszObj */
  147. )
  148. {
  149. return S_OK;
  150. }
  151. /*
  152. * CImpIOleObject::Close
  153. *
  154. * Purpose:
  155. * Forces the object to close down its user interface and unload.
  156. *
  157. * Parameters:
  158. * dwSaveOption DWORD describing the circumstances under which
  159. * the object is being saved and closed.
  160. *
  161. * Return Value:
  162. * HRESULT NOERROR or a general error value.
  163. */
  164. STDMETHODIMP
  165. CImpIOleObject::Close(
  166. IN DWORD dwSaveOption
  167. )
  168. {
  169. BOOL fSave=FALSE;
  170. //If object is dirty and we're asked to save, save it and close.
  171. if (OLECLOSE_SAVEIFDIRTY==dwSaveOption && m_pObj->m_fDirty)
  172. fSave=TRUE;
  173. /*
  174. * If asked to prompt, only do so if dirty, then if we get a
  175. * YES, save as usual and close. On NO, just close. On
  176. * CANCEL return OLE_E_PROMPTSAVECANCELLED.
  177. */
  178. if (OLECLOSE_PROMPTSAVE==dwSaveOption && m_pObj->m_fDirty) {
  179. UINT uRet;
  180. uRet = MessageBox(NULL, ResourceString(IDS_CLOSEPROMPT),
  181. ResourceString(IDS_CLOSECAPTION), MB_YESNOCANCEL);
  182. if (IDCANCEL==uRet)
  183. return (OLE_E_PROMPTSAVECANCELLED);
  184. if (IDYES==uRet)
  185. fSave=TRUE;
  186. }
  187. if (fSave) {
  188. m_pObj->SendAdvise(OBJECTCODE_SAVEOBJECT);
  189. m_pObj->SendAdvise(OBJECTCODE_SAVED);
  190. }
  191. //We get directly here on OLECLOSE_NOSAVE.
  192. if ( m_pObj->m_fLockContainer && ( NULL != m_pObj->m_pIOleClientSite ) ) {
  193. //Match LockContainer call from SetClientSite
  194. LPOLECONTAINER pIOleCont;
  195. if (SUCCEEDED(m_pObj->m_pIOleClientSite->GetContainer(&pIOleCont))) {
  196. pIOleCont->LockContainer(FALSE);
  197. pIOleCont->Release();
  198. }
  199. }
  200. // Deactivate
  201. m_pObj->InPlaceDeactivate();
  202. // Revoke registration in ROT
  203. if (m_pObj->m_dwRegROT != 0) {
  204. IRunningObjectTable *pROT;
  205. if (!FAILED(GetRunningObjectTable(0, &pROT))) {
  206. pROT->Revoke(m_pObj->m_dwRegROT);
  207. pROT->Release();
  208. m_pObj->m_dwRegROT = 0;
  209. }
  210. }
  211. return NOERROR;
  212. }
  213. /*
  214. * CImpIOleObject::DoVerb
  215. *
  216. * Purpose:
  217. * Executes an object-defined action.
  218. *
  219. * Parameters:
  220. * iVerb LONG index of the verb to execute.
  221. * pMSG LPMSG describing the event causing the
  222. * activation.
  223. * pActiveSite LPOLECLIENTSITE to the site involved.
  224. * lIndex LONG the piece on which execution is happening.
  225. * hWndParent HWND of the window in which the object can play
  226. * in-place.
  227. * pRectPos LPRECT of the object in hWndParent where the
  228. * object can play in-place if desired.
  229. *
  230. * Return Value:
  231. * HRESULT NOERROR or a general error value.
  232. */
  233. STDMETHODIMP
  234. CImpIOleObject::DoVerb(
  235. LONG iVerb,
  236. LPMSG /* pMSG */,
  237. LPOLECLIENTSITE pActiveSite,
  238. LONG /* lIndex */,
  239. HWND /* hWndParent */,
  240. LPCRECT /* pRectPos */
  241. )
  242. {
  243. HRESULT hr;
  244. CAUUID caGUID;
  245. switch (iVerb)
  246. {
  247. case OLEIVERB_HIDE:
  248. if (NULL != m_pObj->m_pIOleIPSite) {
  249. m_pObj->UIDeactivate();
  250. ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  251. }
  252. else {
  253. ShowWindow(m_pObj->m_pHW->Window(), SW_HIDE);
  254. m_pObj->SendAdvise(OBJECTCODE_HIDEWINDOW);
  255. }
  256. break;
  257. case OLEIVERB_PRIMARY:
  258. case OLEIVERB_SHOW:
  259. if (NULL != m_pObj->m_pIOleIPSite) {
  260. ShowWindow(m_pObj->m_pHW->Window(), SW_SHOW);
  261. return NOERROR; //Already active
  262. }
  263. if (m_pObj->m_fAllowInPlace) {
  264. return m_pObj->InPlaceActivate(pActiveSite ,TRUE);
  265. }
  266. return (OLEOBJ_S_INVALIDVERB);
  267. break;
  268. case OLEIVERB_INPLACEACTIVATE:
  269. if (NULL != m_pObj->m_pHW) {
  270. HWND hWndHW=m_pObj->m_pHW->Window();
  271. ShowWindow(hWndHW, SW_SHOW);
  272. SetFocus(hWndHW);
  273. return NOERROR;
  274. }
  275. /*
  276. * Only inside-out supporting containers will use
  277. * this verb.
  278. */
  279. m_pObj->m_fContainerKnowsInsideOut=TRUE;
  280. m_pObj->InPlaceActivate(pActiveSite, FALSE);
  281. break;
  282. case OLEIVERB_UIACTIVATE:
  283. m_pObj->InPlaceActivate(pActiveSite, TRUE);
  284. break;
  285. case OLEIVERB_PROPERTIES:
  286. case POLYLINEVERB_PROPERTIES:
  287. /*
  288. * Let the container try first if there are
  289. * extended controls. Otherwise we'll display
  290. * our own pages.
  291. */
  292. if (NULL!=m_pObj->m_pIOleControlSite) {
  293. hr=m_pObj->m_pIOleControlSite->ShowPropertyFrame();
  294. if (NOERROR==hr)
  295. break; //All done
  296. }
  297. //Put up our property pages.
  298. hr=m_pObj->m_pImpISpecifyPP->GetPages(&caGUID);
  299. if (FAILED(hr))
  300. return FALSE;
  301. hr = OleCreatePropertyFrame(m_pObj->m_pCtrl->Window(),
  302. 10,
  303. 10,
  304. ResourceString(IDS_PROPFRM_TITLE),
  305. 1,
  306. (IUnknown **)&m_pObj,
  307. caGUID.cElems,
  308. caGUID.pElems,
  309. LOCALE_USER_DEFAULT,
  310. 0L,
  311. NULL);
  312. //Free the GUIDs
  313. CoTaskMemFree((void *)caGUID.pElems);
  314. break;
  315. default:
  316. return (OLEOBJ_S_INVALIDVERB);
  317. }
  318. return NOERROR;
  319. }
  320. /*
  321. * CImpIOleObject::GetUserClassID
  322. *
  323. * Purpose:
  324. * Used for linked objects, this returns the class ID of what end
  325. * users think they are editing.
  326. *
  327. * Parameters:
  328. * pClsID LPCLSID in which to store the CLSID.
  329. *
  330. * Return Value:
  331. * HRESULT NOERROR or a general error value.
  332. */
  333. STDMETHODIMP
  334. CImpIOleObject::GetUserClassID(
  335. OUT LPCLSID pClsID
  336. )
  337. {
  338. HRESULT hr = S_OK;
  339. if (pClsID == NULL) {
  340. return E_POINTER;
  341. }
  342. /*
  343. * If you are not registered to handle data other than yourself,
  344. * then you can just return your class ID here. If you are
  345. * registered as usable from Treat-As dialogs, then you need to
  346. * return the CLSID of what you are really editing.
  347. */
  348. try {
  349. *pClsID=CLSID_SystemMonitor;
  350. } catch (...) {
  351. hr = E_POINTER;
  352. }
  353. return hr;
  354. }
  355. /*
  356. * CImpIOleObject::SetExtent
  357. *
  358. * Purpose:
  359. * Sets the size of the object in HIMETRIC units.
  360. *
  361. * Parameters:
  362. * dwAspect DWORD of the aspect affected.
  363. * pSize LPSIZEL containing the new size.
  364. *
  365. * Return Value:
  366. * HRESULT NOERROR or a general error value.
  367. */
  368. STDMETHODIMP
  369. CImpIOleObject::SetExtent(
  370. IN DWORD dwAspect,
  371. IN LPSIZEL pSize
  372. )
  373. {
  374. HRESULT hr = S_OK;
  375. RECT rectExt;
  376. if (pSize == NULL) {
  377. return E_POINTER;
  378. }
  379. try {
  380. SetRect(&rectExt, 0, 0, pSize->cx, pSize->cy);
  381. if (dwAspect == DVASPECT_CONTENT) {
  382. //
  383. // convert from HIMETRIC to device coord
  384. //
  385. m_pObj->RectConvertMappings(&rectExt,TRUE);
  386. // If changed and non-zero, store as new extent
  387. if ( !EqualRect ( &m_pObj->m_RectExt, &rectExt) &&
  388. !IsRectEmpty( &rectExt ) ) {
  389. m_pObj->m_RectExt = rectExt;
  390. #ifdef USE_SAMPLE_IPOLYLIN10
  391. m_pObj->m_pImpIPolyline->SizeSet(&rectExt, TRUE);
  392. #else
  393. hWnd = m_pObj->m_pCtrl->Window();
  394. if (hWnd) {
  395. SetWindowPos(hWnd,
  396. NULL,
  397. 0,
  398. 0,
  399. rectExt.right - rectExt.left,
  400. rectExt.bottom - rectExt.top,
  401. SWP_NOMOVE | SWP_NOZORDER);
  402. InvalidateRect(hWnd, NULL, TRUE);
  403. }
  404. m_pObj->m_fDirty=TRUE;
  405. #endif
  406. // Notify container of change to force metafile update
  407. // HONG:: Why do we turn off this statement???
  408. //
  409. //m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  410. }
  411. }
  412. } catch (...) {
  413. hr = E_POINTER;
  414. }
  415. return hr;
  416. }
  417. /*
  418. * CImpIOleObject::GetExtent
  419. *
  420. * Purpose:
  421. * Retrieves the size of the object in HIMETRIC units.
  422. *
  423. * Parameters:
  424. * dwAspect DWORD of the aspect requested
  425. * pSize LPSIZEL into which to store the size.
  426. *
  427. * Return Value:
  428. * HRESULT NOERROR or a general error value.
  429. */
  430. STDMETHODIMP
  431. CImpIOleObject::GetExtent(
  432. IN DWORD dwAspect,
  433. OUT LPSIZEL pSize
  434. )
  435. {
  436. HRESULT hr = S_OK;
  437. if (pSize == NULL) {
  438. return E_POINTER;
  439. }
  440. try {
  441. //Delegate directly to IViewObject2::GetExtent
  442. hr = m_pObj->m_pImpIViewObject->GetExtent( dwAspect, -1, NULL, pSize);
  443. } catch (...) {
  444. hr = E_POINTER;
  445. }
  446. return hr;
  447. }
  448. /*
  449. * CImpIOleObject::Advise
  450. * CImpIOleObject::Unadvise
  451. * CImpIOleObject::EnumAdvise
  452. *
  453. * Purpose:
  454. * Advisory connection functions.
  455. */
  456. STDMETHODIMP
  457. CImpIOleObject::Advise(
  458. LPADVISESINK pIAdviseSink,
  459. LPDWORD pdwConn
  460. )
  461. {
  462. HRESULT hr = S_OK;
  463. if (NULL == m_pObj->m_pIOleAdviseHolder)
  464. {
  465. hr = CreateOleAdviseHolder(&m_pObj->m_pIOleAdviseHolder);
  466. if (FAILED(hr))
  467. return hr;
  468. }
  469. try {
  470. hr = m_pObj->m_pIOleAdviseHolder->Advise(pIAdviseSink, pdwConn);
  471. } catch (...) {
  472. hr = E_POINTER;
  473. }
  474. return hr;
  475. }
  476. STDMETHODIMP
  477. CImpIOleObject::Unadvise(DWORD dwConn)
  478. {
  479. if (NULL != m_pObj->m_pIOleAdviseHolder)
  480. return m_pObj->m_pIOleAdviseHolder->Unadvise(dwConn);
  481. return (E_FAIL);
  482. }
  483. STDMETHODIMP
  484. CImpIOleObject::EnumAdvise(
  485. LPENUMSTATDATA *ppEnum
  486. )
  487. {
  488. HRESULT hr = S_OK;
  489. if (ppEnum == NULL) {
  490. return E_POINTER;
  491. }
  492. try {
  493. * ppEnum = NULL;
  494. if (NULL != m_pObj->m_pIOleAdviseHolder) {
  495. hr = m_pObj->m_pIOleAdviseHolder->EnumAdvise(ppEnum);
  496. }
  497. else {
  498. hr = E_FAIL;
  499. }
  500. } catch (...) {
  501. hr = E_POINTER;
  502. }
  503. return hr;
  504. }
  505. /*
  506. * CImpIOleObject::SetMoniker
  507. *
  508. * Purpose:
  509. * Informs the object of its moniker or its container's moniker
  510. * depending on dwWhich.
  511. *
  512. * Parameters:
  513. * dwWhich DWORD describing whether the moniker is the
  514. * object's or the container's.
  515. * pmk LPMONIKER with the name.
  516. *
  517. * Return Value:
  518. * HRESULT NOERROR or a general error value.
  519. */
  520. STDMETHODIMP
  521. CImpIOleObject::SetMoniker(
  522. DWORD /* dwWhich */,
  523. LPMONIKER /* pmk */
  524. )
  525. {
  526. LPMONIKER pmkFull;
  527. HRESULT hr = E_FAIL;
  528. HRESULT hrTmp;
  529. LPBC pbc;
  530. if (NULL != m_pObj->m_pIOleClientSite) {
  531. hr = m_pObj->m_pIOleClientSite->GetMoniker (
  532. OLEGETMONIKER_ONLYIFTHERE,
  533. OLEWHICHMK_OBJFULL,
  534. &pmkFull);
  535. if (SUCCEEDED(hr)) {
  536. hrTmp = CreateBindCtx(0, &pbc);
  537. if (SUCCEEDED(hrTmp)) {
  538. hrTmp = pmkFull->IsRunning(pbc, NULL, NULL);
  539. pbc->Release();
  540. if (SUCCEEDED(hrTmp)) {
  541. pmkFull->Release();
  542. return NOERROR;
  543. }
  544. }
  545. //This will revoke the old one if m_dwRegROT is nonzero.
  546. RegisterAsRunning(m_pUnkOuter, pmkFull, 0, &m_pObj->m_dwRegROT);
  547. //Inform clients of the new moniker
  548. if (NULL != m_pObj->m_pIOleAdviseHolder) {
  549. m_pObj->m_pIOleAdviseHolder->SendOnRename(pmkFull);
  550. }
  551. pmkFull->Release();
  552. }
  553. }
  554. return hr;
  555. }
  556. /*
  557. * CImpIOleObject::GetMoniker
  558. *
  559. * Purpose:
  560. * Asks the object for a moniker that can later be used to
  561. * reconnect to it.
  562. *
  563. * Parameters:
  564. * dwAssign DWORD determining how to assign the moniker to
  565. * to the object.
  566. * dwWhich DWORD describing which moniker the caller wants.
  567. * ppmk LPMONIKER * into which to store the moniker.
  568. *
  569. * Return Value:
  570. * HRESULT NOERROR or a general error value.
  571. */
  572. STDMETHODIMP
  573. CImpIOleObject::GetMoniker(
  574. IN DWORD /* dwAssign */,
  575. IN DWORD /* dwWhich */,
  576. OUT LPMONIKER *ppmk
  577. )
  578. {
  579. HRESULT hr = E_FAIL;
  580. if (ppmk == NULL) {
  581. return E_POINTER;
  582. }
  583. try {
  584. *ppmk = NULL;
  585. /*
  586. * Since we only support embedded objects, our moniker
  587. * is always the full moniker from the contianer.
  588. */
  589. if (NULL != m_pObj->m_pIOleClientSite)
  590. {
  591. hr = m_pObj->m_pIOleClientSite->GetMoniker(
  592. OLEGETMONIKER_ONLYIFTHERE,
  593. OLEWHICHMK_OBJFULL,
  594. ppmk);
  595. }
  596. } catch (...) {
  597. hr = E_POINTER;
  598. }
  599. return hr;
  600. }
  601. STDMETHODIMP
  602. CImpIOleObject::InitFromData(
  603. LPDATAOBJECT /* pIDataObject */,
  604. BOOL /* fCreation */,
  605. DWORD /* dw */
  606. )
  607. {
  608. return (E_NOTIMPL);
  609. }
  610. STDMETHODIMP
  611. CImpIOleObject::GetClipboardData(
  612. DWORD /* dwReserved */,
  613. LPDATAOBJECT * /* ppIDataObj */
  614. )
  615. {
  616. return (E_NOTIMPL);
  617. }
  618. STDMETHODIMP CImpIOleObject::Update(void)
  619. {
  620. return NOERROR;
  621. }
  622. STDMETHODIMP CImpIOleObject::IsUpToDate(void)
  623. {
  624. return NOERROR;
  625. }
  626. STDMETHODIMP CImpIOleObject::SetColorScheme(LPLOGPALETTE /* pLP */)
  627. {
  628. return (E_NOTIMPL);
  629. }
  630. //Methods implemented using registry helper functions in OLE.
  631. STDMETHODIMP CImpIOleObject::EnumVerbs(LPENUMOLEVERB *ppEnum)
  632. {
  633. HRESULT hr = S_OK;
  634. if (ppEnum == NULL) {
  635. return E_POINTER;
  636. }
  637. try {
  638. hr = OleRegEnumVerbs(m_pObj->m_clsID, ppEnum);
  639. } catch (...) {
  640. hr = E_POINTER;
  641. }
  642. return hr;
  643. }
  644. STDMETHODIMP CImpIOleObject::GetUserType(
  645. DWORD dwForm,
  646. LPOLESTR *ppszType
  647. )
  648. {
  649. HRESULT hr = S_OK;
  650. if (ppszType == NULL) {
  651. return E_POINTER;
  652. }
  653. try {
  654. hr = OleRegGetUserType(m_pObj->m_clsID, dwForm, ppszType);
  655. } catch (...) {
  656. hr = E_POINTER;
  657. }
  658. return hr;
  659. }
  660. STDMETHODIMP CImpIOleObject::GetMiscStatus(
  661. DWORD dwAspect,
  662. LPDWORD pdwStatus
  663. )
  664. {
  665. HRESULT hr = S_OK;
  666. if (pdwStatus == NULL) {
  667. return E_POINTER;
  668. }
  669. try {
  670. hr = OleRegGetMiscStatus(m_pObj->m_clsID, dwAspect, pdwStatus);
  671. } catch (...) {
  672. hr = E_POINTER;
  673. }
  674. return hr;
  675. }
  676. void RegisterAsRunning(
  677. IUnknown *pUnk,
  678. IMoniker *pmk,
  679. DWORD dwFlags,
  680. LPDWORD pdwReg
  681. )
  682. {
  683. IRunningObjectTable *pROT;
  684. HRESULT hr = S_OK;
  685. DWORD dwReg;
  686. if (FAILED(GetRunningObjectTable(0, &pROT))) {
  687. return;
  688. }
  689. dwReg = *pdwReg;
  690. hr = pROT->Register(dwFlags, pUnk, pmk, pdwReg);
  691. if (MK_S_MONIKERALREADYREGISTERED == GetScode(hr))
  692. {
  693. if (0 != dwReg)
  694. pROT->Revoke(dwReg);
  695. }
  696. pROT->Release();
  697. return;
  698. }