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.

230 lines
5.5 KiB

  1. #include "stock.h"
  2. #pragma hdrstop
  3. STDAPI BindCtx_CreateWithMode(DWORD grfMode, IBindCtx **ppbc)
  4. {
  5. ASSERTMSG(ppbc != NULL, "Caller must pass valid ppbc");
  6. HRESULT hr = CreateBindCtx(0, ppbc);
  7. if (SUCCEEDED(hr))
  8. {
  9. BIND_OPTS bo = {sizeof(bo), 0, grfMode, 0};
  10. hr = (*ppbc)->SetBindOptions(&bo);
  11. if (FAILED(hr))
  12. {
  13. ATOMICRELEASE(*ppbc);
  14. }
  15. }
  16. ASSERT(SUCCEEDED(hr) ? (*ppbc != NULL) : (*ppbc == NULL));
  17. return hr;
  18. }
  19. STDAPI_(DWORD) BindCtx_GetMode(IBindCtx *pbc, DWORD grfModeDefault)
  20. {
  21. if (pbc)
  22. {
  23. BIND_OPTS bo = {sizeof(bo)}; // Requires size filled in.
  24. if (SUCCEEDED(pbc->GetBindOptions(&bo)))
  25. grfModeDefault = bo.grfMode;
  26. }
  27. return grfModeDefault;
  28. }
  29. STDAPI_(BOOL) BindCtx_ContainsObject(IBindCtx *pbc, LPOLESTR psz)
  30. {
  31. BOOL bResult = FALSE;
  32. IUnknown *punk;
  33. if (pbc && SUCCEEDED(pbc->GetObjectParam(psz, &punk)))
  34. {
  35. bResult = TRUE;
  36. punk->Release();
  37. }
  38. return bResult;
  39. }
  40. class CDummyUnknown : public IOleWindow
  41. {
  42. public:
  43. CDummyUnknown() : _cRef(1), _hwnd(NULL) {}
  44. CDummyUnknown(HWND hwnd) : _cRef(1), _hwnd(hwnd) {}
  45. // IUnknown refcounting
  46. STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
  47. {
  48. static const QITAB qit[] = {
  49. QITABENT(CDummyUnknown, IOleWindow ),
  50. { 0 },
  51. };
  52. return QISearch(this, qit, riid, ppv);
  53. }
  54. STDMETHODIMP_(ULONG) AddRef(void)
  55. {
  56. return ++_cRef;
  57. }
  58. STDMETHODIMP_(ULONG) Release(void)
  59. {
  60. if (--_cRef > 0)
  61. return _cRef;
  62. delete this;
  63. return 0;
  64. }
  65. // IOleWindow
  66. STDMETHODIMP GetWindow(HWND * lphwnd) { *lphwnd = _hwnd; return _hwnd ? S_OK : E_NOTIMPL; }
  67. STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) { return E_NOTIMPL; }
  68. protected:
  69. LONG _cRef;
  70. HWND _hwnd;
  71. };
  72. STDAPI BindCtx_RegisterObjectParam(IBindCtx *pbcIn, LPCOLESTR pszRegister, IUnknown *punkRegister, IBindCtx **ppbcOut)
  73. {
  74. HRESULT hr = S_OK;
  75. *ppbcOut = pbcIn;
  76. if (pbcIn)
  77. pbcIn->AddRef();
  78. else
  79. hr = CreateBindCtx(0, ppbcOut);
  80. if (SUCCEEDED(hr))
  81. {
  82. IUnknown *punkDummy = NULL;
  83. if (!punkRegister)
  84. {
  85. punkRegister = punkDummy = new CDummyUnknown();
  86. hr = punkDummy ? S_OK : E_OUTOFMEMORY;
  87. }
  88. if (SUCCEEDED(hr))
  89. {
  90. hr = (*ppbcOut)->RegisterObjectParam((LPOLESTR)pszRegister, punkRegister);
  91. if (punkDummy)
  92. punkDummy->Release();
  93. }
  94. if (FAILED(hr))
  95. ATOMICRELEASE(*ppbcOut);
  96. }
  97. return hr;
  98. }
  99. STDAPI BindCtx_RegisterObjectParams(IBindCtx *pbcIn, BINDCTX_PARAM *rgParams, UINT cParams, IBindCtx **ppbcOut)
  100. {
  101. HRESULT hr = S_FALSE;
  102. // require at least one param
  103. ASSERT(cParams);
  104. *ppbcOut = 0;
  105. for (UINT i = 0; SUCCEEDED(hr) && i < cParams; i++)
  106. {
  107. // returns the in param if NON-NULL
  108. hr = BindCtx_RegisterObjectParam(pbcIn, rgParams[i].pszName, rgParams[i].pbcParam, &pbcIn);
  109. // we only keep the first addref()
  110. // and we return it
  111. if (SUCCEEDED(hr))
  112. {
  113. if (i == 0)
  114. *ppbcOut = pbcIn;
  115. else
  116. pbcIn->Release();
  117. }
  118. }
  119. if (FAILED(hr))
  120. {
  121. ATOMICRELEASE(*ppbcOut);
  122. }
  123. return hr;
  124. }
  125. STDAPI BindCtx_RegisterUIWindow(IBindCtx *pbcIn, HWND hwnd, IBindCtx **ppbcOut)
  126. {
  127. IUnknown *punkDummy = new CDummyUnknown(hwnd);
  128. HRESULT hr = punkDummy ? S_OK : E_OUTOFMEMORY;
  129. if (SUCCEEDED(hr))
  130. {
  131. hr = BindCtx_RegisterObjectParam(pbcIn, STR_DISPLAY_UI_DURING_BINDING, punkDummy, ppbcOut);
  132. punkDummy->Release();
  133. }
  134. else
  135. {
  136. *ppbcOut = 0;
  137. }
  138. return hr;
  139. }
  140. STDAPI_(HWND) BindCtx_GetUIWindow(IBindCtx *pbc)
  141. {
  142. HWND hwnd = NULL;
  143. IUnknown *punk;
  144. if (pbc && SUCCEEDED(pbc->GetObjectParam(STR_DISPLAY_UI_DURING_BINDING, &punk)))
  145. {
  146. IUnknown_GetWindow(punk, &hwnd);
  147. punk->Release();
  148. }
  149. return hwnd;
  150. }
  151. // dwTicksToAllow is time in msec relative to "now"
  152. STDAPI BindCtx_CreateWithTimeoutDelta(DWORD dwTicksToAllow, IBindCtx **ppbc)
  153. {
  154. HRESULT hr = CreateBindCtx(0, ppbc);
  155. if (SUCCEEDED(hr))
  156. {
  157. DWORD dwDeadline = GetTickCount() + dwTicksToAllow;
  158. if (0 == dwDeadline)
  159. dwDeadline = 1;
  160. BIND_OPTS bo = {sizeof(bo), 0, 0, dwDeadline};
  161. hr = (*ppbc)->SetBindOptions(&bo);
  162. if (FAILED(hr))
  163. {
  164. ATOMICRELEASE(*ppbc);
  165. }
  166. }
  167. ASSERT(SUCCEEDED(hr) ? (*ppbc != NULL) : (*ppbc == NULL));
  168. return hr;
  169. }
  170. // returns # of msec relative to "now" to allow the operation to take
  171. STDAPI BindCtx_GetTimeoutDelta(IBindCtx *pbc, DWORD *pdwTicksToAllow)
  172. {
  173. *pdwTicksToAllow = 0;
  174. HRESULT hr = E_FAIL;
  175. if (pbc)
  176. {
  177. BIND_OPTS bo = {sizeof(bo)}; // Requires size filled in.
  178. if (SUCCEEDED(pbc->GetBindOptions(&bo)))
  179. {
  180. if (bo.dwTickCountDeadline)
  181. {
  182. DWORD dwNow = GetTickCount();
  183. if (dwNow > bo.dwTickCountDeadline)
  184. {
  185. *pdwTicksToAllow = 0; // we have already elappsed the timeout, return 0
  186. }
  187. else
  188. {
  189. *pdwTicksToAllow = bo.dwTickCountDeadline - dwNow; // positive delta in the future
  190. }
  191. hr = S_OK;
  192. }
  193. }
  194. }
  195. return hr;
  196. }