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.

203 lines
6.1 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Helper utilities for implementing automation interfaces.
  4. // Note that autbaseimp.h makes use of these utilities. If you inherit from
  5. // CAutBaseImp then this is all implementated for you and you probably won't
  6. // need to use this file directly.
  7. //
  8. #pragma once
  9. #include <limits>
  10. //////////////////////////////////////////////////////////////////////
  11. // Aggregation controlling unknown
  12. // Class that implements the controlling unknown for aggregation.
  13. // The interface should be returned only from CoCreate.
  14. // This object will keep the reference count and call Destroy on its parent when 0.
  15. // The parent should then delete the CAutUnknown and itself.
  16. // QI only returns IUnknown and IDispatch from the parent object.
  17. class CAutUnknown : public IUnknown
  18. {
  19. public:
  20. // Virtual base class. Inherit from CAutUnknown::CAutUnknownParent if you want to use an object with CAutUnknown.
  21. class CAutUnknownParent
  22. {
  23. public:
  24. virtual void Destroy() = 0;
  25. };
  26. CAutUnknown();
  27. // Call Init immediately. The parent passes pointers to itself for both params.
  28. // I didn't put this on the constructor because VC warns about using 'this' in
  29. // a member initializer list.
  30. void Init(CAutUnknownParent *pParent, IDispatch *pDispatch);
  31. // IUnknown
  32. STDMETHOD(QueryInterface)(const IID &iid, void **ppv);
  33. STDMETHOD_(ULONG, AddRef)();
  34. STDMETHOD_(ULONG, Release)();
  35. private:
  36. // Data
  37. long m_cRef;
  38. CAutUnknownParent *m_pParent;
  39. IDispatch *m_pDispatch;
  40. };
  41. //////////////////////////////////////////////////////////////////////
  42. // IDispatch implemented from type table
  43. // Max params to any method -- increase this as needed
  44. const int g_cDispatchMaxParams = 5;
  45. // Parameters
  46. enum AutDispatchType { ADT_None, ADT_Long, ADT_Interface, ADT_Bstr };
  47. struct AutDispatchParam
  48. {
  49. AutDispatchType adt;
  50. bool fOptional; // not relevant for return parameters
  51. const IID *piid; // only relevant if ADT_INTERFACE: specifies the IID of the desired interface (ignored for return parameters)
  52. };
  53. #define ADPARAM_NORETURN ADT_None, false, &IID_NULL
  54. // Methods
  55. struct AutDispatchMethod
  56. {
  57. DISPID dispid;
  58. const WCHAR *pwszName;
  59. AutDispatchParam adpReturn;
  60. AutDispatchParam rgadpParams[g_cDispatchMaxParams]; // terminate with ADT_NONE for last param
  61. };
  62. // terminate an array of methods with dispid DISPID_UNKNOWN
  63. // Decoded parameters -- read (write for return) void * as pointer to type specified in methods
  64. union AutDispatchDecodedParam
  65. {
  66. LONG lVal; // ADT_Long
  67. void *iVal; // ADT_Interface (cast to the interface specified by piid)
  68. BSTR bstrVal; // ADT_Bstr
  69. };
  70. struct AutDispatchDecodedParams
  71. {
  72. void *pvReturn; // set to NULL by AutDispatchInvokeDecode if no return specified or no return requested by caller, otherwise set to location to write return
  73. AutDispatchDecodedParam params[g_cDispatchMaxParams];
  74. };
  75. // Helper functions
  76. HRESULT AutDispatchGetIDsOfNames(
  77. const AutDispatchMethod *pMethods,
  78. REFIID riid,
  79. LPOLESTR __RPC_FAR *rgszNames,
  80. UINT cNames,
  81. LCID lcid,
  82. DISPID __RPC_FAR *rgDispId);
  83. HRESULT AutDispatchInvokeDecode(
  84. const AutDispatchMethod *pMethods,
  85. AutDispatchDecodedParams *pDecodedParams,
  86. DISPID dispIdMember,
  87. REFIID riid,
  88. LCID lcid,
  89. WORD wFlags,
  90. DISPPARAMS __RPC_FAR *pDispParams,
  91. VARIANT __RPC_FAR *pVarResult,
  92. UINT __RPC_FAR *puArgErr,
  93. const WCHAR *pwszTraceTargetType,
  94. IUnknown *punkTraceTargetObject);
  95. void AutDispatchInvokeFree(
  96. const AutDispatchMethod *pMethods,
  97. AutDispatchDecodedParams *pDecodedParams,
  98. DISPID dispIdMember,
  99. REFIID riid);
  100. HRESULT AutDispatchHrToException(
  101. const AutDispatchMethod *pMethods,
  102. DISPID dispIdMember,
  103. REFIID riid,
  104. HRESULT hr,
  105. EXCEPINFO __RPC_FAR *pExcepInfo);
  106. // Implementation of IDispatch for the standard Load method on objects.
  107. // Dummy implementation--does nothing.
  108. // Assign Load a dispid that probably won't conflict with the wrapped object's methods.
  109. // Probably it doesn't matter if two methods have the same dispid, but theoretically some scripting engine could
  110. // be weirded out by that and hide a method with the same dispid that is exposed after the real object is loaded.
  111. const DISPID g_dispidLoad = 10000000;
  112. // Return S_OK and the dispid if this is a call to load.
  113. HRESULT AutLoadDispatchGetIDsOfNames(
  114. REFIID riid,
  115. LPOLESTR __RPC_FAR *rgszNames,
  116. UINT cNames,
  117. LCID lcid,
  118. DISPID __RPC_FAR *rgDispId);
  119. // Returns S_OK if this is a call to load.
  120. HRESULT AutLoadDispatchInvoke(
  121. bool *pfUseOleAut,
  122. DISPID dispIdMember,
  123. REFIID riid,
  124. LCID lcid,
  125. WORD wFlags,
  126. DISPPARAMS __RPC_FAR *pDispParams,
  127. VARIANT __RPC_FAR *pVarResult,
  128. EXCEPINFO __RPC_FAR *pExcepInfo,
  129. UINT __RPC_FAR *puArgErr);
  130. //////////////////////////////////////////////////////////////////////
  131. // Miscellaneous little things
  132. inline LONG ClipLongRange(LONG lVal, LONG lMin, LONG lMax) { return lVal < lMin
  133. ? lMin
  134. : (lVal > lMax ? lMax : lVal); }
  135. // Trim the range of a LONG to the range of another data type.
  136. // �� compiler bug? need an extra unused parameter of the template type
  137. template<class T>
  138. LONG ClipLongRangeToType(LONG lVal, T t) { return ClipLongRange(lVal, std::numeric_limits<T>::min(), std::numeric_limits<T>::max()); }
  139. const UINT g_uiRefTimePerMillisecond = 10000;
  140. // Conversion between tempo normally represented in floating point and integers used by
  141. // scripts that may not handle floating point numbers.
  142. // 100 corresponds to 1 (no change), 1 corresponds to .01 (1/100th as fast), 10000 corresponds to 100 (100X as fast)
  143. const float g_fltTempoScale = 100.0;
  144. inline float
  145. ConvertToTempo(LONG lTempo)
  146. {
  147. return lTempo / g_fltTempoScale;
  148. }
  149. inline LONG
  150. ConvertFromTempo(double dblTempo)
  151. {
  152. LONG lTempo = static_cast<LONG>(dblTempo * g_fltTempoScale + .5);
  153. return lTempo ? lTempo : 1;
  154. }
  155. // Returns a proper VB boolean value (0 for false, -1 for true)
  156. inline LONG
  157. BoolForVB(bool f) { return f ? VARIANT_TRUE : VARIANT_FALSE; }
  158. // Convert from one set of flags into another
  159. struct FlagMapEntry
  160. {
  161. LONG lSrc;
  162. DWORD dwDest;
  163. };
  164. DWORD MapFlags(LONG lFlags, const FlagMapEntry *pfm);
  165. HRESULT SendVolumePMsg(LONG lVolume, LONG lDuration, DWORD dwPChannel, IDirectMusicGraph *pGraph, IDirectMusicPerformance *pPerf, short *pnNewVolume);