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.

252 lines
7.7 KiB

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