/// <summary> /// Collect information /// </summary> private void Collect() { // Remember all the interface name to coclass name mapping Hashtable interfaceToCoClassMapping = new Hashtable(); // // For every coclass // int nCount = m_typeLib.GetTypeInfoCount(); for (int n = 0; n < nCount; ++n) { TypeInfo type = m_typeLib.GetTypeInfo(n); // // Walk the list of implemented interfaces // using (TypeAttr attr = type.GetTypeAttr()) { if (attr.typekind == TypeLibTypes.Interop.TYPEKIND.TKIND_COCLASS) { DefaultInterfaceInfo defaultInterfaceInfo = new DefaultInterfaceInfo(); defaultInterfaceInfo.coclass = type; defaultInterfaceInfo.coclassName = type.GetDocumentation(); for (int m = 0; m < attr.cImplTypes; ++m) { TypeLibTypes.Interop.IMPLTYPEFLAGS flags = type.GetImplTypeFlags(m); bool bDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; // For invalid default interfaces, such as // coclass MyObj // { // [default] interface IUnknown; // interface IA; // } // to use the first valid interface, which is IA; // if (!bDefault) continue; bool bSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = type.GetRefType(m); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { // Skip IUnknown & IDispatch if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) continue; // Skip non-dispatch interfaces that doesn't derive from IUnknown if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl)) continue; string name = typeImpl.GetDocumentation(); if (bSource) { // Default source interface if (bDefault || // If explicitly stated as default, use that defaultInterfaceInfo.defaultSourceInterface == null) // otherwise, try to use the first one { defaultInterfaceInfo.defaultSourceInterface = typeImpl; defaultInterfaceInfo.defaultSourceInterfaceName = name; } } else { // Default interface if (bDefault || // If explicitly stated as default, use that defaultInterfaceInfo.defaultInterface == null) // otherwise, try to use the first one { defaultInterfaceInfo.defaultInterface = typeImpl; defaultInterfaceInfo.defaultInterfaceName = name; } } } } // // Walk through the list of implemented interfaces again. This time we remember all the implemented interfaces (including base) // for (int m = 0; m < attr.cImplTypes; ++m) { TypeInfo typeImpl = type.GetRefType(m); string name = typeImpl.GetDocumentation(); while (typeImpl != null) { // If we arleady seen this interface if (interfaceToCoClassMapping.Contains(name)) { // and if it is for a different interface if ((string)interfaceToCoClassMapping[name] != defaultInterfaceInfo.coclassName) { // Set the name to null so that we know we've seen other interfaces interfaceToCoClassMapping[name] = null; } } else { interfaceToCoClassMapping.Add(name, defaultInterfaceInfo.coclassName); } TypeAttr attrImpl = typeImpl.GetTypeAttr(); if (attrImpl.cImplTypes == 1) typeImpl = typeImpl.GetRefType(0); else typeImpl = null; } } // We do allow coclass that doesn't have any 'valid' default interfaces to have a class interface // For example, // coclass MyObject { // [default] interface IUnknown; // } m_defaultInterfaceInfoList.Add(defaultInterfaceInfo); } } } foreach (DefaultInterfaceInfo defaultInterfaceInfo in m_defaultInterfaceInfoList) { bool isExclusive = true; if (defaultInterfaceInfo.defaultInterface != null) { if (interfaceToCoClassMapping.Contains(defaultInterfaceInfo.defaultInterfaceName)) { if (interfaceToCoClassMapping[defaultInterfaceInfo.defaultInterfaceName] == null) { isExclusive = false; } } defaultInterfaceInfo.isExclusive = isExclusive; } } }
/// <summary> /// Collect information /// </summary> private void Collect() { // Remember all the interface name to coclass name mapping Hashtable interfaceToCoClassMapping = new Hashtable(); // // For every coclass // int nCount = m_typeLib.GetTypeInfoCount(); for (int n = 0; n < nCount; ++n) { TypeInfo type = m_typeLib.GetTypeInfo(n); // // Walk the list of implemented interfaces // using (TypeAttr attr = type.GetTypeAttr()) { if (attr.typekind == TYPEKIND.TKIND_COCLASS) { DefaultInterfaceInfo defaultInterfaceInfo = new DefaultInterfaceInfo(); defaultInterfaceInfo.coclass = type; defaultInterfaceInfo.coclassName = type.GetDocumentation(); for (int m = 0; m < attr.cImplTypes; ++m) { IMPLTYPEFLAGS flags = type.GetImplTypeFlags(m); bool bDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; // For invalid default interfaces, such as // coclass MyObj // { // [default] interface IUnknown; // interface IA; // } // to use the first valid interface, which is IA; // if (!bDefault) continue; bool bSource = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = type.GetRefType(m); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { // Skip IUnknown & IDispatch if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) { continue; } // Skip non-dispatch interfaces that doesn't derive from IUnknown if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl)) { continue; } string name = typeImpl.GetDocumentation(); if (bSource) { // Default source interface if (bDefault || // If explicitly stated as default, use that defaultInterfaceInfo.defaultSourceInterface == null) // otherwise, try to use the first one { defaultInterfaceInfo.defaultSourceInterface = typeImpl; defaultInterfaceInfo.defaultSourceInterfaceName = name; } } else { // Default interface if (bDefault || // If explicitly stated as default, use that defaultInterfaceInfo.defaultInterface == null) // otherwise, try to use the first one { defaultInterfaceInfo.defaultInterface = typeImpl; defaultInterfaceInfo.defaultInterfaceName = name; } } } } // // Walk through the list of implemented interfaces again. This time we remember all the implemented interfaces (including base) // for (int m = 0; m < attr.cImplTypes; ++m) { TypeInfo typeImpl = type.GetRefType(m); string name = typeImpl.GetDocumentation(); while (typeImpl != null) { // If we arleady seen this interface if (interfaceToCoClassMapping.Contains(name)) { // and if it is for a different interface if ((string)interfaceToCoClassMapping[name] != defaultInterfaceInfo.coclassName) { // Set the name to null so that we know we've seen other interfaces interfaceToCoClassMapping[name] = null; } } else { interfaceToCoClassMapping.Add(name, defaultInterfaceInfo.coclassName); } TypeAttr attrImpl = typeImpl.GetTypeAttr(); if (attrImpl.cImplTypes == 1) { typeImpl = typeImpl.GetRefType(0); } else { typeImpl = null; } } } // We do allow coclass that doesn't have any 'valid' default interfaces to have a class interface // For example, // coclass MyObject { // [default] interface IUnknown; // } m_defaultInterfaceInfoList.Add(defaultInterfaceInfo); } } } foreach (DefaultInterfaceInfo defaultInterfaceInfo in m_defaultInterfaceInfoList) { bool isExclusive = true; if (defaultInterfaceInfo.defaultInterface != null) { if (interfaceToCoClassMapping.Contains(defaultInterfaceInfo.defaultInterfaceName)) { if (interfaceToCoClassMapping[defaultInterfaceInfo.defaultInterfaceName] == null) { isExclusive = false; } } defaultInterfaceInfo.isExclusive = isExclusive; } } }