void ComTypes.ITypeLib.GetLibAttr(out IntPtr ppTLibAttr) { // initialize out parameters ppTLibAttr = default; using (var typeLibAttrPtr = AddressableVariables.CreatePtrTo <ComTypes.TYPELIBATTR>()) { var hr = _this_Internal.GetLibAttr(typeLibAttrPtr.Address); if (ComHelper.HRESULT_FAILED(hr)) { HandleBadHRESULT(hr); } ppTLibAttr = typeLibAttrPtr.Value.Address; } }
void ComTypes.ITypeInfo.GetVarDesc(int index, out IntPtr ppVarDesc) { // initialize out parameters ppVarDesc = default; using (var varDescPtr = AddressableVariables.CreatePtrTo <ComTypes.VARDESC>()) { var hr = _this_Internal.GetVarDesc(index, varDescPtr.Address); if (ComHelper.HRESULT_FAILED(hr)) { HandleBadHRESULT(hr); } ppVarDesc = varDescPtr.Value.Address; // dereference the ptr, and take the contents address } }
void ComTypes.ITypeInfo.GetTypeAttr(out IntPtr ppTypeAttr) { // initialize out parameters ppTypeAttr = default; using (var typeAttrPtr = AddressableVariables.CreatePtrTo <ComTypes.TYPEATTR>()) { var hr = _this_Internal.GetTypeAttr(typeAttrPtr.Address); if (ComHelper.HRESULT_FAILED(hr)) { HandleBadHRESULT(hr); } ppTypeAttr = typeAttrPtr.Value.Address; // dereference the ptr, and take the contents address } }
public override int GetFuncDesc(int index, IntPtr ppFuncDesc) { var hr = _target_ITypeInfo.GetFuncDesc(index, ppFuncDesc); if (ComHelper.HRESULT_FAILED(hr)) { return(HandleBadHRESULT(hr)); } if (_target_ITypeInfoAlternate != null) { var pFuncDesc = StructHelper.ReadStructureUnsafe <IntPtr>(ppFuncDesc); var funcDesc = StructHelper.ReadStructureUnsafe <ComTypes.FUNCDESC>(pFuncDesc); // Populate wFuncFlags from the alternative typeinfo provided by VBA // The alternative typeinfo is not as useful as the main typeinfo for most things, but does expose wFuncFlags // The list of functions appears to be in the same order as the main typeinfo. using (var funcDescAlternatePtr = AddressableVariables.CreatePtrTo <ComTypes.FUNCDESC>()) { var hr2 = _target_ITypeInfoAlternate.GetFuncDesc(index, funcDescAlternatePtr.Address); if (!ComHelper.HRESULT_FAILED(hr2)) { var funcDescAlternate = funcDescAlternatePtr.Value.Value; // dereference the ptr, then the content //sanity check if (funcDescAlternate.memid == funcDesc.memid) { funcDesc.wFuncFlags = funcDescAlternate.wFuncFlags; } else { Debug.Assert(false, $"The sanity check failed; {nameof(funcDesc.memid)}: {funcDesc.memid} and {nameof(funcDescAlternate.memid)}: {funcDescAlternate.memid}"); } _target_ITypeInfoAlternate.ReleaseFuncDesc(funcDescAlternatePtr.Value.Address); RdMarshal.StructureToPtr(funcDesc, pFuncDesc, true); } } } return(hr); }
private void InitCommon() { using (var typeAttrPtr = AddressableVariables.CreatePtrTo <ComTypes.TYPEATTR>()) { var hr = _target_ITypeInfo.GetTypeAttr(typeAttrPtr.Address); if (!ComHelper.HRESULT_FAILED(hr)) { CachedAttributes = typeAttrPtr.Value.Value; // dereference the ptr, then the content var pTypeAttr = typeAttrPtr.Value.Address; // dereference the ptr, and take the contents address _target_ITypeInfo.ReleaseTypeAttr(pTypeAttr); // can release immediately as CachedAttributes is a copy } else { if (hr == (int)KnownComHResults.E_VBA_COMPILEERROR) { // If there is a compilation error outside of a procedure code block, the type information is not available for that component. // We detect this, via the E_VBA_COMPILEERROR error HasModuleScopeCompilationErrors = true; } // just mute the error and expose an empty type CachedAttributes = new ComTypes.TYPEATTR(); } } Funcs = new TypeInfoFunctionCollection(this, CachedAttributes); // Refer to AllVars XML docs for details AllVars = new TypeInfoVariablesCollection(this, CachedAttributes); if (CachedAttributes.typekind == ComTypes.TYPEKIND.TKIND_MODULE && HasVBEExtensions) { _consts = new TypeInfoConstantsCollection(this, CachedAttributes); } ImplementedInterfaces = new TypeInfoImplementedInterfacesCollection(this, CachedAttributes); // cache the container type library if it is available, else create a simulated one using (var typeLibPtr = AddressableVariables.Create <IntPtr>()) using (var containerTypeLibIndex = AddressableVariables.Create <int>()) { var hr = _target_ITypeInfo.GetContainingTypeLib(typeLibPtr.Address, containerTypeLibIndex.Address); if (!ComHelper.HRESULT_FAILED(hr)) { // We have to wrap the ITypeLib returned by GetContainingTypeLib _container = TypeApiFactory.GetTypeLibWrapper(typeLibPtr.Value, addRef: false); ContainerIndex = containerTypeLibIndex.Value; } else { if (hr == (int)KnownComHResults.E_NOTIMPL) { // it is acceptable for a type to not have a container, as types can be runtime generated (e.g. UserForm base classes) // When that is the case, the ITypeInfo responds with E_NOTIMPL // However, we create fake container to avoid errors from CLR when using those "uncontained" TypeInfo HasSimulatedContainer = true; var newContainer = new SimpleCustomTypeLibrary(); _container = newContainer; ContainerIndex = newContainer.Add(this); } else { throw new ArgumentException("Unrecognised error when getting ITypeInfo container: \n" + hr); } } } }