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.

464 lines
11 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. iviewobj.cpp
  5. Abstract:
  6. Implementation of the IViewObject interface.
  7. --*/
  8. #include "polyline.h"
  9. #include "unihelpr.h"
  10. #include "unkhlpr.h"
  11. /*
  12. * CImpIViewObject interface implementation
  13. */
  14. IMPLEMENT_CONTAINED_INTERFACE(CPolyline, CImpIViewObject)
  15. /*
  16. * CImpIViewObject::Draw
  17. *
  18. * Purpose:
  19. * Draws the object on the given hDC specifically for the requested
  20. * aspect, device, and within the appropriate bounds.
  21. *
  22. * Parameters:
  23. * dwAspect DWORD aspect to draw.
  24. * lindex LONG index of the piece to draw.
  25. * pvAspect LPVOID for extra information, always NULL.
  26. * ptd DVTARGETDEVICE * containing device
  27. * information.
  28. * hICDev HDC containing the IC for the device.
  29. * hDC HDC on which to draw.
  30. * pRectBounds LPCRECTL describing the rectangle in which
  31. * to draw.
  32. * pRectWBounds LPCRECTL describing the placement rectangle
  33. * if part of what you draw is another metafile.
  34. * pfnContinue Function to call periodically during
  35. * long repaints.
  36. * dwContinue DWORD extra information to pass to the
  37. * pfnContinue.
  38. *
  39. * Return Value:
  40. * HRESULT NOERROR or a general error value.
  41. */
  42. STDMETHODIMP CImpIViewObject::Draw(
  43. DWORD dwAspect,
  44. LONG lindex,
  45. LPVOID pvAspect,
  46. DVTARGETDEVICE *ptd,
  47. HDC hICDev,
  48. HDC hDC,
  49. LPCRECTL pRectBounds,
  50. LPCRECTL pRectWBounds,
  51. BOOL (CALLBACK *pfnContinue) (DWORD_PTR),
  52. DWORD_PTR dwContinue )
  53. {
  54. HRESULT hr = S_OK;
  55. RECT rc;
  56. RECTL rectBoundsDP;
  57. BOOL bMetafile = FALSE;
  58. BOOL bDeleteDC = FALSE;
  59. HDC hLocalICDev = NULL;
  60. //
  61. //Delegate iconic and printed representations.
  62. //
  63. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect)) {
  64. try {
  65. hr = m_pObj->m_pDefIViewObject->Draw(dwAspect,
  66. lindex,
  67. pvAspect,
  68. ptd,
  69. hICDev,
  70. hDC,
  71. pRectBounds,
  72. pRectWBounds,
  73. pfnContinue,
  74. dwContinue);
  75. } catch (...) {
  76. hr = E_POINTER;
  77. }
  78. }
  79. else {
  80. if ( NULL == hDC ) {
  81. hr = E_INVALIDARG;
  82. }
  83. else if ( NULL == pRectBounds ) {
  84. hr = E_POINTER;
  85. }
  86. else {
  87. try {
  88. if (hICDev == NULL) {
  89. hLocalICDev = CreateTargetDC(hDC, ptd);
  90. bDeleteDC = (hLocalICDev != hDC );
  91. }
  92. else {
  93. hLocalICDev = hICDev;
  94. }
  95. if ( NULL == hLocalICDev ) {
  96. hr = E_UNEXPECTED;
  97. }
  98. else {
  99. rectBoundsDP = *pRectBounds;
  100. bMetafile = GetDeviceCaps(hDC, TECHNOLOGY) == DT_METAFILE;
  101. if (!bMetafile) {
  102. ::LPtoDP ( hLocalICDev, (LPPOINT)&rectBoundsDP, 2);
  103. SaveDC ( hDC );
  104. }
  105. rc.top = rectBoundsDP.top;
  106. rc.left = rectBoundsDP.left;
  107. rc.bottom = rectBoundsDP.bottom;
  108. rc.right = rectBoundsDP.right;
  109. m_pObj->Draw(hDC, hLocalICDev, FALSE, TRUE, &rc);
  110. hr = S_OK;
  111. }
  112. } catch (...) {
  113. hr = E_POINTER;
  114. }
  115. }
  116. }
  117. if (bDeleteDC)
  118. ::DeleteDC(hLocalICDev);
  119. if (!bMetafile)
  120. RestoreDC(hDC, -1);
  121. return hr;
  122. }
  123. /*
  124. * CImpIViewObject::GetColorSet
  125. *
  126. * Purpose:
  127. * Retrieves the color palette used by the object.
  128. *
  129. * Parameters:
  130. * dwAspect DWORD aspect of interest.
  131. * lindex LONG piece of interest.
  132. * pvAspect LPVOID with extra information, always NULL.
  133. * ptd DVTARGETDEVICE * containing device info.
  134. * hICDev HDC containing the IC for the device.
  135. * ppColorSet LPLOGPALETTE * into which to return the
  136. * pointer to the palette in this color set.
  137. *
  138. * Return Value:
  139. * HRESULT NOERROR or a general error value.
  140. */
  141. STDMETHODIMP CImpIViewObject::GetColorSet(
  142. DWORD, // dwDrawAspect
  143. LONG, // lindex
  144. LPVOID, // pvAspect,
  145. DVTARGETDEVICE *, // ptd
  146. HDC, // hICDev,
  147. LPLOGPALETTE * /* ppColorSet */
  148. )
  149. {
  150. return E_NOTIMPL;
  151. }
  152. /*
  153. * CImpIViewObject::Freeze
  154. *
  155. * Purpose:
  156. * Freezes the view of a particular aspect such that data
  157. * changes do not affect the view.
  158. *
  159. * Parameters:
  160. * dwAspect DWORD aspect to freeze.
  161. * lindex LONG piece index under consideration.
  162. * pvAspect LPVOID for further information, always NULL.
  163. * pdwFreeze LPDWORD in which to return the key.
  164. *
  165. * Return Value:
  166. * HRESULT NOERROR or a general error value.
  167. */
  168. STDMETHODIMP CImpIViewObject::Freeze(
  169. DWORD dwAspect,
  170. LONG lindex,
  171. LPVOID pvAspect,
  172. LPDWORD pdwFreeze
  173. )
  174. {
  175. HRESULT hr = S_OK;
  176. //Delegate anything for ICON or DOCPRINT aspects
  177. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  178. {
  179. try {
  180. hr = m_pObj->m_pDefIViewObject->Freeze(dwAspect, lindex, pvAspect, pdwFreeze);
  181. } catch (...) {
  182. hr = E_POINTER;
  183. }
  184. return hr;
  185. }
  186. if (dwAspect & m_pObj->m_dwFrozenAspects)
  187. {
  188. hr = VIEW_S_ALREADY_FROZEN;
  189. try {
  190. *pdwFreeze = dwAspect + FREEZE_KEY_OFFSET;
  191. } catch (...) {
  192. hr = E_POINTER;
  193. }
  194. return hr;
  195. }
  196. m_pObj->m_dwFrozenAspects |= dwAspect;
  197. hr = S_OK;
  198. if (NULL != pdwFreeze) {
  199. try {
  200. *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  201. } catch (...) {
  202. hr = E_POINTER;
  203. }
  204. }
  205. return hr;
  206. }
  207. /*
  208. * CImpIViewObject::Unfreeze
  209. *
  210. * Purpose:
  211. * Thaws an aspect frozen in ::Freeze. We expect that a container
  212. * will redraw us after freezing if necessary, so we don't send
  213. * any sort of notification here.
  214. *
  215. * Parameters:
  216. * dwFreeze DWORD key returned from ::Freeze.
  217. *
  218. * Return Value:
  219. * HRESULT NOERROR or a general error value.
  220. */
  221. STDMETHODIMP CImpIViewObject::Unfreeze(DWORD dwFreeze)
  222. {
  223. DWORD dwAspect = dwFreeze - FREEZE_KEY_OFFSET;
  224. //Delegate anything for ICON or DOCPRINT aspects
  225. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  226. m_pObj->m_pDefIViewObject->Unfreeze(dwFreeze);
  227. //The aspect to unfreeze is in the key.
  228. m_pObj->m_dwFrozenAspects &= ~(dwAspect);
  229. /*
  230. * Since we always kept our current data up to date, we don't
  231. * have to do anything thing here like requesting data again.
  232. * Because we removed dwAspect from m_dwFrozenAspects, Draw
  233. * will again use the current data.
  234. */
  235. return NOERROR;
  236. }
  237. /*
  238. * CImpIViewObject::SetAdvise
  239. *
  240. * Purpose:
  241. * Provides an advise sink to the view object enabling
  242. * notifications for a specific aspect.
  243. *
  244. * Parameters:
  245. * dwAspects DWORD describing the aspects of interest.
  246. * dwAdvf DWORD containing advise flags.
  247. * pIAdviseSink LPADVISESINK to notify.
  248. *
  249. * Return Value:
  250. * HRESULT NOERROR or a general error value.
  251. */
  252. STDMETHODIMP CImpIViewObject::SetAdvise(
  253. DWORD dwAspects,
  254. DWORD dwAdvf,
  255. LPADVISESINK pIAdviseSink
  256. )
  257. {
  258. HRESULT hr = S_OK;
  259. try {
  260. //Pass anything with DVASPECT_ICON or _DOCPRINT to the handler.
  261. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspects))
  262. {
  263. hr = m_pObj->m_pDefIViewObject->SetAdvise(dwAspects, dwAdvf, pIAdviseSink);
  264. }
  265. } catch (...) {
  266. return E_POINTER;
  267. }
  268. //We continue because dwAspects may have more than one in it.
  269. if (NULL != m_pObj->m_pIAdviseSink) {
  270. m_pObj->m_pIAdviseSink->Release();
  271. m_pObj->m_pIAdviseSink = NULL;
  272. }
  273. hr = S_OK;
  274. try {
  275. if (NULL != pIAdviseSink) {
  276. pIAdviseSink->AddRef();
  277. }
  278. } catch (...) {
  279. hr = E_POINTER;
  280. }
  281. if (SUCCEEDED(hr)) {
  282. m_pObj->m_pIAdviseSink = pIAdviseSink;
  283. m_pObj->m_dwAdviseAspects = dwAspects;
  284. m_pObj->m_dwAdviseFlags = dwAdvf;
  285. }
  286. return hr;
  287. }
  288. /*
  289. * CImpIViewObject::GetAdvise
  290. *
  291. * Purpose:
  292. * Returns the last known IAdviseSink seen by ::SetAdvise.
  293. *
  294. * Parameters:
  295. * pdwAspects LPDWORD in which to store the last
  296. * requested aspects.
  297. * pdwAdvf LPDWORD in which to store the last
  298. * requested flags.
  299. * ppIAdvSink LPADVISESINK * in which to store the
  300. * IAdviseSink.
  301. *
  302. * Return Value:
  303. * HRESULT NOERROR or a general error value.
  304. */
  305. STDMETHODIMP CImpIViewObject::GetAdvise(
  306. LPDWORD pdwAspects,
  307. LPDWORD pdwAdvf,
  308. LPADVISESINK *ppAdvSink
  309. )
  310. {
  311. HRESULT hr = S_OK;
  312. BOOL fRefAdded = FALSE;
  313. try {
  314. if (NULL != ppAdvSink) {
  315. *ppAdvSink = m_pObj->m_pIAdviseSink;
  316. if (m_pObj->m_pIAdviseSink != NULL) {
  317. m_pObj->m_pIAdviseSink->AddRef();
  318. fRefAdded = TRUE;
  319. }
  320. }
  321. if (NULL != pdwAspects) {
  322. *pdwAspects = m_pObj->m_dwAdviseAspects;
  323. }
  324. if (NULL != pdwAdvf) {
  325. *pdwAdvf = m_pObj->m_dwAdviseFlags;
  326. }
  327. } catch (...) {
  328. hr = E_POINTER;
  329. }
  330. if (FAILED(hr)) {
  331. if (fRefAdded) {
  332. m_pObj->m_pIAdviseSink->Release();
  333. }
  334. }
  335. return hr;
  336. }
  337. /*
  338. * CImpIViewObject::GetExtent
  339. *
  340. * Purpose:
  341. * Retrieves the extents of the object's display.
  342. *
  343. * Parameters:
  344. * dwAspect DWORD of the aspect of interest.
  345. * lindex LONG index of the piece of interest.
  346. * ptd DVTARGETDEVICE * with device information.
  347. * pszl LPSIZEL to the structure in which to return
  348. * the extents.
  349. *
  350. * Return Value:
  351. * HRESULT NOERROR or a general error value.
  352. */
  353. STDMETHODIMP CImpIViewObject::GetExtent(
  354. DWORD dwAspect,
  355. LONG lindex,
  356. DVTARGETDEVICE *ptd,
  357. LPSIZEL pszl
  358. )
  359. {
  360. RECT rc;
  361. HRESULT hr = S_OK;
  362. if (!(DVASPECT_CONTENT & dwAspect))
  363. {
  364. try {
  365. hr = m_pObj->m_pDefIViewObject->GetExtent(dwAspect, lindex, ptd, pszl);
  366. } catch (...) {
  367. hr = E_POINTER;
  368. }
  369. return hr;
  370. }
  371. #ifdef USE_SAMPLE_IPOLYLIN10
  372. m_pObj->m_pImpIPolyline->RectGet(&rc);
  373. #else
  374. CopyRect(&rc, &m_pObj->m_RectExt);
  375. #endif
  376. m_pObj->RectConvertMappings(&rc, FALSE);
  377. hr = S_OK;
  378. try {
  379. pszl->cx = rc.right-rc.left;
  380. pszl->cy = rc.bottom-rc.top;
  381. } catch (...) {
  382. hr = E_POINTER;
  383. }
  384. return hr;
  385. }