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.

258 lines
8.0 KiB

  1. #ifndef __ATL_IDISPATCH_H__
  2. #define __ATL_IDISPATCH_H__
  3. #include "unicpp/stdafx.h"
  4. extern LCID g_lcidLocale;
  5. #pragma pack(push, _ATL_PACKING)
  6. #ifndef ATL_NO_NAMESPACE
  7. namespace ATL
  8. {
  9. #endif // ATL_NO_NAMESPACE
  10. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor = 1, WORD wMinor = 0, class tihclass = CComTypeInfoHolder>
  11. class ATL_NO_VTABLE CShell32AtlIDispatch
  12. : public IOleObjectImpl<T>
  13. {
  14. public:
  15. CShell32AtlIDispatch();
  16. ~CShell32AtlIDispatch();
  17. // *** IDispatch ***
  18. virtual STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr);
  19. virtual STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
  20. virtual STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid);
  21. // *** IProvideClassInfo ***
  22. virtual STDMETHODIMP GetClassInfo(ITypeInfo** pptinfo);
  23. // *** IOleObject ***
  24. virtual STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus);
  25. virtual STDMETHODIMP DoVerbUIActivate(LPCRECT prcPosRect, HWND hwndParent, HWND hwnd);
  26. virtual STDMETHODIMP TranslateAcceleratorPriv(T * pThis, MSG *pMsg, IOleClientSite * pocs);
  27. virtual STDMETHODIMP PrivateQI(REFIID iid, void ** ppvObject) = 0;
  28. protected:
  29. // Helper functions;
  30. ITypeInfo * _pClassTypeInfo; // ITypeInfo of class
  31. IFileSearchBand * _pdisp; // This will not contain a ref because it's equal to 'this'.
  32. };
  33. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  34. CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::CShell32AtlIDispatch()
  35. {
  36. // This allocator should have zero inited the memory, so assert the member variables are empty.
  37. ASSERT(!_pClassTypeInfo);
  38. }
  39. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  40. CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::~CShell32AtlIDispatch()
  41. {
  42. if (_pClassTypeInfo)
  43. _pClassTypeInfo->Release();
  44. // _pdisp doesn't have a ref so it's OK if it's not NULL.
  45. }
  46. // *** IProvideClassInfo ***
  47. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  48. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::GetClassInfo(ITypeInfo ** ppTI)
  49. {
  50. if (!_pClassTypeInfo)
  51. GetTypeInfoFromLibId(LANGIDFROMLCID(g_lcidLocale), LIBID_Shell32, 1, 0, *pclsid, &_pClassTypeInfo);
  52. if (_pClassTypeInfo)
  53. {
  54. _pClassTypeInfo->AddRef();
  55. *ppTI = _pClassTypeInfo;
  56. return S_OK;
  57. }
  58. *ppTI = NULL;
  59. return E_FAIL;
  60. }
  61. // *** IDispatch ***
  62. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  63. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** ppITypeInfo)
  64. {
  65. HRESULT hr = S_OK;
  66. *ppITypeInfo = NULL;
  67. if (0 != itinfo)
  68. return(TYPE_E_ELEMENTNOTFOUND);
  69. //Load a type lib if we don't have the information already.
  70. if (NULL == *ppITypeInfo)
  71. {
  72. ITypeInfo * pITIDisp;
  73. hr = GetTypeInfoFromLibId(lcid, LIBID_Shell32, 1, 0, *piid, &pITIDisp);
  74. if (SUCCEEDED(hr))
  75. {
  76. HRESULT hrT;
  77. HREFTYPE hrefType;
  78. // All our IDispatch implementations are DUAL. GetTypeInfoOfGuid
  79. // returns the ITypeInfo of the IDispatch-part only. We need to
  80. // find the ITypeInfo for the dual interface-part.
  81. //
  82. hrT = pITIDisp->GetRefTypeOfImplType(0xffffffff, &hrefType);
  83. if (SUCCEEDED(hrT))
  84. hrT = pITIDisp->GetRefTypeInfo(hrefType, ppITypeInfo);
  85. ASSERT(SUCCEEDED(hrT));
  86. pITIDisp->Release();
  87. }
  88. }
  89. return hr;
  90. }
  91. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  92. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::GetIDsOfNames(REFIID // riid
  93. , LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
  94. {
  95. ITypeInfo* pInfo;
  96. HRESULT hr = GetTypeInfo(0, lcid, &pInfo);
  97. if (pInfo != NULL)
  98. {
  99. hr = pInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
  100. pInfo->Release();
  101. }
  102. return hr;
  103. }
  104. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  105. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
  106. {
  107. HRESULT hr = E_FAIL;
  108. DISPPARAMS dispparams = {0};
  109. if (!pdispparams)
  110. pdispparams = &dispparams; // otherwise OLE Fails when passed NULL.
  111. // make sure we have an interface to hand off to Invoke
  112. if (NULL == _pdisp)
  113. {
  114. hr = PrivateQI(*piid, (LPVOID*)&_pdisp);
  115. ASSERT(SUCCEEDED(hr));
  116. // don't hold a refcount on ourself
  117. _pdisp->Release();
  118. }
  119. ITypeInfo * pITypeInfo;
  120. hr = GetTypeInfo(0, lcid, &pITypeInfo);
  121. if (SUCCEEDED(hr))
  122. {
  123. //Clear exceptions
  124. SetErrorInfo(0L, NULL);
  125. hr = pITypeInfo->Invoke(_pdisp, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  126. pITypeInfo->Release();
  127. }
  128. return hr;
  129. }
  130. #define DW_MISC_STATUS (OLEMISC_SETCLIENTSITEFIRST | OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_RECOMPOSEONRESIZE | \
  131. OLEMISC_CANTLINKINSIDE | OLEMISC_INSIDEOUT)
  132. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  133. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
  134. {
  135. *pdwStatus = DW_MISC_STATUS;
  136. return S_OK;
  137. }
  138. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  139. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::DoVerbUIActivate(LPCRECT prcPosRect, HWND hwndParent, HWND hwnd)
  140. {
  141. HRESULT hr = IOleObjectImpl<T>::DoVerbUIActivate(prcPosRect, hwndParent);
  142. if (hwnd)
  143. ::SetFocus(hwnd);
  144. return hr;
  145. }
  146. template <class T, const GUID* pclsid, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
  147. HRESULT CShell32AtlIDispatch<T, pclsid, piid, plibid, 1, 0, tihclass>::TranslateAcceleratorPriv(T * pThis, MSG *pMsg, IOleClientSite * pocs)
  148. {
  149. HRESULT hr = S_FALSE;
  150. if (!EVAL(pMsg))
  151. return E_INVALIDARG;
  152. hr = pThis->T::TranslateAcceleratorInternal(pMsg, pocs);
  153. if (FAILED(hr))
  154. {
  155. if (WM_KEYDOWN == pMsg->message)
  156. {
  157. switch (pMsg->wParam)
  158. {
  159. // We can't handle RETURN because the script wants that
  160. // for post and other reasons
  161. //case VK_RETURN:
  162. case VK_ESCAPE:
  163. case VK_END:
  164. case VK_HOME:
  165. case VK_LEFT:
  166. case VK_UP:
  167. case VK_RIGHT:
  168. case VK_DOWN:
  169. case VK_DELETE:
  170. if (TranslateMessage(pMsg))
  171. {
  172. DispatchMessage(pMsg);
  173. hr = S_OK;
  174. }
  175. break;
  176. case VK_TAB:
  177. {
  178. CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(pocs);
  179. if (EVAL(spSite))
  180. hr = spSite->TranslateAccelerator(pMsg, 0);
  181. }
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. if (S_OK != hr)
  188. {
  189. // We didn't handle it so give our base class a chances.
  190. hr = pThis->IOleInPlaceActiveObjectImpl<T>::TranslateAccelerator(pMsg);
  191. }
  192. }
  193. return hr;
  194. }
  195. #ifndef ATL_NO_NAMESPACE
  196. }; //namespace ATL
  197. #endif // ATL_NO_NAMESPACE
  198. #endif // __ATL_IDISPATCH_H__