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.

218 lines
4.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /* File: oadisp.cpp
  3. Description: Provides reusable implementation of IDispatch.
  4. Revision History:
  5. Date Description Programmer
  6. -------- --------------------------------------------------- ----------
  7. 05/22/97 Initial creation. BrianAu
  8. */
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include "pch.h"
  11. #pragma hdrstop
  12. #include "oadisp.h"
  13. OleAutoDispatch::OleAutoDispatch(
  14. VOID
  15. ) : m_pObject(NULL),
  16. m_pTypeInfo(NULL)
  17. {
  18. }
  19. OleAutoDispatch::OleAutoDispatch(
  20. IDispatch *pObject,
  21. REFIID riidTypeLib,
  22. REFIID riidDispInterface,
  23. LPCTSTR pszTypeLib
  24. ) : m_pObject(NULL),
  25. m_pTypeInfo(NULL),
  26. m_strTypeLib(pszTypeLib)
  27. {
  28. Initialize(pObject, riidTypeLib, riidDispInterface, pszTypeLib);
  29. }
  30. OleAutoDispatch::~OleAutoDispatch(
  31. VOID
  32. )
  33. {
  34. if (NULL != m_pTypeInfo)
  35. {
  36. m_pTypeInfo->Release();
  37. }
  38. }
  39. HRESULT
  40. OleAutoDispatch::Initialize(
  41. IDispatch *pObject,
  42. REFIID riidTypeLib,
  43. REFIID riidDispInterface,
  44. LPCTSTR pszTypeLib
  45. )
  46. {
  47. HRESULT hr = S_FALSE; // Assume already initialized.
  48. if (NULL == m_pObject)
  49. {
  50. //
  51. // Note that we DO NOT AddRef the object pointer.
  52. // We assume that the object will outlive the OleAutoDispatch.
  53. // If you do, you can get into a circular reference problem where
  54. // the object pointed to by pObject is the container for *this.
  55. //
  56. m_pObject = pObject;
  57. m_idTypeLib = riidTypeLib;
  58. m_idDispInterface = riidDispInterface;
  59. m_strTypeLib = pszTypeLib;
  60. hr = S_OK;
  61. }
  62. return hr;
  63. }
  64. HRESULT
  65. OleAutoDispatch::GetIDsOfNames(
  66. REFIID riid,
  67. OLECHAR **rgszNames,
  68. UINT cNames,
  69. LCID lcid,
  70. DISPID *rgDispId
  71. )
  72. {
  73. HRESULT hr;
  74. ITypeInfo *pTI;
  75. if (IID_NULL != riid)
  76. {
  77. return DISP_E_UNKNOWNINTERFACE;
  78. }
  79. hr = GetTypeInfo(0, lcid, &pTI);
  80. if (SUCCEEDED(hr))
  81. {
  82. hr = DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispId);
  83. pTI->Release();
  84. }
  85. return hr;
  86. }
  87. HRESULT
  88. OleAutoDispatch::GetTypeInfo(
  89. UINT iTInfo,
  90. LCID lcid,
  91. ITypeInfo **ppTypeInfo
  92. )
  93. {
  94. HRESULT hr = NOERROR;
  95. ITypeLib *pTypeLib;
  96. ITypeInfo **ppTI;
  97. if (0 != iTInfo)
  98. return TYPE_E_ELEMENTNOTFOUND;
  99. if (NULL == ppTypeInfo)
  100. return E_INVALIDARG;
  101. *ppTypeInfo = NULL;
  102. switch(PRIMARYLANGID(lcid))
  103. {
  104. case LANG_NEUTRAL:
  105. case LANG_ENGLISH:
  106. ppTI = &m_pTypeInfo;
  107. break;
  108. default:
  109. return DISP_E_UNKNOWNLCID;
  110. }
  111. if (NULL == *ppTI)
  112. {
  113. hr = LoadRegTypeLib(m_idTypeLib,
  114. 1,
  115. 0,
  116. PRIMARYLANGID(lcid),
  117. &pTypeLib);
  118. if (FAILED(hr))
  119. {
  120. switch(PRIMARYLANGID(lcid))
  121. {
  122. case LANG_NEUTRAL:
  123. case LANG_ENGLISH:
  124. hr = LoadTypeLib(m_strTypeLib, &pTypeLib);
  125. break;
  126. default:
  127. break;
  128. }
  129. }
  130. if (SUCCEEDED(hr))
  131. {
  132. hr = pTypeLib->GetTypeInfoOfGuid(m_idDispInterface, ppTI);
  133. pTypeLib->Release();
  134. }
  135. }
  136. if (SUCCEEDED(hr))
  137. {
  138. (*ppTI)->AddRef();
  139. *ppTypeInfo = *ppTI;
  140. }
  141. return hr;
  142. }
  143. HRESULT
  144. OleAutoDispatch::GetTypeInfoCount(
  145. UINT *pctinfo
  146. )
  147. {
  148. //
  149. // 1 = "We implement GetTypeInfo"
  150. //
  151. *pctinfo = 1;
  152. return NOERROR;
  153. }
  154. HRESULT
  155. OleAutoDispatch::Invoke(
  156. DISPID dispIdMember,
  157. REFIID riid,
  158. LCID lcid,
  159. WORD wFlags,
  160. DISPPARAMS *pDispParams,
  161. VARIANT *pVarResult,
  162. EXCEPINFO *pExcepInfo,
  163. UINT *puArgErr
  164. )
  165. {
  166. HRESULT hr;
  167. ITypeInfo *pTI;
  168. if (IID_NULL != riid)
  169. {
  170. return DISP_E_UNKNOWNINTERFACE;
  171. }
  172. hr = GetTypeInfo(0, lcid, &pTI);
  173. if (SUCCEEDED(hr))
  174. {
  175. hr = pTI->Invoke(m_pObject,
  176. dispIdMember,
  177. wFlags,
  178. pDispParams,
  179. pVarResult,
  180. pExcepInfo,
  181. puArgErr);
  182. pTI->Release();
  183. }
  184. return hr;
  185. }