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); }
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 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; }