internal static ITypeLibWrapper FromVBProject(IVBProject vbProject) { using (var references = vbProject.References) { // Now we've got the references object, we can read the internal object structure to grab the ITypeLib var internalReferencesObj = StructHelper.ReadComObjectStructure <VBEReferencesObj>(references.Target); return(TypeApiFactory.GetTypeLibWrapper(internalReferencesObj._typeLib, addRef: true)); } }
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); } } } }