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.

232 lines
5.7 KiB

  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // CBitmapImgCtx
  4. //
  5. // Implement IImgCtx for drawing out of a bitmap
  6. //
  7. // WARNING: Incomplete implementation -- just barely enough to keep
  8. // listview happy. Should not be exposed to anyone other than listview.
  9. //
  10. //////////////////////////////////////////////////////////////////////////
  11. #include "ctlspriv.h"
  12. #include <iimgctx.h>
  13. class CBitmapImgCtx : public IImgCtx
  14. {
  15. public:
  16. // *** IUnknown methods ***
  17. STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppv);
  18. STDMETHODIMP_(ULONG) AddRef(void);
  19. STDMETHODIMP_(ULONG) Release(void);
  20. // *** IImgCtx methods ***
  21. STDMETHODIMP Load(LPCWSTR pszUrl, DWORD dwFlags);
  22. STDMETHODIMP SelectChanges(ULONG ulChgOn, ULONG ulChgOff, BOOL fSignal);
  23. STDMETHODIMP SetCallback(PFNIMGCTXCALLBACK pfn, void * pvPrivateData);
  24. STDMETHODIMP Disconnect();
  25. STDMETHODIMP GetUpdateRects(LPRECT prc, LPRECT prcImg, LPLONG pcrc);
  26. STDMETHODIMP GetStateInfo(PULONG pulState, LPSIZE psize, BOOL fClearChanges);
  27. STDMETHODIMP GetPalette(HPALETTE *phpal);
  28. STDMETHODIMP Draw(HDC hdc, LPRECT prcBounds);
  29. STDMETHODIMP Tile(HDC hdc, LPPOINT pptBackOrg, LPRECT prcClip, LPSIZE psize);
  30. STDMETHODIMP StretchBlt(HDC hdc, int dstX, int dstY, int dstXE, int dstYE, int srcX, int srcY, int srcXE, int srcYE, DWORD dwROP);
  31. public:
  32. CBitmapImgCtx() : _cRef(1) { }
  33. BOOL Initialize(HBITMAP hbm);
  34. protected:
  35. ~CBitmapImgCtx()
  36. {
  37. if (_hbr) DeleteObject(_hbr);
  38. }
  39. // Keep _cRef as first member so we can coalesce
  40. // with ILVRange's IUnknown implementation
  41. int _cRef;
  42. HBRUSH _hbr; // Bitmap pattern brush
  43. SIZE _sizBmp; // Size of original bitmap
  44. PFNIMGCTXCALLBACK _pfnCallback;
  45. LPVOID _pvRefCallback;
  46. };
  47. STDAPI_(IImgCtx *) CBitmapImgCtx_Create(HBITMAP hbm)
  48. {
  49. CBitmapImgCtx *pbic = new CBitmapImgCtx();
  50. if (pbic && !pbic->Initialize(hbm))
  51. {
  52. pbic->Release();
  53. pbic = NULL;
  54. }
  55. return pbic;
  56. }
  57. // CBitmapImgCtx::Initialize
  58. BOOL CBitmapImgCtx::Initialize(HBITMAP hbm)
  59. {
  60. BOOL fSuccess = FALSE;
  61. _hbr = CreatePatternBrush(hbm);
  62. if (_hbr)
  63. {
  64. BITMAP bm;
  65. if (GetObject(hbm, sizeof(bm), &bm))
  66. {
  67. _sizBmp.cx = bm.bmWidth;
  68. _sizBmp.cy = bm.bmHeight;
  69. fSuccess = TRUE;
  70. }
  71. }
  72. return fSuccess;
  73. }
  74. // IUnknown::QueryInterface
  75. HRESULT CBitmapImgCtx::QueryInterface(REFIID iid, void **ppv)
  76. {
  77. if (IsEqualIID(iid, IID_IImgCtx) || IsEqualIID(iid, IID_IUnknown))
  78. {
  79. *ppv = SAFECAST(this, IImgCtx *);
  80. }
  81. else
  82. {
  83. *ppv = NULL;
  84. return E_NOINTERFACE;
  85. }
  86. _cRef++;
  87. return NOERROR;
  88. }
  89. // IUnknown::AddRef
  90. ULONG CBitmapImgCtx::AddRef()
  91. {
  92. return ++_cRef;
  93. }
  94. // IUnknown::Release
  95. ULONG CBitmapImgCtx::Release()
  96. {
  97. if (--_cRef)
  98. return _cRef;
  99. delete this;
  100. return 0;
  101. }
  102. // IImgCtx::Load
  103. HRESULT CBitmapImgCtx::Load(LPCWSTR pszUrl, DWORD dwFlags)
  104. {
  105. ASSERT(0); // Listview should never call this
  106. return E_NOTIMPL;
  107. }
  108. // IImgCtx::SelectChanges
  109. HRESULT CBitmapImgCtx::SelectChanges(ULONG ulChgOn, ULONG ulChgOff, BOOL fSignal)
  110. {
  111. // Listview always calls with exactly these parameters
  112. ASSERT(ulChgOn == IMGCHG_COMPLETE);
  113. ASSERT(ulChgOff == 0);
  114. ASSERT(fSignal == TRUE);
  115. // Listview always calls after setting the callback
  116. ASSERT(_pfnCallback);
  117. _pfnCallback(this, _pvRefCallback);
  118. return S_OK;
  119. }
  120. // IImgCtx::SetCallback
  121. HRESULT CBitmapImgCtx::SetCallback(PFNIMGCTXCALLBACK pfn, void * pvPrivateData)
  122. {
  123. _pfnCallback = pfn;
  124. _pvRefCallback = pvPrivateData;
  125. return S_OK;
  126. }
  127. // IImgCtx::Disconnect
  128. HRESULT CBitmapImgCtx::Disconnect()
  129. {
  130. ASSERT(0); // Listview should never call this
  131. return E_NOTIMPL;
  132. }
  133. // IImgCtx::GetUpdateRects
  134. HRESULT CBitmapImgCtx::GetUpdateRects(LPRECT prc, LPRECT prcImg, LPLONG pcrc)
  135. {
  136. ASSERT(0); // Listview should never call this
  137. return E_NOTIMPL;
  138. }
  139. // IImgCtx::GetStateInfo
  140. HRESULT CBitmapImgCtx::GetStateInfo(PULONG pulState, LPSIZE psize, BOOL fClearChanges)
  141. {
  142. *pulState = IMGCHG_COMPLETE;
  143. *psize = _sizBmp;
  144. return S_OK;
  145. }
  146. // IImgCtx::GetPalette
  147. HRESULT CBitmapImgCtx::GetPalette(HPALETTE *phpal)
  148. {
  149. *phpal = NULL;
  150. return S_OK;
  151. }
  152. // IImgCtx::Draw
  153. //
  154. // Drawing is a special case of tiling where only one tile's worth
  155. // gets drawn. Listview (our only caller) is careful never to ask
  156. // for more than one tile's worth, so we can just forward straight
  157. // to IImgCtx::Tile().
  158. HRESULT CBitmapImgCtx::Draw(HDC hdc, LPRECT prcBounds)
  159. {
  160. POINT pt = { prcBounds->left, prcBounds->top };
  161. ASSERT(prcBounds->right - prcBounds->left <= _sizBmp.cx);
  162. ASSERT(prcBounds->bottom - prcBounds->top <= _sizBmp.cy);
  163. return Tile(hdc, &pt, prcBounds, NULL);
  164. }
  165. // IImgCtx::Tile
  166. HRESULT CBitmapImgCtx::Tile(HDC hdc, LPPOINT pptBackOrg, LPRECT prcClip, LPSIZE psize)
  167. {
  168. ASSERT(psize == NULL); // Listview always passes NULL
  169. POINT pt;
  170. if (SetBrushOrgEx(hdc, pptBackOrg->x, pptBackOrg->y, &pt))
  171. {
  172. FillRect(hdc, prcClip, _hbr);
  173. SetBrushOrgEx(hdc, pt.x, pt.y, NULL);
  174. }
  175. // Nobody checks the return value
  176. return S_OK;
  177. }
  178. // IImgCtx::StretchBlt
  179. HRESULT CBitmapImgCtx::StretchBlt(HDC hdc, int dstX, int dstY, int dstXE, int dstYE, int srcX, int srcY, int srcXE, int srcYE, DWORD dwROP)
  180. {
  181. ASSERT(0); // Listview should never call this
  182. return E_NOTIMPL;
  183. }