script_com.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #pragma once
  2. extern bool g_ComErrorNotify;
  3. class ComObject;
  4. class ComEvent : public ObjectBase
  5. {
  6. DWORD mCookie = 0;
  7. ComObject *mObject;
  8. ITypeInfo *mTypeInfo = nullptr;
  9. IID mIID;
  10. IObject *mAhkObject = nullptr;
  11. TCHAR mPrefix[64];
  12. public:
  13. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  14. STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
  15. STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
  16. // IObject::Invoke() and Type() are unlikely to be called, since that would mean
  17. // the script has a reference to the object, which means either that the script
  18. // itself has implemented IConnectionPoint (and why would it?), or has used the
  19. // IEnumConnections interface to retrieve its own object (unlikely).
  20. //ResultType Invoke(IObject_Invoke_PARAMS_DECL); // ObjectBase::Invoke is sufficient.
  21. IObject_Type_Impl("ComEvent") // Unlikely to be called; see above.
  22. Object *Base() { return nullptr; }
  23. HRESULT Connect(ITypeInfo *tinfo = nullptr, IID *iid = nullptr);
  24. void SetPrefixOrSink(LPCTSTR pfx, IObject *ahkObject);
  25. ComEvent(ComObject *obj) : mObject(obj) { }
  26. ~ComEvent();
  27. friend class ComObject;
  28. };
  29. class ComObject : public ObjectBase
  30. {
  31. public:
  32. union
  33. {
  34. IDispatch *mDispatch;
  35. IUnknown *mUnknown;
  36. SAFEARRAY *mArray;
  37. void *mValPtr;
  38. __int64 mVal64; // Allow 64-bit values when ComObject is used as a VARIANT in 32-bit builds.
  39. };
  40. ComEvent *mEventSink;
  41. VARTYPE mVarType;
  42. enum { F_OWNVALUE = 1 };
  43. USHORT mFlags;
  44. enum
  45. {
  46. P_Ptr,
  47. // ComValueRef
  48. P___Item, // v2.0: Allows accessing a VT_BYREF value via comobj[].
  49. P___Value = P___Item, // v2.1: Alias to allow use with VAR_VIRTUAL_OBJ (ByRef parameters).
  50. };
  51. static ObjectMember sRefMembers[], sValueMembers[];
  52. static ObjectMemberMd sArrayMembers[];
  53. FResult SafeArray_Item(VariantParams &aParam, ExprTokenType *aNewValue, ResultToken *aResultToken);
  54. FResult set_SafeArray_Item(ExprTokenType &aNewValue, VariantParams &aParam) { return SafeArray_Item(aParam, &aNewValue, nullptr); }
  55. FResult get_SafeArray_Item(ResultToken &aResultToken, VariantParams &aParam) { return SafeArray_Item(aParam, nullptr, &aResultToken); }
  56. FResult SafeArray_Clone(IObject *&aRetVal);
  57. FResult SafeArray_Enum(optl<int>, IObject *&aRetVal);
  58. FResult SafeArray_MaxIndex(optl<UINT> aDims, int &aRetVal);
  59. FResult SafeArray_MinIndex(optl<UINT> aDims, int &aRetVal);
  60. ResultType Invoke(IObject_Invoke_PARAMS_DECL);
  61. void Invoke(ResultToken &aResultToken, int aID, int aFlags, ExprTokenType *aParam[], int aParamCount);
  62. LPTSTR Type();
  63. Object *Base();
  64. IObject_DebugWriteProperty_Def;
  65. void ToVariant(VARIANT &aVar)
  66. {
  67. aVar.vt = mVarType;
  68. aVar.llVal = mVal64;
  69. // Caller handles this if needed:
  70. //if (VT_DISPATCH == mVarType && mDispatch)
  71. // mDispatch->AddRef();
  72. }
  73. ComObject(IDispatch *pdisp)
  74. : mVal64((__int64)pdisp), mVarType(VT_DISPATCH), mEventSink(NULL), mFlags(0) { }
  75. ComObject(__int64 llVal, VARTYPE vt, USHORT flags = 0)
  76. : mVal64(llVal), mVarType(vt), mEventSink(NULL), mFlags(flags) { }
  77. ~ComObject()
  78. {
  79. if ((VT_DISPATCH == mVarType || VT_UNKNOWN == mVarType) && mUnknown)
  80. {
  81. if (mEventSink)
  82. {
  83. mEventSink->Connect(FALSE);
  84. if (mEventSink) // i.e. it wasn't fully released as a result of calling Unadvise().
  85. mEventSink->mObject = nullptr;
  86. }
  87. mUnknown->Release();
  88. }
  89. else if ((mVarType & (VT_BYREF|VT_ARRAY)) == VT_ARRAY && (mFlags & F_OWNVALUE))
  90. {
  91. SafeArrayDestroy(mArray);
  92. }
  93. else if (mVarType == VT_BSTR && (mFlags & F_OWNVALUE))
  94. {
  95. SysFreeString((BSTR)mValPtr);
  96. }
  97. }
  98. };
  99. class ComEnum : public EnumBase
  100. {
  101. IEnumVARIANT *penum;
  102. bool cheat;
  103. public:
  104. ResultType Next(Var *aOutput, Var *aOutputType);
  105. ComEnum(IEnumVARIANT *enm);
  106. ~ComEnum()
  107. {
  108. penum->Release();
  109. }
  110. };
  111. class ComArrayEnum : public EnumBase
  112. {
  113. ComObject *mArrayObject;
  114. void *mData;
  115. long mLBound, mUBound;
  116. UINT mElemSize;
  117. VARTYPE mType;
  118. bool mIndexMode;
  119. long mOffset = -1;
  120. ComArrayEnum(ComObject *aObj, void *aData, long aLBound, long aUBound, UINT aElemSize, VARTYPE aType, bool aIndexMode)
  121. : mArrayObject(aObj), mData(aData), mLBound(aLBound), mUBound(aUBound), mElemSize(aElemSize), mType(aType), mIndexMode(aIndexMode)
  122. {
  123. }
  124. public:
  125. static HRESULT Begin(ComObject *aArrayObject, ComArrayEnum *&aOutput, int aMode);
  126. ResultType Next(Var *aVar1, Var *aVar2);
  127. ~ComArrayEnum();
  128. };
  129. // Adapts an AutoHotkey enumerator object to the IEnumVARIANT COM interface.
  130. class EnumComCompat : public IEnumVARIANT, public IServiceProvider
  131. {
  132. IObject *mEnum;
  133. int mRefCount;
  134. bool mCheat;
  135. public:
  136. EnumComCompat(IObject *enumObj) : mEnum(enumObj), mRefCount(1), mCheat(false) {}
  137. ~EnumComCompat() { mEnum->Release(); }
  138. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
  139. STDMETHODIMP_(ULONG) AddRef();
  140. STDMETHODIMP_(ULONG) Release();
  141. STDMETHODIMP Next(ULONG celt, /*out*/ VARIANT *rgVar, /*out*/ ULONG *pCeltFetched);
  142. STDMETHODIMP Skip(ULONG celt);
  143. STDMETHODIMP Reset();
  144. STDMETHODIMP Clone(/*out*/ IEnumVARIANT **ppEnum);
  145. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
  146. };
  147. enum TTVArgType
  148. {
  149. VariantIsValue,
  150. VariantIsAllocatedString,
  151. VariantIsVarRef
  152. };
  153. void TokenToVariant(ExprTokenType &aToken, VARIANT &aVar, TTVArgType *aVarIsArg = FALSE);
  154. HRESULT TokenToVarType(ExprTokenType &aToken, VARTYPE aVarType, void *apValue, bool aCallerIsComValue = false);
  155. void ComError(HRESULT, ResultToken &, LPTSTR = _T(""), EXCEPINFO* = NULL);
  156. bool SafeSetTokenObject(ExprTokenType &aToken, IObject *aObject);