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.

1336 lines
33 KiB

  1. /*++
  2. Copyright (C) 1993-1999 Microsoft Corporation
  3. Module Name:
  4. polyline.cpp
  5. Abstract:
  6. Implementation of the CPolyline class that is exposed as a
  7. component object.
  8. --*/
  9. #include "polyline.h"
  10. #include "smonctrl.h"
  11. #include "unihelpr.h"
  12. #include "utils.h"
  13. extern ITypeLib *g_pITypeLib;
  14. /*
  15. * CPolyline:CPolyline
  16. * CPolyline::~CPolyline
  17. *
  18. * Constructor Parameters:
  19. * pUnkOuter LPUNKNOWN of the controlling unknown.
  20. * pfnDestroy PFNDESTROYED to call when an object is
  21. * destroyed.
  22. * hInst HINSTANCE of the application we're in.
  23. */
  24. CPolyline::CPolyline (
  25. LPUNKNOWN pUnkOuter,
  26. PFNDESTROYED pfnDestroy )
  27. : m_cRef ( 0 ),
  28. m_pUnkOuter ( pUnkOuter ),
  29. m_pfnDestroy ( pfnDestroy ),
  30. m_fDirty ( FALSE ),
  31. #ifdef USE_SAMPLE_IPOLYLIN10
  32. m_pImpIPolyline ( NULL ),
  33. #endif
  34. m_pImpIConnPtCont ( NULL ),
  35. m_cf ( 0 ),
  36. m_clsID ( CLSID_SystemMonitor ),
  37. m_pIStorage ( NULL ),
  38. m_pIStream ( NULL ),
  39. m_pImpIPersistStorage ( NULL ),
  40. m_pImpIPersistStreamInit ( NULL ),
  41. m_pImpIPersistPropertyBag ( NULL ),
  42. m_pImpIPerPropertyBrowsing ( NULL ),
  43. m_pImpIDataObject ( NULL ),
  44. m_pImpIObjectSafety ( NULL ),
  45. m_pIDataAdviseHolder ( NULL ),
  46. m_pDefIUnknown ( NULL ),
  47. m_pDefIDataObject ( NULL ),
  48. m_pDefIViewObject ( NULL ),
  49. m_pDefIPersistStorage ( NULL ),
  50. m_pIOleAdviseHolder ( NULL ),
  51. m_pImpIOleObject ( NULL ),
  52. m_pIOleClientSite ( NULL ),
  53. m_pImpIViewObject ( NULL ),
  54. m_pIAdviseSink ( NULL ),
  55. m_dwFrozenAspects ( 0 ),
  56. m_dwAdviseAspects ( 0 ),
  57. m_dwAdviseFlags ( 0 ),
  58. m_pImpIRunnableObject ( NULL ),
  59. m_bIsRunning ( FALSE ),
  60. // m_pImpIExternalConnection ( NULL ),
  61. m_fLockContainer ( FALSE ),
  62. m_dwRegROT ( 0L ),
  63. m_pIOleIPSite ( NULL ),
  64. m_pIOleIPFrame ( NULL ),
  65. m_pIOleIPUIWindow ( NULL ),
  66. m_pImpIOleIPObject ( NULL ),
  67. m_pImpIOleIPActiveObject ( NULL ),
  68. m_hMenuShared ( NULL ),
  69. m_hOLEMenu ( NULL ),
  70. m_pHW ( NULL ),
  71. m_fAllowInPlace ( TRUE ),
  72. m_fUIActive ( FALSE ),
  73. m_fContainerKnowsInsideOut ( FALSE ),
  74. m_pImpISpecifyPP ( NULL ),
  75. m_pImpIProvideClassInfo ( NULL ),
  76. m_pImpIDispatch ( NULL ),
  77. m_pImpISystemMonitor ( NULL ),
  78. m_pImpIOleControl ( NULL ),
  79. m_pImpICounters ( NULL ),
  80. m_pImpILogFiles ( NULL ),
  81. m_pITypeLib ( NULL ),
  82. m_pIOleControlSite ( NULL ),
  83. m_pIDispatchAmbients ( NULL ),
  84. m_fFreezeEvents ( FALSE ),
  85. m_fHatch ( TRUE ),
  86. m_pCtrl ( NULL )
  87. {
  88. // Set default extents
  89. SetRect(&m_RectExt, 0, 0, 300, 200);
  90. return;
  91. }
  92. CPolyline::~CPolyline(void)
  93. {
  94. LPUNKNOWN pIUnknown=this;
  95. if (NULL!=m_pUnkOuter)
  96. pIUnknown=m_pUnkOuter;
  97. if (NULL!=m_pHW) {
  98. delete m_pHW;
  99. m_pHW = NULL;
  100. }
  101. if (NULL != m_pCtrl) {
  102. delete m_pCtrl;
  103. m_pCtrl = NULL;
  104. }
  105. /*
  106. * In aggregation, release cached pointers but
  107. * AddRef the controlling unknown first.
  108. */
  109. pIUnknown->AddRef();
  110. pIUnknown->AddRef();
  111. pIUnknown->AddRef();
  112. ReleaseInterface(m_pDefIViewObject);
  113. ReleaseInterface(m_pDefIDataObject);
  114. ReleaseInterface(m_pDefIPersistStorage);
  115. //Cached pointer rules do not apply to IUnknown
  116. ReleaseInterface(m_pDefIUnknown);
  117. ReleaseInterface(m_pIAdviseSink);
  118. ReleaseInterface(m_pIOleClientSite);
  119. ReleaseInterface(m_pIOleAdviseHolder);
  120. DeleteInterfaceImp(m_pImpIOleObject);
  121. DeleteInterfaceImp(m_pImpIViewObject);
  122. DeleteInterfaceImp(m_pImpIRunnableObject);
  123. //Other in-place interfaces released in deactivation.
  124. DeleteInterfaceImp(m_pImpIOleIPObject);
  125. DeleteInterfaceImp(m_pImpIOleIPActiveObject);
  126. ReleaseInterface(m_pIDispatchAmbients);
  127. ReleaseInterface(m_pIOleControlSite);
  128. DeleteInterfaceImp(m_pImpISpecifyPP);
  129. DeleteInterfaceImp(m_pImpIProvideClassInfo);
  130. DeleteInterfaceImp(m_pImpIDispatch);
  131. DeleteInterfaceImp(m_pImpISystemMonitor);
  132. DeleteInterfaceImp(m_pImpIOleControl);
  133. DeleteInterfaceImp(m_pImpICounters);
  134. DeleteInterfaceImp(m_pImpILogFiles);
  135. //Anything we might have registered in IRunnableObject::Run
  136. if (m_dwRegROT != 0)
  137. {
  138. IRunningObjectTable *pROT;
  139. if (!FAILED(GetRunningObjectTable(0, &pROT)))
  140. {
  141. pROT->Revoke(m_dwRegROT);
  142. pROT->Release();
  143. }
  144. }
  145. // DeleteInterfaceImp(m_pImpIExternalConnection);
  146. ReleaseInterface(m_pIDataAdviseHolder);
  147. DeleteInterfaceImp(m_pImpIDataObject);
  148. DeleteInterfaceImp(m_pImpIObjectSafety);
  149. DeleteInterfaceImp(m_pImpIPersistStreamInit);
  150. DeleteInterfaceImp(m_pImpIPersistStorage);
  151. DeleteInterfaceImp(m_pImpIPersistPropertyBag);
  152. DeleteInterfaceImp(m_pImpIPerPropertyBrowsing);
  153. ReleaseInterface(m_pIStream);
  154. ReleaseInterface(m_pIStorage);
  155. DeleteInterfaceImp(m_pImpIConnPtCont);
  156. #ifdef USE_SAMPLE_IPOLYLIN10
  157. DeleteInterfaceImp(m_pImpIPolyline);
  158. #endif
  159. return;
  160. }
  161. /*
  162. * CPolyline::Init
  163. *
  164. * Purpose:
  165. * Performs any intiailization of a CPolyline that's prone to
  166. * failure that we also use internally before exposing the
  167. * object outside this DLL.
  168. *
  169. * Parameters:
  170. * None
  171. *
  172. * Return Value:
  173. * BOOL TRUE if the function is successful,
  174. * FALSE otherwise.
  175. */
  176. BOOL CPolyline::Init(void)
  177. {
  178. LPUNKNOWN pIUnknown=this;
  179. HRESULT hr;
  180. INT i;
  181. if (NULL!=m_pUnkOuter)
  182. pIUnknown=m_pUnkOuter;
  183. m_cf=(CLIPFORMAT)RegisterClipboardFormat(SZSYSMONCLIPFORMAT);
  184. m_pImpIPersistStorage=new CImpIPersistStorage(this, pIUnknown);
  185. if (NULL==m_pImpIPersistStorage)
  186. return FALSE;
  187. m_pImpIPersistStreamInit=new CImpIPersistStreamInit(this, pIUnknown);
  188. if (NULL==m_pImpIPersistStreamInit)
  189. return FALSE;
  190. m_pImpIPersistPropertyBag=new CImpIPersistPropertyBag(this, pIUnknown);
  191. if (NULL==m_pImpIPersistPropertyBag)
  192. return FALSE;
  193. m_pImpIPerPropertyBrowsing=new CImpIPerPropertyBrowsing(this, pIUnknown);
  194. if (NULL==m_pImpIPerPropertyBrowsing)
  195. return FALSE;
  196. #ifdef USE_SAMPLE_IPOLYLIN10
  197. m_pImpIPolyline=new CImpIPolyline(this, pIUnknown);
  198. if (NULL==m_pImpIPolyline)
  199. return FALSE;
  200. #endif
  201. m_pImpIConnPtCont=new CImpIConnPtCont(this, pIUnknown);
  202. if (NULL==m_pImpIConnPtCont)
  203. return FALSE;
  204. for (i=0; i<CONNECTION_POINT_CNT; i++) {
  205. if (!m_ConnectionPoint[i].Init(this, pIUnknown, i)) {
  206. return FALSE;
  207. }
  208. }
  209. m_pImpIDataObject=new CImpIDataObject(this, pIUnknown);
  210. if (NULL==m_pImpIDataObject)
  211. return FALSE;
  212. m_pImpIOleObject=new CImpIOleObject(this, pIUnknown);
  213. if (NULL==m_pImpIOleObject)
  214. return FALSE;
  215. m_pImpIViewObject=new CImpIViewObject(this, pIUnknown);
  216. if (NULL==m_pImpIViewObject)
  217. return FALSE;
  218. m_pImpIRunnableObject=new CImpIRunnableObject(this, pIUnknown);
  219. if (NULL==m_pImpIRunnableObject)
  220. return FALSE;
  221. /***********************************
  222. m_pImpIExternalConnection=new CImpIExternalConnection(this
  223. , pIUnknown);
  224. if (NULL==m_pImpIExternalConnection)
  225. return FALSE;
  226. ************************************/
  227. m_pImpIOleIPObject=new CImpIOleInPlaceObject(this, pIUnknown);
  228. if (NULL==m_pImpIOleIPObject)
  229. return FALSE;
  230. m_pImpIOleIPActiveObject=new CImpIOleInPlaceActiveObject(this
  231. , pIUnknown);
  232. if (NULL==m_pImpIOleIPActiveObject)
  233. return FALSE;
  234. m_pImpISpecifyPP=new CImpISpecifyPP(this, pIUnknown);
  235. if (NULL==m_pImpISpecifyPP)
  236. return FALSE;
  237. m_pImpIProvideClassInfo=new CImpIProvideClassInfo(this, pIUnknown);
  238. if (NULL==m_pImpIProvideClassInfo)
  239. return FALSE;
  240. m_pImpISystemMonitor=new CImpISystemMonitor(this, pIUnknown);
  241. if (NULL==m_pImpISystemMonitor)
  242. return FALSE;
  243. m_pImpICounters = new CImpICounters(this, pIUnknown);
  244. if (NULL==m_pImpICounters)
  245. return FALSE;
  246. m_pImpILogFiles = new CImpILogFiles(this, pIUnknown);
  247. if (NULL==m_pImpILogFiles)
  248. return FALSE;
  249. m_pImpIDispatch=new CImpIDispatch(this, pIUnknown);
  250. if (NULL==m_pImpIDispatch)
  251. return FALSE;
  252. m_pImpIDispatch->SetInterface(DIID_DISystemMonitor, m_pImpISystemMonitor);
  253. m_pImpIOleControl=new CImpIOleControl(this, pIUnknown);
  254. if (NULL==m_pImpIOleControl)
  255. return FALSE;
  256. m_pImpIObjectSafety = new CImpIObjectSafety(this, pIUnknown);
  257. if (NULL == m_pImpIObjectSafety) {
  258. return FALSE;
  259. }
  260. m_pCtrl = new CSysmonControl(this);
  261. if (NULL==m_pCtrl)
  262. return FALSE;
  263. if ( !m_pCtrl->AllocateSubcomponents() )
  264. return FALSE;
  265. /*
  266. * We're sitting at ref count 0 and the next call will AddRef a
  267. * few times and Release a few times. This insures we don't
  268. * delete ourselves prematurely.
  269. */
  270. m_cRef++;
  271. //
  272. // Aggregate OLE's cache for IOleCache* interfaces.
  273. //
  274. hr = CreateDataCache(pIUnknown,
  275. CLSID_SystemMonitor ,
  276. IID_IUnknown,
  277. (PPVOID)&m_pDefIUnknown);
  278. if (FAILED(hr))
  279. return FALSE;
  280. /*
  281. * NOTE: The spec specifically states that any interfaces
  282. * besides IUnknown that we obtain on an aggregated object
  283. * should be Released immediately after we QueryInterface for
  284. * them because the QueryInterface will AddRef us, and since
  285. * we would not release these interfaces until we were
  286. * destroyed, we'd never go away because we'd never get a zero
  287. * ref count.
  288. */
  289. //Now try to get other interfaces to which we delegate
  290. hr=m_pDefIUnknown->QueryInterface(IID_IViewObject2 , (PPVOID)&m_pDefIViewObject);
  291. if (FAILED(hr))
  292. return FALSE;
  293. pIUnknown->Release();
  294. hr=m_pDefIUnknown->QueryInterface(IID_IDataObject , (PPVOID)&m_pDefIDataObject);
  295. if (FAILED(hr))
  296. return FALSE;
  297. pIUnknown->Release();
  298. hr=m_pDefIUnknown->QueryInterface(IID_IPersistStorage , (PPVOID)&m_pDefIPersistStorage);
  299. if (FAILED(hr))
  300. return FALSE;
  301. pIUnknown->Release();
  302. m_cRef--;
  303. #ifdef USE_SAMPLE_IPOLYLIN10
  304. m_pImpIPolyline->New();
  305. #endif
  306. /*
  307. * The type information lib already loaded in DllAttach
  308. * just use it.(AddRef on it is called in DllAttach)
  309. *
  310. */
  311. m_pITypeLib = g_pITypeLib;
  312. //Set up our CONTROLINFO structure (we have two mnemonics)
  313. m_ctrlInfo.cb=sizeof(CONTROLINFO);
  314. m_ctrlInfo.dwFlags=0;
  315. m_ctrlInfo.hAccel=NULL;
  316. m_ctrlInfo.cAccel=0;
  317. /*
  318. * Note: we cannot initialize ambients until we get
  319. * a container interface pointer in IOleObject::SetClientSite.
  320. */
  321. return TRUE;
  322. }
  323. /*
  324. * CPolyline::QueryInterface
  325. * CPolyline::AddRef
  326. * CPolyline::Release
  327. *
  328. * Purpose:
  329. * IUnknown members for CPolyline object.
  330. */
  331. STDMETHODIMP CPolyline::QueryInterface(
  332. REFIID riid,
  333. PPVOID ppv
  334. )
  335. {
  336. HRESULT hr = S_OK;
  337. try {
  338. *ppv=NULL;
  339. if (IID_IUnknown==riid)
  340. *ppv=this;
  341. else if (IID_IConnectionPointContainer==riid)
  342. *ppv=m_pImpIConnPtCont;
  343. else if (IID_IPersistStorage==riid)
  344. *ppv=m_pImpIPersistStorage;
  345. else if (IID_IPersist==riid || IID_IPersistStream==riid
  346. || IID_IPersistStreamInit==riid)
  347. *ppv=m_pImpIPersistStreamInit;
  348. else if (IID_IPersistPropertyBag==riid )
  349. *ppv=m_pImpIPersistPropertyBag;
  350. else if (IID_IPerPropertyBrowsing==riid )
  351. *ppv=m_pImpIPerPropertyBrowsing;
  352. else if (IID_IDataObject==riid)
  353. *ppv=m_pImpIDataObject;
  354. else if (IID_IOleObject==riid)
  355. *ppv=m_pImpIOleObject;
  356. else if (IID_IViewObject==riid || IID_IViewObject2==riid)
  357. *ppv=m_pImpIViewObject;
  358. else if (IID_IRunnableObject==riid)
  359. // *ppv=m_pImpIRunnableObject;
  360. return E_NOINTERFACE;
  361. else if (IID_IExternalConnection==riid)
  362. // *ppv=m_pImpIExternalConnection;
  363. return E_NOINTERFACE;
  364. //IOleWindow will be the InPlaceObject
  365. else if (IID_IOleWindow==riid || IID_IOleInPlaceObject==riid)
  366. *ppv=m_pImpIOleIPObject;
  367. // The OLE rule state that InPlaceActiveObject should not be
  368. // provided in response to a query, but the current MFC (4.0)
  369. // won't work if we don't do it.
  370. else if (IID_IOleInPlaceActiveObject==riid)
  371. *ppv=m_pImpIOleIPActiveObject;
  372. else if (IID_ISpecifyPropertyPages==riid)
  373. *ppv=m_pImpISpecifyPP;
  374. else if (IID_IProvideClassInfo==riid)
  375. *ppv=m_pImpIProvideClassInfo;
  376. else if (IID_IDispatch==riid || DIID_DISystemMonitor==riid)
  377. *ppv=m_pImpIDispatch;
  378. else if (IID_ISystemMonitor==riid)
  379. *ppv=m_pImpISystemMonitor;
  380. else if (IID_IOleControl==riid)
  381. *ppv=m_pImpIOleControl;
  382. //Use the default handler's cache.
  383. else if (IID_IOleCache==riid || IID_IOleCache2==riid)
  384. return m_pDefIUnknown->QueryInterface(riid, ppv);
  385. else if (IID_IObjectSafety == riid) {
  386. *ppv = m_pImpIObjectSafety;
  387. }
  388. else {
  389. hr = E_NOINTERFACE;
  390. }
  391. } catch (...) {
  392. hr = E_POINTER;
  393. }
  394. assert ( NULL != *ppv );
  395. if (SUCCEEDED(hr) && NULL != *ppv ) {
  396. ((LPUNKNOWN)*ppv)->AddRef();
  397. }
  398. return hr;
  399. }
  400. STDMETHODIMP_(ULONG) CPolyline::AddRef(void)
  401. {
  402. return ++m_cRef;
  403. }
  404. STDMETHODIMP_(ULONG) CPolyline::Release(void)
  405. {
  406. if (0L!=--m_cRef)
  407. return m_cRef;
  408. // Prevent reentrant call
  409. m_cRef++;
  410. if (NULL!=m_pfnDestroy)
  411. (*m_pfnDestroy)();
  412. delete this;
  413. return 0L;
  414. }
  415. /*
  416. * CPolyline::RectConvertMappings
  417. *
  418. * Purpose:
  419. * Converts the contents of a rectangle from device (MM_TEXT) or
  420. * HIMETRIC to the other.
  421. *
  422. * Parameters:
  423. * pRect LPRECT containing the rectangle to convert.
  424. * fToDevice BOOL TRUE to convert from HIMETRIC to device,
  425. * FALSE to convert device to HIMETRIC.
  426. *
  427. * Return Value:
  428. * None
  429. */
  430. void
  431. CPolyline::RectConvertMappings(
  432. LPRECT pRect,
  433. BOOL fToDevice
  434. )
  435. {
  436. HDC hDC = NULL;
  437. INT iLpx, iLpy;
  438. if ( NULL != pRect ) {
  439. hDC=GetDC(NULL);
  440. if ( NULL != hDC ) {
  441. iLpx=GetDeviceCaps(hDC, LOGPIXELSX);
  442. iLpy=GetDeviceCaps(hDC, LOGPIXELSY);
  443. ReleaseDC(NULL, hDC);
  444. if (fToDevice) {
  445. pRect->left=MulDiv(iLpx, pRect->left, HIMETRIC_PER_INCH);
  446. pRect->top =MulDiv(iLpy, pRect->top , HIMETRIC_PER_INCH);
  447. pRect->right =MulDiv(iLpx, pRect->right, HIMETRIC_PER_INCH);
  448. pRect->bottom=MulDiv(iLpy, pRect->bottom,HIMETRIC_PER_INCH);
  449. } else {
  450. if ( 0 != iLpx && 0 != iLpy ) {
  451. pRect->left=MulDiv(pRect->left, HIMETRIC_PER_INCH, iLpx);
  452. pRect->top =MulDiv(pRect->top , HIMETRIC_PER_INCH, iLpy);
  453. pRect->right =MulDiv(pRect->right, HIMETRIC_PER_INCH, iLpx);
  454. pRect->bottom=MulDiv(pRect->bottom,HIMETRIC_PER_INCH, iLpy);
  455. }
  456. }
  457. }
  458. }
  459. return;
  460. }
  461. /*
  462. * CPolyline::RenderBitmap
  463. *
  464. * Purpose:
  465. * Creates a bitmap image of the current Polyline.
  466. *
  467. * Parameters:
  468. * phBmp HBITMAP * in which to return the bitmap.
  469. *
  470. * Return Value:
  471. * HRESULT NOERROR if successful, otherwise a
  472. * POLYLINE_E_ value.
  473. */
  474. STDMETHODIMP
  475. CPolyline::RenderBitmap(
  476. HBITMAP *phBmp,
  477. HDC hAttribDC
  478. )
  479. {
  480. //HDC hDC;
  481. HRESULT hr = NOERROR;
  482. HDC hMemDC;
  483. HBITMAP hBmp = NULL;
  484. RECT rc;
  485. HGDIOBJ hObj;
  486. HWND hWnd;
  487. if (NULL==phBmp) {
  488. hr = E_POINTER;
  489. } else if ( NULL == hAttribDC ) {
  490. hr = E_INVALIDARG;
  491. } else {
  492. hWnd = m_pCtrl->Window();
  493. if ( NULL != hWnd ) {
  494. //Render a bitmap the size of the current rectangle.
  495. hMemDC = CreateCompatibleDC(hAttribDC);
  496. if ( NULL != hMemDC ) {
  497. GetClientRect(hWnd, &rc);
  498. hBmp = CreateCompatibleBitmap(hAttribDC, rc.right, rc.bottom);
  499. if (NULL!=hBmp) {
  500. //Draw the control into the bitmap.
  501. hObj = SelectObject(hMemDC, hBmp);
  502. Draw(hMemDC, hAttribDC, FALSE, TRUE, &rc);
  503. SelectObject(hMemDC, hObj);
  504. }
  505. DeleteDC(hMemDC);
  506. // ReleaseDC(hWnd, hDC);
  507. }
  508. *phBmp=hBmp;
  509. hr = NOERROR;
  510. } else {
  511. hr = E_UNEXPECTED;
  512. }
  513. }
  514. return hr;
  515. }
  516. /*
  517. * CPolyline::RenderMetafilePict
  518. *
  519. * Purpose:
  520. * Renders the current Polyline into a METAFILEPICT structure in
  521. * global memory.
  522. *
  523. * Parameters:
  524. * phMem HGLOBAL * in which to return the
  525. * METAFILEPICT.
  526. *
  527. * Return Value:
  528. * HRESULT NOERROR if successful, otherwise a
  529. * POLYLINE_E_ value.
  530. */
  531. STDMETHODIMP
  532. CPolyline::RenderMetafilePict(
  533. HGLOBAL *phMem,
  534. HDC hAttribDC
  535. )
  536. {
  537. HGLOBAL hMem;
  538. HMETAFILE hMF;
  539. LPMETAFILEPICT pMF;
  540. RECT rc;
  541. HDC hDC;
  542. if (NULL==phMem)
  543. return E_POINTER;
  544. //Create a memory metafile and return its handle.
  545. hDC=(HDC)CreateMetaFile(NULL);
  546. if (NULL==hDC)
  547. return STG_E_MEDIUMFULL;
  548. SetMapMode(hDC, MM_ANISOTROPIC);
  549. //
  550. // Always set up the window extents to the real window size
  551. // so the drawing routines can work in their normal dev coords
  552. //
  553. /********* Use the extent rect, not the window rect *********/
  554. rc = m_RectExt;
  555. // GetClientRect(m_pCtrl->Window(), &rc);
  556. /************************************************************/
  557. Draw( hDC, hAttribDC, TRUE, TRUE, &rc );
  558. hMF=CloseMetaFile(hDC);
  559. if (NULL==hMF)
  560. return STG_E_MEDIUMFULL;
  561. //Allocate the METAFILEPICT structure.
  562. hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE
  563. , sizeof(METAFILEPICT));
  564. if (NULL==hMem)
  565. {
  566. DeleteMetaFile(hMF);
  567. return E_FAIL;
  568. }
  569. /*
  570. * Global lock only fails in PMODE if the selector is invalid
  571. * (like it was discarded) or references a 0 length segment,
  572. * neither of which can happen here.
  573. */
  574. pMF=(LPMETAFILEPICT)GlobalLock(hMem);
  575. pMF->hMF=hMF;
  576. pMF->mm=MM_ANISOTROPIC;
  577. //Insert the extents in MM_HIMETRIC units.
  578. /********* Use the extent rect, not the window rect *********/
  579. rc = m_RectExt;
  580. // GetClientRect(m_pCtrl->Window(), &rc);
  581. /************************************************************/
  582. RectConvertMappings(&rc, FALSE);
  583. pMF->xExt=rc.right;
  584. pMF->yExt=rc.bottom;
  585. GlobalUnlock(hMem);
  586. *phMem=hMem;
  587. return NOERROR;
  588. }
  589. /*
  590. * CPolyline::SendAdvise
  591. *
  592. * Purpose:
  593. * Calls the appropriate IOleClientSite or IAdviseSink member
  594. * function for various events such as closure, renaming, etc.
  595. *
  596. * Parameters:
  597. * uCode UINT OBJECTCODE_* identifying the notification.
  598. *
  599. * Return Value:
  600. * None
  601. */
  602. void CPolyline::SendAdvise(UINT uCode)
  603. {
  604. DWORD dwAspect=DVASPECT_CONTENT | DVASPECT_THUMBNAIL;
  605. switch (uCode)
  606. {
  607. case OBJECTCODE_SAVED:
  608. if (NULL!=m_pIOleAdviseHolder)
  609. m_pIOleAdviseHolder->SendOnSave();
  610. break;
  611. case OBJECTCODE_CLOSED:
  612. if (NULL!=m_pIOleAdviseHolder)
  613. m_pIOleAdviseHolder->SendOnClose();
  614. break;
  615. case OBJECTCODE_RENAMED:
  616. //Call IOleAdviseHolder::SendOnRename (later)
  617. break;
  618. case OBJECTCODE_SAVEOBJECT:
  619. if (m_fDirty && NULL!=m_pIOleClientSite)
  620. m_pIOleClientSite->SaveObject();
  621. m_fDirty=FALSE;
  622. break;
  623. case OBJECTCODE_DATACHANGED:
  624. m_fDirty=TRUE;
  625. //No flags are necessary here.
  626. if (NULL!=m_pIDataAdviseHolder) {
  627. m_pIDataAdviseHolder->SendOnDataChange(m_pImpIDataObject, 0, 0);
  628. }
  629. if ( ( NULL!=m_pIAdviseSink ) & (dwAspect & m_dwAdviseAspects)) {
  630. m_pIAdviseSink->OnViewChange(dwAspect & m_dwAdviseAspects, 0);
  631. }
  632. break;
  633. case OBJECTCODE_SHOWWINDOW:
  634. if (NULL!=m_pIOleClientSite)
  635. m_pIOleClientSite->OnShowWindow(TRUE);
  636. break;
  637. case OBJECTCODE_HIDEWINDOW:
  638. if (NULL!=m_pIOleClientSite)
  639. m_pIOleClientSite->OnShowWindow(FALSE);
  640. break;
  641. case OBJECTCODE_SHOWOBJECT:
  642. if (NULL!=m_pIOleClientSite)
  643. m_pIOleClientSite->ShowObject();
  644. break;
  645. }
  646. return;
  647. }
  648. /*
  649. * CPolyline::SendEvent
  650. *
  651. * Purpose:
  652. * Send an event to all connection points.
  653. *
  654. *
  655. * Parameters:
  656. * uEventType Event Type
  657. * dwParam Parameter to send with event.
  658. *
  659. * Return Value:
  660. * None
  661. */
  662. void CPolyline::SendEvent (
  663. IN UINT uEventType,
  664. IN DWORD dwParam
  665. )
  666. {
  667. INT i;
  668. // Don't send if container has frozen events
  669. if (m_fFreezeEvents)
  670. return;
  671. // Pass event to each connection point
  672. for (i=0; i<CONNECTION_POINT_CNT; i++) {
  673. m_ConnectionPoint[i].SendEvent(uEventType, dwParam);
  674. }
  675. }
  676. /*
  677. * CPolyline::InPlaceActivate
  678. *
  679. * Purpose:
  680. * Goes through all the steps of activating the Polyline as an
  681. * in-place object.
  682. *
  683. * Parameters:
  684. * pActiveSite LPOLECLIENTSITE of the active site we show in.
  685. * fIncludeUI BOOL controls whether we call UIActivate too.
  686. *
  687. * Return Value:
  688. * HRESULT Whatever error code is appropriate.
  689. */
  690. HRESULT CPolyline::InPlaceActivate(
  691. LPOLECLIENTSITE pActiveSite,
  692. BOOL fIncludeUI
  693. )
  694. {
  695. HRESULT hr;
  696. HWND hWndSite;
  697. HWND hWndHW;
  698. HWND hWndCtrl;
  699. RECT rcPos;
  700. RECT rcClip;
  701. OLEINPLACEFRAMEINFO frameInfo;
  702. if (NULL==pActiveSite)
  703. return E_POINTER;
  704. // If we already have a site, just handle UI
  705. if (NULL != m_pIOleIPSite) {
  706. if (fIncludeUI) {
  707. UIActivate();
  708. SetFocus(m_pCtrl->Window());
  709. }
  710. return NOERROR;
  711. }
  712. // Initialization, obtaining interfaces, OnInPlaceActivate.
  713. hr=pActiveSite->QueryInterface(IID_IOleInPlaceSite,
  714. (PPVOID)&m_pIOleIPSite);
  715. if (FAILED(hr))
  716. return hr;
  717. hr=m_pIOleIPSite->CanInPlaceActivate();
  718. if (NOERROR!=hr) {
  719. m_pIOleIPSite->Release();
  720. m_pIOleIPSite=NULL;
  721. return E_FAIL;
  722. }
  723. m_pIOleIPSite->OnInPlaceActivate();
  724. // Get the window context and create a window.
  725. m_pIOleIPSite->GetWindow(&hWndSite);
  726. frameInfo.cb=sizeof(OLEINPLACEFRAMEINFO);
  727. m_pIOleIPSite->GetWindowContext(&m_pIOleIPFrame,
  728. &m_pIOleIPUIWindow,
  729. &rcPos,
  730. &rcClip,
  731. &frameInfo);
  732. /*
  733. * Create the hatch window after we get a parent window. We
  734. * could not create the hatch window sooner because had nothing
  735. * to use for the parent.
  736. */
  737. m_pHW=new CHatchWin();
  738. if (NULL==m_pHW) {
  739. InPlaceDeactivate();
  740. return E_OUTOFMEMORY;
  741. }
  742. if (!m_pHW->Init(hWndSite, ID_HATCHWINDOW, NULL)) {
  743. InPlaceDeactivate();
  744. return E_OUTOFMEMORY;
  745. }
  746. hr=m_pImpIRunnableObject->Run(NULL);
  747. // Move the hatch window to the container window.
  748. hWndHW = m_pHW->Window();
  749. SetParent(hWndHW, hWndSite);
  750. // Move the Polyline window from the hidden dialog to hatch window
  751. hWndCtrl = m_pCtrl->Window();
  752. m_pHW->HwndAssociateSet(hWndCtrl);
  753. m_pHW->ChildSet(hWndCtrl);
  754. m_pHW->RectsSet(&rcPos, &rcClip); //Positions polyline
  755. ShowWindow(hWndHW, SW_SHOW);
  756. SendAdvise(OBJECTCODE_SHOWOBJECT);
  757. // Critical for accelerators to work initially.
  758. SetFocus(hWndCtrl);
  759. if (fIncludeUI)
  760. hr = UIActivate();
  761. else
  762. hr = NOERROR;
  763. /*
  764. * Since we don't have an Undo while in-place, tell the continer
  765. * to free it's undo state immediately.
  766. */
  767. m_pIOleIPSite->DiscardUndoState();
  768. return hr;
  769. }
  770. /*
  771. * CPolyline::InPlaceDeactivate
  772. *
  773. * Purpose:
  774. * Reverses all the activation steps from InPlaceActivate.
  775. *
  776. * Parameters:
  777. * None
  778. *
  779. * Return Value:
  780. * None
  781. */
  782. void CPolyline::InPlaceDeactivate(void)
  783. {
  784. UIDeactivate();
  785. if (NULL!=m_pHW)
  786. {
  787. ShowWindow(m_pHW->Window(), SW_HIDE);
  788. // Move the window to its foster home
  789. if (m_pCtrl->Window()) {
  790. SetParent(m_pCtrl->Window(), g_hWndFoster);
  791. }
  792. m_pHW->ChildSet(NULL);
  793. delete m_pHW;
  794. m_pHW=NULL;
  795. }
  796. ReleaseInterface(m_pIOleIPFrame);
  797. ReleaseInterface(m_pIOleIPUIWindow)
  798. if (NULL!=m_pIOleIPSite)
  799. {
  800. m_pIOleIPSite->OnInPlaceDeactivate();
  801. ReleaseInterface(m_pIOleIPSite);
  802. }
  803. return;
  804. }
  805. /*
  806. * CPolyline::UIActivate
  807. *
  808. * Purpose:
  809. * Goes through all the steps of activating the user interface of
  810. * Polyline as an in-place object.
  811. *
  812. * Parameters:
  813. * None
  814. *
  815. * Return Value:
  816. * HRESULT NOERROR or error code.
  817. */
  818. HRESULT CPolyline::UIActivate(void)
  819. {
  820. LPWSTR szUserType;
  821. // If already UI active, just return
  822. if (m_fUIActive)
  823. return NOERROR;
  824. m_fUIActive = TRUE;
  825. // Show hatched border only if enabled
  826. if (m_fHatch)
  827. m_pHW->ShowHatch(TRUE);
  828. // Call IOleInPlaceSite::UIActivate
  829. if (NULL!=m_pIOleIPSite)
  830. m_pIOleIPSite->OnUIActivate();
  831. // Set the active object
  832. szUserType = ResourceString(IDS_USERTYPE);
  833. if (NULL != m_pIOleIPFrame)
  834. m_pIOleIPFrame->SetActiveObject(m_pImpIOleIPActiveObject, szUserType);
  835. if (NULL != m_pIOleIPUIWindow)
  836. m_pIOleIPUIWindow->SetActiveObject(m_pImpIOleIPActiveObject, szUserType);
  837. // Negotiate border space. None needed.
  838. if (NULL != m_pIOleIPFrame)
  839. m_pIOleIPFrame->SetBorderSpace(NULL);
  840. if (NULL != m_pIOleIPUIWindow)
  841. m_pIOleIPUIWindow->SetBorderSpace(NULL);
  842. // Create the shared menu. No items added.
  843. if (NULL != m_pIOleIPFrame)
  844. m_pIOleIPFrame->SetMenu(NULL, NULL, m_pCtrl->Window());
  845. return NOERROR;
  846. }
  847. /*
  848. * CPolyline::UIDeactivate
  849. *
  850. * Purpose:
  851. * Reverses all the user interface activation steps from
  852. * UIActivate.
  853. *
  854. * Parameters:
  855. * None
  856. *
  857. * Return Value:
  858. * None
  859. */
  860. void CPolyline::UIDeactivate(void)
  861. {
  862. if (!m_fUIActive){
  863. return;
  864. }
  865. m_fUIActive=FALSE;
  866. // Hide hatched border if enabled
  867. if (m_fHatch && NULL != m_pHW ){
  868. m_pHW->ShowHatch(FALSE);
  869. }
  870. // Tell frame and UI Window we aren't active
  871. if (NULL!=m_pIOleIPFrame){
  872. m_pIOleIPFrame->SetActiveObject(NULL, NULL);
  873. }
  874. if (NULL!=m_pIOleIPUIWindow){
  875. m_pIOleIPUIWindow->SetActiveObject(NULL, NULL);
  876. }
  877. //We don't have any shared menu or tools to clean up.
  878. if (NULL!=m_pIOleIPSite){
  879. m_pIOleIPSite->OnUIDeactivate(FALSE);
  880. }
  881. }
  882. /*
  883. * AmbientGet
  884. *
  885. * Purpose:
  886. * Retrieves a specific ambient property into a VARIANT.
  887. *
  888. * Parameters:
  889. * dispID DISPID of the property to retrieve.
  890. * pva VARIANT * to fill with the new value.
  891. *
  892. * Return value
  893. * BOOL TRUE if the ambient was retrieved, FALSE
  894. * otherwise.
  895. */
  896. BOOL CPolyline::AmbientGet(DISPID dispID, VARIANT *pva)
  897. {
  898. HRESULT hr;
  899. DISPPARAMS dp;
  900. if (NULL==pva)
  901. return FALSE;
  902. if (NULL==m_pIDispatchAmbients)
  903. return FALSE;
  904. SETNOPARAMS(dp);
  905. hr=m_pIDispatchAmbients->Invoke(dispID,
  906. IID_NULL,
  907. LOCALE_USER_DEFAULT,
  908. DISPATCH_PROPERTYGET,
  909. &dp,
  910. pva,
  911. NULL,
  912. NULL);
  913. return SUCCEEDED(hr);
  914. }
  915. /*
  916. * AmbientsInitialize
  917. *
  918. * Purpose:
  919. * Attempts to retrieve the container's ambient properties
  920. * and initialize (or reinitialize) Polyline accordingly.
  921. *
  922. * Parameters:
  923. * dwWhich DWORD containing INITAMBIENT_... flags
  924. * describing which ambients to initialize.
  925. * This can be any combination.
  926. *
  927. * Return Value:
  928. * None
  929. */
  930. void CPolyline::AmbientsInitialize(DWORD dwWhich)
  931. {
  932. VARIANT va;
  933. LPFONT pIFont,pIFontClone;
  934. LPFONTDISP pIFontDisp;
  935. if (NULL == m_pIDispatchAmbients) {
  936. return;
  937. }
  938. /*
  939. * We need to retrieve these ambients into these variables:
  940. *
  941. * Ambient Property: Variable:
  942. * -----------------------------------------------
  943. * DISPID_AMBIENT_SHOWHATCHING m_fHatch
  944. * DISPID_AMBIENT_UIDEAD m_fUIDead
  945. * DISPID_AMBIENT_BACKCOLOR m_pCtrl...
  946. * DISPID_AMBIENT_FONT ..... m_pCtrl...
  947. * DISPID_AMBIENT_FORECOLOR m_pCtrl...
  948. * DISPID_AMBIENT_APPEARANCE m_pCtrl...
  949. * DISPID_AMBIENT_USERMODE m_pCtrl...
  950. */
  951. VariantInit(&va);
  952. if ((INITAMBIENT_SHOWHATCHING & dwWhich)
  953. &&AmbientGet(DISPID_AMBIENT_SHOWHATCHING, &va)) {
  954. m_fHatch=V_BOOL(&va);
  955. if (NULL != m_pHW)
  956. m_pHW->ShowHatch(m_fHatch && m_fUIActive);
  957. }
  958. if ((INITAMBIENT_UIDEAD & dwWhich)
  959. && AmbientGet(DISPID_AMBIENT_UIDEAD, &va)) {
  960. m_pCtrl->m_fUIDead = (BOOLEAN)V_BOOL(&va);
  961. }
  962. if ((INITAMBIENT_USERMODE & dwWhich)
  963. && AmbientGet(DISPID_AMBIENT_USERMODE, &va)) {
  964. m_pCtrl->m_fUserMode = (BOOLEAN)V_BOOL(&va);
  965. }
  966. if ((INITAMBIENT_APPEARANCE & dwWhich)
  967. && AmbientGet(DISPID_AMBIENT_APPEARANCE, &va)) {
  968. m_pCtrl->put_Appearance(V_I4(&va), TRUE);
  969. }
  970. if ((INITAMBIENT_BACKCOLOR & dwWhich)
  971. && AmbientGet(DISPID_AMBIENT_BACKCOLOR, &va)) {
  972. m_pCtrl->put_BackPlotColor(V_I4(&va), TRUE);
  973. }
  974. if ((INITAMBIENT_FORECOLOR & dwWhich)
  975. && AmbientGet(DISPID_AMBIENT_FORECOLOR, &va)) {
  976. m_pCtrl->put_FgndColor(V_I4(&va), TRUE);
  977. }
  978. if ((INITAMBIENT_FONT & dwWhich)
  979. && AmbientGet(DISPID_AMBIENT_FONT, &va)) {
  980. pIFontDisp = (LPFONTDISP)V_DISPATCH(&va);
  981. if (pIFontDisp != NULL) {
  982. if (SUCCEEDED(pIFontDisp->QueryInterface(IID_IFont, (PPVOID)&pIFont))) {
  983. if (SUCCEEDED(pIFont->Clone(&pIFontClone))) {
  984. m_pCtrl->put_Font(pIFontClone, TRUE);
  985. pIFontClone->Release();
  986. }
  987. pIFont->Release();
  988. }
  989. pIFontDisp->Release();
  990. }
  991. }
  992. if ((INITAMBIENT_RTL & dwWhich)
  993. && AmbientGet( DISPID_AMBIENT_RIGHTTOLEFT, &va)) {
  994. m_pCtrl->m_fRTL = (BOOLEAN)V_BOOL(&va);
  995. }
  996. }
  997. void
  998. CPolyline::Draw(
  999. HDC hDC,
  1000. HDC hAttribDC,
  1001. BOOL fMetafile,
  1002. BOOL fEntire,
  1003. LPRECT pRect)
  1004. {
  1005. RECT rc;
  1006. if (!fMetafile && !RectVisible(hDC, pRect))
  1007. return;
  1008. SetMapMode(hDC, MM_ANISOTROPIC);
  1009. //
  1010. // Always set up the window extents to the natural window size
  1011. // so the drawing routines can work in their normal dev coords
  1012. //
  1013. // Use client rect vs. extent rect for Zoom calculation.
  1014. // Zoom factor = prcPos / Extent, so pRect/ClientRect.
  1015. /********* Use the extent rect, not the window rect *********/
  1016. // Using rectExt makes Word printing correct at all zoom levels.
  1017. rc = m_RectExt;
  1018. // GetClientRect(m_pCtrl->Window(), &rc);
  1019. /************************************************************/
  1020. SetWindowOrgEx(hDC, 0, 0, NULL);
  1021. SetWindowExtEx(hDC, rc.right, rc.bottom, NULL);
  1022. SetViewportOrgEx(hDC, pRect->left, pRect->top, NULL);
  1023. SetViewportExtEx(hDC, pRect->right - pRect->left,
  1024. pRect->bottom - pRect->top, NULL);
  1025. m_pCtrl->InitView( g_hWndFoster);
  1026. m_pCtrl->Render(hDC, hAttribDC, fMetafile, fEntire, &rc);
  1027. return;
  1028. }