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.

352 lines
9.0 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 = NOERROR;
  55. RECT rc;
  56. RECTL rectBoundsDP;
  57. BOOL bMetafile = FALSE;
  58. BOOL bDeleteDC = FALSE;
  59. HDC hLocalICDev;
  60. //Delegate iconic and printed representations.
  61. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect)) {
  62. hr = m_pObj->m_pDefIViewObject->Draw(dwAspect, lindex
  63. , pvAspect, ptd, hICDev, hDC, pRectBounds, pRectWBounds
  64. , pfnContinue, dwContinue);
  65. } else {
  66. if ( NULL == hDC ) {
  67. hr = E_INVALIDARG;
  68. } else if ( NULL == pRectBounds ) {
  69. hr = E_POINTER;
  70. } else {
  71. if (hICDev == NULL) {
  72. hLocalICDev = CreateTargetDC(hDC, ptd);
  73. bDeleteDC = (hLocalICDev != hDC );
  74. } else {
  75. hLocalICDev = hICDev;
  76. }
  77. if ( NULL == hLocalICDev ) {
  78. hr = E_UNEXPECTED;
  79. } else {
  80. rectBoundsDP = *pRectBounds;
  81. bMetafile = GetDeviceCaps(hDC, TECHNOLOGY) == DT_METAFILE;
  82. if (!bMetafile) {
  83. ::LPtoDP ( hLocalICDev, (LPPOINT)&rectBoundsDP, 2);
  84. SaveDC ( hDC );
  85. }
  86. RECTFROMRECTL(rc, rectBoundsDP);
  87. m_pObj->Draw(hDC, hLocalICDev, FALSE, TRUE, &rc);
  88. if (bDeleteDC)
  89. ::DeleteDC(hLocalICDev);
  90. if (!bMetafile)
  91. RestoreDC(hDC, -1);
  92. hr = NOERROR;
  93. }
  94. }
  95. }
  96. return hr;
  97. }
  98. /*
  99. * CImpIViewObject::GetColorSet
  100. *
  101. * Purpose:
  102. * Retrieves the color palette used by the object.
  103. *
  104. * Parameters:
  105. * dwAspect DWORD aspect of interest.
  106. * lindex LONG piece of interest.
  107. * pvAspect LPVOID with extra information, always NULL.
  108. * ptd DVTARGETDEVICE * containing device info.
  109. * hICDev HDC containing the IC for the device.
  110. * ppColorSet LPLOGPALETTE * into which to return the
  111. * pointer to the palette in this color set.
  112. *
  113. * Return Value:
  114. * HRESULT NOERROR or a general error value.
  115. */
  116. STDMETHODIMP CImpIViewObject::GetColorSet(
  117. DWORD, // dwDrawAspect
  118. LONG, // lindex
  119. LPVOID, // pvAspect,
  120. DVTARGETDEVICE *, // ptd
  121. HDC, // hICDev,
  122. LPLOGPALETTE * /* ppColorSet */) {
  123. return ResultFromScode(E_NOTIMPL);
  124. }
  125. /*
  126. * CImpIViewObject::Freeze
  127. *
  128. * Purpose:
  129. * Freezes the view of a particular aspect such that data
  130. * changes do not affect the view.
  131. *
  132. * Parameters:
  133. * dwAspect DWORD aspect to freeze.
  134. * lindex LONG piece index under consideration.
  135. * pvAspect LPVOID for further information, always NULL.
  136. * pdwFreeze LPDWORD in which to return the key.
  137. *
  138. * Return Value:
  139. * HRESULT NOERROR or a general error value.
  140. */
  141. STDMETHODIMP CImpIViewObject::Freeze(DWORD dwAspect, LONG lindex
  142. , LPVOID pvAspect, LPDWORD pdwFreeze)
  143. {
  144. //Delegate anything for ICON or DOCPRINT aspects
  145. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  146. {
  147. return m_pObj->m_pDefIViewObject->Freeze(dwAspect, lindex
  148. , pvAspect, pdwFreeze);
  149. }
  150. if (dwAspect & m_pObj->m_dwFrozenAspects)
  151. {
  152. *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  153. return ResultFromScode(VIEW_S_ALREADY_FROZEN);
  154. }
  155. m_pObj->m_dwFrozenAspects |= dwAspect;
  156. if (NULL!=pdwFreeze)
  157. *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  158. return NOERROR;
  159. }
  160. /*
  161. * CImpIViewObject::Unfreeze
  162. *
  163. * Purpose:
  164. * Thaws an aspect frozen in ::Freeze. We expect that a container
  165. * will redraw us after freezing if necessary, so we don't send
  166. * any sort of notification here.
  167. *
  168. * Parameters:
  169. * dwFreeze DWORD key returned from ::Freeze.
  170. *
  171. * Return Value:
  172. * HRESULT NOERROR or a general error value.
  173. */
  174. STDMETHODIMP CImpIViewObject::Unfreeze(DWORD dwFreeze)
  175. {
  176. DWORD dwAspect=dwFreeze - FREEZE_KEY_OFFSET;
  177. //Delegate anything for ICON or DOCPRINT aspects
  178. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  179. m_pObj->m_pDefIViewObject->Unfreeze(dwFreeze);
  180. //The aspect to unfreeze is in the key.
  181. m_pObj->m_dwFrozenAspects &= ~(dwAspect);
  182. /*
  183. * Since we always kept our current data up to date, we don't
  184. * have to do anything thing here like requesting data again.
  185. * Because we removed dwAspect from m_dwFrozenAspects, Draw
  186. * will again use the current data.
  187. */
  188. return NOERROR;
  189. }
  190. /*
  191. * CImpIViewObject::SetAdvise
  192. *
  193. * Purpose:
  194. * Provides an advise sink to the view object enabling
  195. * notifications for a specific aspect.
  196. *
  197. * Parameters:
  198. * dwAspects DWORD describing the aspects of interest.
  199. * dwAdvf DWORD containing advise flags.
  200. * pIAdviseSink LPADVISESINK to notify.
  201. *
  202. * Return Value:
  203. * HRESULT NOERROR or a general error value.
  204. */
  205. STDMETHODIMP CImpIViewObject::SetAdvise(DWORD dwAspects, DWORD dwAdvf
  206. , LPADVISESINK pIAdviseSink)
  207. {
  208. //Pass anything with DVASPECT_ICON or _DOCPRINT to the handler.
  209. if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspects))
  210. {
  211. m_pObj->m_pDefIViewObject->SetAdvise(dwAspects, dwAdvf
  212. , pIAdviseSink);
  213. }
  214. //We continue because dwAspects may have more than one in it.
  215. if (NULL!=m_pObj->m_pIAdviseSink)
  216. m_pObj->m_pIAdviseSink->Release();
  217. m_pObj->m_pIAdviseSink=pIAdviseSink;
  218. m_pObj->m_dwAdviseAspects=dwAspects;
  219. m_pObj->m_dwAdviseFlags=dwAdvf;
  220. if (NULL!=m_pObj->m_pIAdviseSink)
  221. m_pObj->m_pIAdviseSink->AddRef();
  222. return NOERROR;
  223. }
  224. /*
  225. * CImpIViewObject::GetAdvise
  226. *
  227. * Purpose:
  228. * Returns the last known IAdviseSink seen by ::SetAdvise.
  229. *
  230. * Parameters:
  231. * pdwAspects LPDWORD in which to store the last
  232. * requested aspects.
  233. * pdwAdvf LPDWORD in which to store the last
  234. * requested flags.
  235. * ppIAdvSink LPADVISESINK * in which to store the
  236. * IAdviseSink.
  237. *
  238. * Return Value:
  239. * HRESULT NOERROR or a general error value.
  240. */
  241. STDMETHODIMP CImpIViewObject::GetAdvise(LPDWORD pdwAspects
  242. , LPDWORD pdwAdvf, LPADVISESINK *ppAdvSink)
  243. {
  244. if (NULL != ppAdvSink) {
  245. *ppAdvSink = m_pObj->m_pIAdviseSink;
  246. if (m_pObj->m_pIAdviseSink != NULL)
  247. m_pObj->m_pIAdviseSink->AddRef();
  248. }
  249. if (NULL != pdwAspects)
  250. *pdwAspects = m_pObj->m_dwAdviseAspects;
  251. if (NULL != pdwAdvf)
  252. *pdwAdvf = m_pObj->m_dwAdviseFlags;
  253. return NOERROR;
  254. }
  255. /*
  256. * CImpIViewObject::GetExtent
  257. *
  258. * Purpose:
  259. * Retrieves the extents of the object's display.
  260. *
  261. * Parameters:
  262. * dwAspect DWORD of the aspect of interest.
  263. * lindex LONG index of the piece of interest.
  264. * ptd DVTARGETDEVICE * with device information.
  265. * pszl LPSIZEL to the structure in which to return
  266. * the extents.
  267. *
  268. * Return Value:
  269. * HRESULT NOERROR or a general error value.
  270. */
  271. STDMETHODIMP CImpIViewObject::GetExtent(DWORD dwAspect, LONG lindex
  272. , DVTARGETDEVICE *ptd, LPSIZEL pszl)
  273. {
  274. RECT rc;
  275. if (!(DVASPECT_CONTENT & dwAspect))
  276. {
  277. return m_pObj->m_pDefIViewObject->GetExtent(dwAspect
  278. , lindex, ptd, pszl);
  279. }
  280. m_pObj->m_pImpIPolyline->RectGet(&rc);
  281. m_pObj->RectConvertMappings(&rc, FALSE);
  282. pszl->cx=rc.right-rc.left;
  283. pszl->cy=rc.bottom-rc.top;
  284. return NOERROR;
  285. }