public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo[] infoArray = null; int pcti = 0; UnsafeNativeMethods.ITypeInfo pTypeInfo = null; if (obj is System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo) { System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo) obj; if (!System.Windows.Forms.NativeMethods.Succeeded(info2.GetMultiTypeInfoCount(ref pcti)) || (pcti == 0)) { pcti = 0; } if (pcti > 0) { infoArray = new UnsafeNativeMethods.ITypeInfo[pcti]; for (int i = 0; i < pcti; i++) { if (!System.Windows.Forms.NativeMethods.Failed(info2.GetInfoOfIndex(i, 1, ref pTypeInfo, 0, 0, IntPtr.Zero, IntPtr.Zero))) { infoArray[i] = pTypeInfo; } } } } if ((infoArray == null) || (infoArray.Length == 0)) { pTypeInfo = FindTypeInfo(obj, wantCoClass); if (pTypeInfo != null) { infoArray = new UnsafeNativeMethods.ITypeInfo[] { pTypeInfo }; } } return infoArray; }
internal string GetClassName(object component) { string pbstrClassName = null; if (((component is System.Windows.Forms.NativeMethods.IVsPerPropertyBrowsing) && System.Windows.Forms.NativeMethods.Succeeded(((System.Windows.Forms.NativeMethods.IVsPerPropertyBrowsing)component).GetClassName(ref pbstrClassName))) && (pbstrClassName != null)) { return(pbstrClassName); } UnsafeNativeMethods.ITypeInfo info = Com2TypeInfoProcessor.FindTypeInfo(component, true); if ((info != null) && (info != null)) { try { info.GetDocumentation(-1, ref pbstrClassName, null, null, null); while (((pbstrClassName != null) && (pbstrClassName.Length > 0)) && (pbstrClassName[0] == '_')) { pbstrClassName = pbstrClassName.Substring(1); } return(pbstrClassName); } catch { } } return(""); }
/// <summary> /// Given an Object, this attempts to locate its type ifo /// </summary> public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo pTypeInfo = null; // This is kind of odd. What's going on here is that if we want the CoClass (e.g. for // the interface name), we need to look for IProvideClassInfo first, then look for the // typeinfo from the IDispatch. In the case of many OleAut32 operations, the CoClass // doesn't have the interface members on it, although in the shell it usually does, so // we need to re-order the lookup if we *actually* want the CoClass if it's available. for (int i = 0; pTypeInfo == null && i < 2; i++) { if (wantCoClass == (i == 0)) { if (obj is NativeMethods.IProvideClassInfo pProvideClassInfo) { pProvideClassInfo.GetClassInfo(out pTypeInfo); } } else { if (obj is UnsafeNativeMethods.IDispatch iDispatch) { iDispatch.GetTypeInfo(0, Kernel32.GetThreadLocale(), out pTypeInfo); } } } return(pTypeInfo); }
public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo classInfo = null; for (int i = 0; (classInfo == null) && (i < 2); i++) { if (wantCoClass == (i == 0)) { if (obj is System.Windows.Forms.NativeMethods.IProvideClassInfo) { System.Windows.Forms.NativeMethods.IProvideClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideClassInfo)obj; try { classInfo = info2.GetClassInfo(); } catch { } } } else if (obj is UnsafeNativeMethods.IDispatch) { UnsafeNativeMethods.IDispatch dispatch = (UnsafeNativeMethods.IDispatch)obj; try { classInfo = dispatch.GetTypeInfo(0, SafeNativeMethods.GetThreadLCID()); } catch { } } } return(classInfo); }
public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo[] infoArray = null; int pcti = 0; UnsafeNativeMethods.ITypeInfo pTypeInfo = null; if (obj is System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo) { System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo)obj; if (!System.Windows.Forms.NativeMethods.Succeeded(info2.GetMultiTypeInfoCount(ref pcti)) || (pcti == 0)) { pcti = 0; } if (pcti > 0) { infoArray = new UnsafeNativeMethods.ITypeInfo[pcti]; for (int i = 0; i < pcti; i++) { if (!System.Windows.Forms.NativeMethods.Failed(info2.GetInfoOfIndex(i, 1, ref pTypeInfo, 0, 0, IntPtr.Zero, IntPtr.Zero))) { infoArray[i] = pTypeInfo; } } } } if ((infoArray == null) || (infoArray.Length == 0)) { pTypeInfo = FindTypeInfo(obj, wantCoClass); if (pTypeInfo != null) { infoArray = new UnsafeNativeMethods.ITypeInfo[] { pTypeInfo }; } } return(infoArray); }
private unsafe long GetTypeInfoVersion(UnsafeNativeMethods.ITypeInfo pTypeInfo) { long num3; IntPtr zero = IntPtr.Zero; if (!System.Windows.Forms.NativeMethods.Succeeded(pTypeInfo.GetTypeAttr(ref zero))) { return(0L); } try { System.Runtime.InteropServices.ComTypes.TYPEATTR typeattr; try { typeattr = *((System.Runtime.InteropServices.ComTypes.TYPEATTR *)zero); } catch { return(0L); } long num2 = 0L; int * numPtr = (int *)&num2; byte *numPtr2 = (byte *)&typeattr; numPtr[0] = *((int *)(numPtr2 + CountMemberOffset)); numPtr++; numPtr[0] = *((int *)(numPtr2 + VersionOffset)); num3 = num2; } finally { pTypeInfo.ReleaseTypeAttr(zero); } return(num3); }
private unsafe long GetTypeInfoVersion(UnsafeNativeMethods.ITypeInfo pTypeInfo) { IntPtr pTypeAttr = IntPtr.Zero; HRESULT hr = pTypeInfo.GetTypeAttr(ref pTypeAttr); if (!hr.Succeeded()) { return(0); } Runtime.InteropServices.ComTypes.TYPEATTR pTAStruct; try { try { // just access directly...no marshalling needed! // pTAStruct = *(Runtime.InteropServices.ComTypes.TYPEATTR *)pTypeAttr; } catch { return(0); } long result = 0; // we pull two things out of the struct: the // number of functions and variables, and the version. // since they are next to each other, we just pull the memory directly. // // the cFuncs and cVars are both shorts, so we read them as one block of ints. // // int * pResult = (int *)&result; byte *pbStruct = (byte *)&pTAStruct; // in the low byte, pull the number of props. // *pResult = *(int *)(pbStruct + CountMemberOffset); // move up to the high word of the long. // pResult++; // now pull out the version info. // *pResult = *(int *)(pbStruct + VersionOffset); // return that composite long. // return(result); } finally { pTypeInfo.ReleaseTypeAttr(pTypeAttr); } }
private static Guid GetGuidForTypeInfo(UnsafeNativeMethods.ITypeInfo typeInfo, int[] versions) { IntPtr pTypeAttr = IntPtr.Zero; int hr = typeInfo.GetTypeAttr(ref pTypeAttr); if (!NativeMethods.Succeeded(hr)) { throw new ExternalException(string.Format(SR.TYPEINFOPROCESSORGetTypeAttrFailed, hr), hr); } try { ref readonly NativeMethods.tagTYPEATTR typeAttr = ref UnsafeNativeMethods.PtrToRef <NativeMethods.tagTYPEATTR>(pTypeAttr);
private static void ProcessVariables(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispidToGet, int nameDispID, StructCache structCache) { IntPtr zero = IntPtr.Zero; int typeAttr = typeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr); } System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); UnsafeNativeMethods.PtrToStructure(zero, data); try { if (data != null) { System.Windows.Forms.NativeMethods.tagVARDESC gvardesc = (System.Windows.Forms.NativeMethods.tagVARDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagVARDESC)); for (int i = 0; i < data.cVars; i++) { IntPtr pVarDesc = IntPtr.Zero; if (System.Windows.Forms.NativeMethods.Succeeded(typeInfo.GetVarDesc(i, ref pVarDesc)) && (pVarDesc != IntPtr.Zero)) { UnsafeNativeMethods.PtrToStructure(pVarDesc, gvardesc); try { if ((gvardesc.varkind != 2) && ((dispidToGet == -1) || (gvardesc.memid == dispidToGet))) { PropInfo info = ProcessDataCore(typeInfo, propInfoList, gvardesc.memid, nameDispID, gvardesc.elemdescVar.tdesc, gvardesc.wVarFlags, structCache); if (info.ReadOnly != 1) { info.ReadOnly = 2; } } } finally { if (pVarDesc != IntPtr.Zero) { typeInfo.ReleaseVarDesc(pVarDesc); } } } } structCache.ReleaseStruct(gvardesc); } } finally { typeInfo.ReleaseTypeAttr(zero); structCache.ReleaseStruct(data); } }
/// <summary> /// Given an Object, this attempts to locate its type ifo /// </summary> public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo pTypeInfo = null; // this is kind of odd. What's going on here is that // if we want the CoClass (e.g. for the interface name), // we need to look for IProvideClassInfo first, then // look for the typeinfo from the IDispatch. // In the case of many OleAut32 operations, the CoClass // doesn't have the interface members on it, although // in the shell it usually does, so // we need to re-order the lookup if we _actually_ want // the CoClass if it's available. // for (int i = 0; pTypeInfo == null && i < 2; i++) { if (wantCoClass == (i == 0)) { if (obj is NativeMethods.IProvideClassInfo pProvideClassInfo) { try { pTypeInfo = pProvideClassInfo.GetClassInfo(); } catch { } } } else { if (obj is UnsafeNativeMethods.IDispatch iDispatch) { try { pTypeInfo = iDispatch.GetTypeInfo(0, SafeNativeMethods.GetThreadLCID()); } catch { } } } } return(pTypeInfo); }
internal string GetClassName(object component) { string name = null; // does IVsPerPropretyBrowsing supply us a name? if (component is NativeMethods.IVsPerPropertyBrowsing) { int hr = ((NativeMethods.IVsPerPropertyBrowsing)component).GetClassName(ref name); if (NativeMethods.Succeeded(hr) && name != null) { return(name); } // otherwise fall through... } UnsafeNativeMethods.ITypeInfo pTypeInfo = Com2TypeInfoProcessor.FindTypeInfo(component, true); if (pTypeInfo == null) { //Debug.Fail("The current component failed to return an ITypeInfo"); return(""); } if (pTypeInfo != null) { string desc = null; try { pTypeInfo.GetDocumentation(NativeMethods.MEMBERID_NIL, ref name, ref desc, null, null); // strip the leading underscores while (name != null && name.Length > 0 && name[0] == '_') { name = name.Substring(1); } return(name); } catch { } } return(""); }
/// <include file='doc\COM2TypeInfoProcessor.uex' path='docs/doc[@for="Com2TypeInfoProcessor.FindTypeInfos"]/*' /> /// <devdoc> /// Given an Object, this attempts to locate its type info. If it implementes IProvideMultipleClassInfo /// all available type infos will be returned, otherwise the primary one will be alled. /// </devdoc> public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass) { UnsafeNativeMethods.ITypeInfo[] typeInfos = null; int n = 0; UnsafeNativeMethods.ITypeInfo temp = null; if (obj is NativeMethods.IProvideMultipleClassInfo) { NativeMethods.IProvideMultipleClassInfo pCI = (NativeMethods.IProvideMultipleClassInfo)obj; if (!NativeMethods.Succeeded(pCI.GetMultiTypeInfoCount(ref n)) || n == 0) { n = 0; } if (n > 0) { typeInfos = new UnsafeNativeMethods.ITypeInfo[n]; for (int i = 0; i < n; i++) { if (NativeMethods.Failed(pCI.GetInfoOfIndex(i, 1 /*MULTICLASSINFO_GETTYPEINFO*/, ref temp, 0, 0, IntPtr.Zero, IntPtr.Zero))) { continue; } Debug.Assert(temp != null, "IProvideMultipleClassInfo::GetInfoOfIndex returned S_OK for ITypeInfo index " + i + ", this is a issue in the object that's being browsed, NOT the property browser."); typeInfos[i] = temp; } } } if (typeInfos == null || typeInfos.Length == 0) { temp = FindTypeInfo(obj, wantCoClass); if (temp != null) { typeInfos = new UnsafeNativeMethods.ITypeInfo[] { temp }; } } return(typeInfos); }
private static Guid GetGuidForTypeInfo(UnsafeNativeMethods.ITypeInfo typeInfo, StructCache structCache, int[] versions) { IntPtr zero = IntPtr.Zero; int typeAttr = typeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr); } Guid empty = Guid.Empty; System.Windows.Forms.NativeMethods.tagTYPEATTR data = null; try { if (structCache == null) { data = new System.Windows.Forms.NativeMethods.tagTYPEATTR(); } else { data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); } UnsafeNativeMethods.PtrToStructure(zero, data); empty = data.guid; if (versions != null) { versions[0] = data.wMajorVerNum; versions[1] = data.wMinorVerNum; } } finally { typeInfo.ReleaseTypeAttr(zero); if ((structCache != null) && (data != null)) { structCache.ReleaseStruct(data); } } return(empty); }
public static Com2Properties GetProperties(object obj) { if ((obj == null) || !Marshal.IsComObject(obj)) { return(null); } UnsafeNativeMethods.ITypeInfo[] infoArray = FindTypeInfos(obj, false); if ((infoArray == null) || (infoArray.Length == 0)) { return(null); } int defaultIndex = -1; int num2 = -1; ArrayList list = new ArrayList(); for (int i = 0; i < infoArray.Length; i++) { UnsafeNativeMethods.ITypeInfo typeInfo = infoArray[i]; if (typeInfo != null) { int[] versions = new int[2]; Guid key = GetGuidForTypeInfo(typeInfo, null, versions); PropertyDescriptor[] props = null; bool flag = ((key != Guid.Empty) && (processedLibraries != null)) && processedLibraries.Contains(key); if (flag) { CachedProperties properties = (CachedProperties)processedLibraries[key]; if ((versions[0] == properties.MajorVersion) && (versions[1] == properties.MinorVersion)) { props = properties.Properties; if ((i == 0) && (properties.DefaultIndex != -1)) { defaultIndex = properties.DefaultIndex; } } else { flag = false; } } if (!flag) { props = InternalGetProperties(obj, typeInfo, -1, ref num2); if ((i == 0) && (num2 != -1)) { defaultIndex = num2; } if (processedLibraries == null) { processedLibraries = new Hashtable(); } if (key != Guid.Empty) { processedLibraries[key] = new CachedProperties(props, (i == 0) ? defaultIndex : -1, versions[0], versions[1]); } } if (props != null) { list.AddRange(props); } } } Com2PropertyDescriptor[] array = new Com2PropertyDescriptor[list.Count]; list.CopyTo(array, 0); return(new Com2Properties(obj, array, defaultIndex)); }
private static System.Type GetValueTypeFromTypeDesc(System.Windows.Forms.NativeMethods.tagTYPEDESC typeDesc, UnsafeNativeMethods.ITypeInfo typeInfo, object[] typeData, StructCache structCache) { IntPtr unionMember; int hr = 0; switch (((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)) { case System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH: case System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN: typeData[0] = GetGuidForTypeInfo(typeInfo, structCache, null); return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)); case System.Windows.Forms.NativeMethods.tagVT.VT_PTR: { System.Windows.Forms.NativeMethods.tagTYPEDESC data = (System.Windows.Forms.NativeMethods.tagTYPEDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEDESC)); try { try { UnsafeNativeMethods.PtrToStructure(typeDesc.unionMember, data); } catch { data = new System.Windows.Forms.NativeMethods.tagTYPEDESC { unionMember = (IntPtr)Marshal.ReadInt32(typeDesc.unionMember), vt = Marshal.ReadInt16(typeDesc.unionMember, 4) }; } if (data.vt == 12) { return(VTToType((System.Windows.Forms.NativeMethods.tagVT)data.vt)); } unionMember = data.unionMember; } finally { structCache.ReleaseStruct(data); } break; } case System.Windows.Forms.NativeMethods.tagVT.VT_USERDEFINED: unionMember = typeDesc.unionMember; break; default: return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt)); } UnsafeNativeMethods.ITypeInfo pTypeInfo = null; hr = typeInfo.GetRefTypeInfo(unionMember, ref pTypeInfo); if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetRefTypeInfoFailed", new object[] { hr }), hr); } try { if (pTypeInfo != null) { IntPtr zero = IntPtr.Zero; hr = pTypeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { hr }), hr); } System.Windows.Forms.NativeMethods.tagTYPEATTR gtypeattr = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); UnsafeNativeMethods.PtrToStructure(zero, gtypeattr); try { Guid g = gtypeattr.guid; if (!Guid.Empty.Equals(g)) { typeData[0] = g; } switch (gtypeattr.typekind) { case 0: return(ProcessTypeInfoEnum(pTypeInfo, structCache)); case 3: case 5: return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN)); case 4: return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH)); case 6: return(GetValueTypeFromTypeDesc(gtypeattr.Get_tdescAlias(), pTypeInfo, typeData, structCache)); } return(null); } finally { pTypeInfo.ReleaseTypeAttr(zero); structCache.ReleaseStruct(gtypeattr); } } } finally { pTypeInfo = null; } return(null); }
/// <summary> /// Gets the properties for a given Com2 Object. The returned Com2Properties /// Object contains the properties and relevant data about them. /// </summary> public static Com2Properties GetProperties(object obj) { Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties"); if (obj == null || !Marshal.IsComObject(obj)) { Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties returning null: Object is not a com Object"); return(null); } UnsafeNativeMethods.ITypeInfo[] typeInfos = FindTypeInfos(obj, false); // oops, looks like this guy doesn't surface any type info // this is okay, so we just say it has no props if (typeInfos == null || typeInfos.Length == 0) { Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties :: Didn't get typeinfo"); return(null); } int defaultProp = -1; int temp = -1; ArrayList propList = new ArrayList(); Guid[] typeGuids = new Guid[typeInfos.Length]; for (int i = 0; i < typeInfos.Length; i++) { UnsafeNativeMethods.ITypeInfo ti = typeInfos[i]; if (ti == null) { continue; } int[] versions = new int[2]; Guid typeGuid = GetGuidForTypeInfo(ti, versions); PropertyDescriptor[] props = null; bool dontProcess = typeGuid != Guid.Empty && processedLibraries != null && processedLibraries.Contains(typeGuid); if (dontProcess) { CachedProperties cp = (CachedProperties)processedLibraries[typeGuid]; if (versions[0] == cp.MajorVersion && versions[1] == cp.MinorVersion) { props = cp.Properties; if (i == 0 && cp.DefaultIndex != -1) { defaultProp = cp.DefaultIndex; } } else { dontProcess = false; } } if (!dontProcess) { props = InternalGetProperties(obj, ti, Ole32.DispatchID.MEMBERID_NIL, ref temp); // only save the default property from the first type Info if (i == 0 && temp != -1) { defaultProp = temp; } if (processedLibraries == null) { processedLibraries = new Hashtable(); } if (typeGuid != Guid.Empty) { processedLibraries[typeGuid] = new CachedProperties(props, i == 0 ? defaultProp : -1, versions[0], versions[1]); } } if (props != null) { propList.AddRange(props); } } Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties : returning " + propList.Count.ToString(CultureInfo.InvariantCulture) + " properties"); // done! Com2PropertyDescriptor[] temp2 = new Com2PropertyDescriptor[propList.Count]; propList.CopyTo(temp2, 0); return(new Com2Properties(obj, temp2, defaultProp)); }
private static PropertyDescriptor[] InternalGetProperties(object obj, UnsafeNativeMethods.ITypeInfo typeInfo, int dispidToGet, ref int defaultIndex) { if (typeInfo == null) { return(null); } Hashtable propInfoList = new Hashtable(); int nameDispId = GetNameDispId((UnsafeNativeMethods.IDispatch)obj); bool addAboutBox = false; StructCache structCache = new StructCache(); try { ProcessFunctions(typeInfo, propInfoList, dispidToGet, nameDispId, ref addAboutBox, structCache); } catch (ExternalException) { } try { ProcessVariables(typeInfo, propInfoList, dispidToGet, nameDispId, structCache); } catch (ExternalException) { } typeInfo = null; int count = propInfoList.Count; if (addAboutBox) { count++; } PropertyDescriptor[] descriptorArray = new PropertyDescriptor[count]; int hr = 0; object[] retval = new object[1]; ComNativeDescriptor instance = ComNativeDescriptor.Instance; foreach (PropInfo info in propInfoList.Values) { if (!info.NonBrowsable) { try { hr = instance.GetPropertyValue(obj, info.DispId, retval); } catch (ExternalException exception) { hr = exception.ErrorCode; } if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { info.Attributes.Add(new BrowsableAttribute(false)); info.NonBrowsable = true; } } else { hr = 0; } Attribute[] array = new Attribute[info.Attributes.Count]; info.Attributes.CopyTo(array, 0); descriptorArray[info.Index] = new Com2PropertyDescriptor(info.DispId, info.Name, array, info.ReadOnly != 2, info.ValueType, info.TypeData, !System.Windows.Forms.NativeMethods.Succeeded(hr)); if (info.IsDefault) { int index = info.Index; } } if (addAboutBox) { descriptorArray[descriptorArray.Length - 1] = new Com2AboutBoxPropertyDescriptor(); } return(descriptorArray); }
private static PropInfo ProcessDataCore(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispid, int nameDispID, System.Windows.Forms.NativeMethods.tagTYPEDESC typeDesc, int flags, StructCache structCache) { string pBstrName = null; string pBstrDocString = null; int hr = typeInfo.GetDocumentation(dispid, ref pBstrName, ref pBstrDocString, null, null); ComNativeDescriptor instance = ComNativeDescriptor.Instance; if (!System.Windows.Forms.NativeMethods.Succeeded(hr)) { throw new COMException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetDocumentationFailed", new object[] { dispid, hr, instance.GetClassName(typeInfo) }), hr); } if (pBstrName == null) { return(null); } PropInfo info = (PropInfo)propInfoList[pBstrName]; if (info == null) { info = new PropInfo { Index = propInfoList.Count }; propInfoList[pBstrName] = info; info.Name = pBstrName; info.DispId = dispid; info.Attributes.Add(new DispIdAttribute(info.DispId)); } if (pBstrDocString != null) { info.Attributes.Add(new DescriptionAttribute(pBstrDocString)); } if (info.ValueType == null) { object[] typeData = new object[1]; try { info.ValueType = GetValueTypeFromTypeDesc(typeDesc, typeInfo, typeData, structCache); } catch (Exception) { } if (info.ValueType == null) { info.NonBrowsable = true; } if (info.NonBrowsable) { flags |= 0x400; } if (typeData[0] != null) { info.TypeData = typeData[0]; } } if ((flags & 1) != 0) { info.ReadOnly = 1; } if ((((flags & 0x40) != 0) || ((flags & 0x400) != 0)) || ((info.Name[0] == '_') || (dispid == -515))) { info.Attributes.Add(new BrowsableAttribute(false)); info.NonBrowsable = true; } if ((flags & 0x200) != 0) { info.IsDefault = true; } if (((flags & 4) != 0) && ((flags & 0x10) != 0)) { info.Attributes.Add(new BindableAttribute(true)); } if (dispid == nameDispID) { info.Attributes.Add(new ParenthesizePropertyNameAttribute(true)); info.Attributes.Add(new MergablePropertyAttribute(false)); } return(info); }
private static void ProcessFunctions(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispidToGet, int nameDispID, ref bool addAboutBox, StructCache structCache) { IntPtr zero = IntPtr.Zero; int typeAttr = typeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr); } System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); UnsafeNativeMethods.PtrToStructure(zero, data); try { if (data != null) { System.Windows.Forms.NativeMethods.tagFUNCDESC gfuncdesc = (System.Windows.Forms.NativeMethods.tagFUNCDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagFUNCDESC)); System.Windows.Forms.NativeMethods.tagELEMDESC structure = (System.Windows.Forms.NativeMethods.tagELEMDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagELEMDESC)); for (int i = 0; i < data.cFuncs; i++) { IntPtr pFuncDesc = IntPtr.Zero; if (System.Windows.Forms.NativeMethods.Succeeded(typeInfo.GetFuncDesc(i, ref pFuncDesc)) && (pFuncDesc != IntPtr.Zero)) { UnsafeNativeMethods.PtrToStructure(pFuncDesc, gfuncdesc); try { if ((gfuncdesc.invkind == 1) || ((dispidToGet != -1) && (gfuncdesc.memid != dispidToGet))) { if (gfuncdesc.memid == -552) { addAboutBox = true; } } else { System.Windows.Forms.NativeMethods.tagTYPEDESC tdesc; bool flag = gfuncdesc.invkind == 2; if (flag) { if (gfuncdesc.cParams != 0) { continue; } tdesc = gfuncdesc.elemdescFunc.tdesc; } else { if ((gfuncdesc.lprgelemdescParam == IntPtr.Zero) || (gfuncdesc.cParams != 1)) { continue; } Marshal.PtrToStructure(gfuncdesc.lprgelemdescParam, structure); tdesc = structure.tdesc; } PropInfo info = ProcessDataCore(typeInfo, propInfoList, gfuncdesc.memid, nameDispID, tdesc, gfuncdesc.wFuncFlags, structCache); if ((info != null) && !flag) { info.ReadOnly = 2; } } } finally { typeInfo.ReleaseFuncDesc(pFuncDesc); } } } structCache.ReleaseStruct(gfuncdesc); structCache.ReleaseStruct(structure); } } finally { typeInfo.ReleaseTypeAttr(zero); structCache.ReleaseStruct(data); } }
private static System.Type ProcessTypeInfoEnum(UnsafeNativeMethods.ITypeInfo enumTypeInfo, StructCache structCache) { if (enumTypeInfo != null) { try { IntPtr zero = IntPtr.Zero; int typeAttr = enumTypeInfo.GetTypeAttr(ref zero); if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero)) { throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr); } System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR)); UnsafeNativeMethods.PtrToStructure(zero, data); if (zero == IntPtr.Zero) { return(null); } try { int cVars = data.cVars; ArrayList list = new ArrayList(); ArrayList list2 = new ArrayList(); System.Windows.Forms.NativeMethods.tagVARDESC gvardesc = (System.Windows.Forms.NativeMethods.tagVARDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagVARDESC)); object objectForNativeVariant = null; string pBstrName = null; string pBstrDocString = null; enumTypeInfo.GetDocumentation(-1, ref pBstrName, ref pBstrDocString, null, null); for (int i = 0; i < cVars; i++) { IntPtr pVarDesc = IntPtr.Zero; if (System.Windows.Forms.NativeMethods.Succeeded(enumTypeInfo.GetVarDesc(i, ref pVarDesc)) && (pVarDesc != IntPtr.Zero)) { try { UnsafeNativeMethods.PtrToStructure(pVarDesc, gvardesc); if (((gvardesc != null) && (gvardesc.varkind == 2)) && (gvardesc.unionMember != IntPtr.Zero)) { str2 = (string)(pBstrDocString = null); objectForNativeVariant = null; if (System.Windows.Forms.NativeMethods.Succeeded(enumTypeInfo.GetDocumentation(gvardesc.memid, null, ref pBstrDocString, null, null))) { string str4; try { objectForNativeVariant = Marshal.GetObjectForNativeVariant(gvardesc.unionMember); } catch (Exception) { } list2.Add(objectForNativeVariant); if (pBstrDocString != null) { str4 = pBstrDocString; } else { str4 = str2; } list.Add(str4); } } } finally { if (pVarDesc != IntPtr.Zero) { enumTypeInfo.ReleaseVarDesc(pVarDesc); } } } } structCache.ReleaseStruct(gvardesc); if (list.Count > 0) { IntPtr iUnknownForObject = Marshal.GetIUnknownForObject(enumTypeInfo); try { pBstrName = iUnknownForObject.ToString() + "_" + pBstrName; if (builtEnums == null) { builtEnums = new Hashtable(); } else if (builtEnums.ContainsKey(pBstrName)) { return((System.Type)builtEnums[pBstrName]); } System.Type underlyingType = typeof(int); if ((list2.Count > 0) && (list2[0] != null)) { underlyingType = list2[0].GetType(); } EnumBuilder builder = ModuleBuilder.DefineEnum(pBstrName, TypeAttributes.Public, underlyingType); for (int j = 0; j < list.Count; j++) { builder.DefineLiteral((string)list[j], list2[j]); } System.Type type2 = builder.CreateType(); builtEnums[pBstrName] = type2; return(type2); } finally { if (iUnknownForObject != IntPtr.Zero) { Marshal.Release(iUnknownForObject); } } } } finally { enumTypeInfo.ReleaseTypeAttr(zero); structCache.ReleaseStruct(data); } } catch { } } return(null); }