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.

220 lines
5.0 KiB

  1. #include "priv.h"
  2. #include "bandobj.h"
  3. UINT g_cfDeskBand = 0;
  4. UINT g_cfDeskBandState = 0;
  5. void InitCFDeskBand()
  6. {
  7. if (!g_cfDeskBand)
  8. g_cfDeskBand = RegisterClipboardFormat(TEXT("DeskBand"));
  9. if (!g_cfDeskBandState)
  10. g_cfDeskBandState = RegisterClipboardFormat(TEXT("DeskBandState"));
  11. }
  12. CBandDataObject::CBandDataObject()
  13. : _cRef(1)
  14. {
  15. InitCFDeskBand();
  16. }
  17. HRESULT CBandDataObject::Init(IUnknown* punkBand, IBandSite *pbs, DWORD dwBandID)
  18. {
  19. HRESULT hres = E_FAIL;
  20. _pstm = SHCreateMemStream(NULL, 0);
  21. if (_pstm) {
  22. IPersistStream *ppstm;
  23. punkBand->QueryInterface(IID_IPersistStream, (LPVOID*)&ppstm);
  24. if (ppstm) {
  25. LARGE_INTEGER li = {0};
  26. OleSaveToStream(ppstm, _pstm);
  27. _pstm->Seek(li, STREAM_SEEK_SET, NULL);
  28. ppstm->Release();
  29. // bandsite state flags
  30. _dwState = 0; // (if we fail just do w/o the state flags)
  31. if (pbs)
  32. pbs->QueryBand(dwBandID, NULL, &_dwState, NULL, 0);
  33. hres = S_OK;
  34. }
  35. }
  36. return hres;
  37. }
  38. CBandDataObject::~CBandDataObject()
  39. {
  40. if (_pstm)
  41. _pstm->Release();
  42. }
  43. ULONG CBandDataObject::AddRef()
  44. {
  45. _cRef++;
  46. return _cRef;
  47. }
  48. ULONG CBandDataObject::Release()
  49. {
  50. ASSERT(_cRef > 0);
  51. _cRef--;
  52. if (_cRef > 0)
  53. return _cRef;
  54. delete this;
  55. return 0;
  56. }
  57. HRESULT CBandDataObject::QueryInterface(REFIID riid, LPVOID * ppvObj)
  58. {
  59. if (IsEqualIID(riid, IID_IUnknown)
  60. || IsEqualIID(riid, IID_IDataObject))
  61. {
  62. *ppvObj = SAFECAST(this, IDataObject*);
  63. AddRef();
  64. return S_OK;
  65. }
  66. *ppvObj = NULL;
  67. return E_NOINTERFACE;
  68. }
  69. // *** IDataObject ***
  70. HRESULT CBandDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
  71. {
  72. HRESULT hres = E_FAIL;
  73. if (pformatetcIn->cfFormat == g_cfDeskBand)
  74. {
  75. if (pformatetcIn->tymed & TYMED_ISTREAM && EVAL(_pstm))
  76. {
  77. ASSERT(_pstm);
  78. pmedium->tymed = TYMED_ISTREAM;
  79. pmedium->pstm = _pstm; // no AddRef since we xfer ownership
  80. _pstm = NULL; // can only use it 1x (read causes seek)
  81. pmedium->pUnkForRelease = NULL;
  82. hres = S_OK;
  83. }
  84. }
  85. else if (pformatetcIn->cfFormat == g_cfDeskBandState)
  86. {
  87. if (pformatetcIn->tymed & TYMED_HGLOBAL)
  88. {
  89. pmedium->tymed = TYMED_HGLOBAL;
  90. pmedium->hGlobal = GlobalAlloc(GPTR, sizeof (DWORD));
  91. if (pmedium->hGlobal)
  92. {
  93. DWORD *pdw = (DWORD*)(pmedium->hGlobal);
  94. *pdw = _dwState;
  95. pmedium->pUnkForRelease = NULL;
  96. hres = S_OK;
  97. }
  98. else
  99. {
  100. hres = E_OUTOFMEMORY;
  101. }
  102. }
  103. }
  104. return hres;
  105. }
  106. HRESULT CBandDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
  107. {
  108. return E_NOTIMPL;
  109. }
  110. HRESULT CBandDataObject::QueryGetData(FORMATETC *pformatetc)
  111. {
  112. HRESULT hres = S_FALSE;
  113. // TODO: (reuse, perf) use rgfmtetc table lookup
  114. if ((pformatetc->cfFormat == g_cfDeskBand) &&
  115. (pformatetc->tymed & TYMED_ISTREAM) ||
  116. (pformatetc->cfFormat == g_cfDeskBandState) &&
  117. (pformatetc->tymed & TYMED_HGLOBAL))
  118. {
  119. hres = S_OK;
  120. }
  121. return hres;
  122. }
  123. HRESULT CBandDataObject::GetCanonicalFormatEtc(FORMATETC *pformatetcIn, FORMATETC *pformatetcOut)
  124. {
  125. *pformatetcOut = *pformatetcIn;
  126. return DATA_S_SAMEFORMATETC;
  127. }
  128. HRESULT CBandDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
  129. {
  130. return E_NOTIMPL;
  131. }
  132. HRESULT CBandDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
  133. {
  134. HRESULT hr = E_FAIL;
  135. if (dwDirection == DATADIR_GET)
  136. {
  137. FORMATETC rgfmtetc[] =
  138. {
  139. { g_cfDeskBand, NULL, 0, -1, TYMED_ISTREAM },
  140. { g_cfDeskBandState, NULL, 0, -1, TYMED_HGLOBAL },
  141. };
  142. hr = SHCreateStdEnumFmtEtc(ARRAYSIZE(rgfmtetc), rgfmtetc, ppenumFormatEtc);
  143. }
  144. return hr;
  145. }
  146. HRESULT CBandDataObject::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
  147. {
  148. return E_NOTIMPL;
  149. }
  150. HRESULT CBandDataObject::DUnadvise(DWORD dwConnection)
  151. {
  152. return E_NOTIMPL;
  153. }
  154. HRESULT CBandDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
  155. {
  156. return E_NOTIMPL;
  157. }
  158. //*** IDataObject_GetDeskBandState -- get band's bandsite state flags from BandDataObject
  159. // NOTES
  160. // 'paired' w/ DragBandState (inline in CBandDataObject::Init)
  161. DWORD IDataObject_GetDeskBandState(IDataObject *pdtobj)
  162. {
  163. DWORD dwState = 0; // (if we fail just do w/o the state flags)
  164. FORMATETC fmte = {g_cfDeskBandState, NULL, 0, -1, TYMED_HGLOBAL};
  165. STGMEDIUM stg;
  166. HRESULT hrTmp;
  167. hrTmp = pdtobj->GetData(&fmte, &stg);
  168. if (SUCCEEDED(hrTmp))
  169. {
  170. DWORD *p = (DWORD *)(stg.hGlobal);
  171. dwState = *p;
  172. ReleaseStgMedium(&stg);
  173. }
  174. return dwState;
  175. }