/// <summary> /// Default ctor. /// </summary> public Com2Properties(object obj, Com2PropertyDescriptor[] props, int defaultIndex) { #if DEBUG ComNativeDescriptor cnd = new ComNativeDescriptor(); dbgObjName = cnd.GetName(obj); if (dbgObjName == null) { dbgObjName = "(null)"; } dbgObjClass = cnd.GetClassName(obj); if (dbgObjClass == null) { dbgObjClass = "(null)"; } if (DbgCom2PropertiesSwitch.TraceVerbose) { Debug.WriteLine("Creating Com2Properties for object " + dbgObjName + ", class=" + dbgObjClass); } #endif // set up our variables SetProps(props); weakObjRef = new WeakReference(obj); this.defaultIndex = defaultIndex; typeInfoVersions = GetTypeInfoVersions(obj); touchedTime = DateTime.Now.Ticks; }
/// <summary> /// Converts the given object to another type. The most common types to convert /// are to and from a string object. The default implementation will make a call /// to ToString on the object if the object is valid and if the destination /// type is string. If this cannot convert to the destination type, this will /// throw a NotSupportedException. /// </summary> public override object?ConvertTo(ITypeDescriptorContext?context, CultureInfo?culture, object?value, Type destinationType) { if (destinationType == typeof(string)) { if (value is null) { return(s_none); } string text = ComNativeDescriptor.GetName(value); if (text is null || text.Length == 0) { text = ComNativeDescriptor.GetClassName(value); } if (text is null) { return("(Object)"); } return(text); } return(base.ConvertTo(context, culture, value, destinationType)); }
public void GetTypeConverterAndTypeEditor(ref TypeConverter typeConverter, System.Type editorBaseType, ref object typeEditor) { TypeConverter currentConverter = typeConverter; object currentEditor = typeEditor; if (currentConverter == null) { currentConverter = this.GetBaseTypeConverter(); } if (currentEditor == null) { currentEditor = this.GetBaseTypeEditor(editorBaseType); } if (((this.refreshState & 0x2000) == 0) && (this.PropertyType == typeof(Com2Variant))) { System.Type propertyType = this.PropertyType; object propertyValue = this.GetValue(this.TargetObject); if (propertyValue != null) { propertyValue.GetType(); } ComNativeDescriptor.ResolveVariantTypeConverterAndTypeEditor(propertyValue, ref currentConverter, editorBaseType, ref currentEditor); } if (currentConverter is Com2PropDescMainConverter) { currentConverter = ((Com2PropDescMainConverter)currentConverter).InnerConverter; } GetTypeConverterAndTypeEditorEvent e = new GetTypeConverterAndTypeEditorEvent(currentConverter, currentEditor); this.OnGetTypeConverterAndTypeEditor(e); currentConverter = e.TypeConverter; currentEditor = e.TypeEditor; if (currentConverter == null) { currentConverter = this.GetBaseTypeConverter(); } if (currentEditor == null) { currentEditor = this.GetBaseTypeEditor(editorBaseType); } System.Type type = currentConverter.GetType(); if ((type != typeof(TypeConverter)) && (type != typeof(Com2PropDescMainConverter))) { currentConverter = new Com2PropDescMainConverter(this, currentConverter); } typeConverter = currentConverter; typeEditor = currentEditor; }
/// <include file='doc\COM2TypeInfoProcessor.uex' path='docs/doc[@for="Com2TypeInfoProcessor.GetNameDispId"]/*' /> /// <devdoc> /// Retrieve the dispid of the property that we are to use as the name /// member. In this case, the grid will put parens around the name. /// </devdoc> public static int GetNameDispId(UnsafeNativeMethods.IDispatch obj) { int dispid = NativeMethods.DISPID_UNKNOWN; string[] names = null; ComNativeDescriptor cnd = ComNativeDescriptor.Instance; bool succeeded = false; // first try to find one with a valid value cnd.GetPropertyValue(obj, "__id", ref succeeded); if (succeeded) { names = new string[] { "__id" }; } else { cnd.GetPropertyValue(obj, NativeMethods.ActiveX.DISPID_Name, ref succeeded); if (succeeded) { dispid = NativeMethods.ActiveX.DISPID_Name; } else { cnd.GetPropertyValue(obj, "Name", ref succeeded); if (succeeded) { names = new string[] { "Name" }; } } } // now get the dispid of the one that worked... if (names != null) { int[] pDispid = new int[] { NativeMethods.DISPID_UNKNOWN }; Guid g = Guid.Empty; int hr = obj.GetIDsOfNames(ref g, names, 1, SafeNativeMethods.GetThreadLCID(), pDispid); if (NativeMethods.Succeeded(hr)) { dispid = pDispid[0]; } } return(dispid); }
public unsafe static DispatchID GetNameDispId(IDispatch obj) { DispatchID dispid = DispatchID.UNKNOWN; string[] names = null; ComNativeDescriptor cnd = ComNativeDescriptor.Instance; bool succeeded = false; // first try to find one with a valid value cnd.GetPropertyValue(obj, "__id", ref succeeded); if (succeeded) { names = new string[] { "__id" }; } else { cnd.GetPropertyValue(obj, DispatchID.Name, ref succeeded); if (succeeded) { dispid = DispatchID.Name; } else { cnd.GetPropertyValue(obj, "Name", ref succeeded); if (succeeded) { names = new string[] { "Name" }; } } } // now get the dispid of the one that worked... if (names is not null) { DispatchID pDispid = DispatchID.UNKNOWN; Guid g = Guid.Empty; HRESULT hr = obj.GetIDsOfNames(&g, names, 1, Kernel32.GetThreadLocale(), &pDispid); if (hr.Succeeded()) { dispid = pDispid; } } return(dispid); }
public static int GetNameDispId(UnsafeNativeMethods.IDispatch obj) { int num = -1; string[] rgszNames = null; ComNativeDescriptor instance = ComNativeDescriptor.Instance; bool succeeded = false; instance.GetPropertyValue(obj, "__id", ref succeeded); if (succeeded) { rgszNames = new string[] { "__id" }; } else { instance.GetPropertyValue(obj, -800, ref succeeded); if (succeeded) { num = -800; } else { instance.GetPropertyValue(obj, "Name", ref succeeded); if (succeeded) { rgszNames = new string[] { "Name" }; } } } if (rgszNames != null) { int[] rgDispId = new int[] { -1 }; Guid empty = Guid.Empty; if (System.Windows.Forms.NativeMethods.Succeeded(obj.GetIDsOfNames(ref empty, rgszNames, 1, SafeNativeMethods.GetThreadLCID(), rgDispId))) { num = rgDispId[0]; } } return(num); }
/// <include file='doc\COM2Properties.uex' path='docs/doc[@for="Com2Properties.Com2Properties"]/*' /> /// <devdoc> /// Default ctor. /// </devdoc> public Com2Properties(object obj, Com2PropertyDescriptor[] props, int defaultIndex) { #if DEBUG ComNativeDescriptor cnd = new ComNativeDescriptor(); this.dbgObjName = cnd.GetName(obj); if (this.dbgObjName == null) { this.dbgObjName = "(null)"; } this.dbgObjClass = cnd.GetClassName(obj); if (this.dbgObjClass == null) { this.dbgObjClass = "(null)"; } if (DbgCom2PropertiesSwitch.TraceVerbose) { Debug.WriteLine("Creating Com2Properties for object " + dbgObjName + ", class=" + dbgObjClass); } #endif // set up our variables SetProps(props); weakObjRef = new WeakReference(obj); hashCode = obj.GetHashCode(); this.defaultIndex = defaultIndex; // get the type infos count if (obj is NativeMethods.IProvideMultipleClassInfo) { int infos = 0; if (NativeMethods.Succeeded(((NativeMethods.IProvideMultipleClassInfo)obj).GetMultiTypeInfoCount(ref infos))) { this.nTypeInfos = infos; } } }
/// <summary> /// Creates a new WalkingTypeDescriptor. /// </summary> internal ComTypeDescriptor(ComNativeDescriptor handler, object instance) { _handler = handler; _instance = instance; }
internal ComTypeDescriptor(ComNativeDescriptor handler, object instance) { this._handler = handler; this._instance = instance; }
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 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); }
/// <include file='doc\COM2Properties.uex' path='docs/doc[@for="Com2Properties.Com2Properties"]/*' /> /// <devdoc> /// Default ctor. /// </devdoc> public Com2Properties(object obj, Com2PropertyDescriptor[] props, int defaultIndex) { #if DEBUG ComNativeDescriptor cnd = new ComNativeDescriptor(); this.dbgObjName = cnd.GetName(obj); if (this.dbgObjName == null) { this.dbgObjName = "(null)"; } this.dbgObjClass = cnd.GetClassName(obj); if (this.dbgObjClass == null) { this.dbgObjClass = "(null)"; } if (DbgCom2PropertiesSwitch.TraceVerbose) Debug.WriteLine("Creating Com2Properties for object " + dbgObjName + ", class=" + dbgObjClass); #endif // set up our variables SetProps(props); weakObjRef = new WeakReference(obj); this.defaultIndex = defaultIndex; typeInfoVersions = GetTypeInfoVersions(obj); touchedTime = DateTime.Now.Ticks; }
private unsafe void OnGetTypeConverterAndTypeEditor(Com2PropertyDescriptor sender, GetTypeConverterAndTypeEditorEvent gveevent) { if (sender.TargetObject is not Oleaut32.IPerPropertyBrowsing ppb) { return; } // check for enums Ole32.CALPOLESTR caStrings = default; Ole32.CADWORD caCookies = default; HRESULT hr; try { hr = ppb.GetPredefinedStrings(sender.DISPID, &caStrings, &caCookies); } catch (ExternalException ex) { hr = (HRESULT)ex.ErrorCode; Debug.Fail($"An exception occurred inside IPerPropertyBrowsing::GetPredefinedStrings(dispid={sender.DISPID}), object type={ComNativeDescriptor.GetClassName(ppb)}"); } // Terminate the existing editor if we created the current one so if the items have disappeared, // we don't hold onto the old items. if (gveevent.TypeConverter is Com2IPerPropertyEnumConverter) { gveevent.TypeConverter = null; } if (hr == HRESULT.S_OK) { string?[] names = caStrings.ConvertAndFree(); uint[] cookies = caCookies.ConvertAndFree(); if (names.Length > 0 && cookies.Length > 0) { gveevent.TypeConverter = new Com2IPerPropertyEnumConverter(new Com2IPerPropertyBrowsingEnum(sender, names, cookies)); } } else { // If we didn't get any strings, try the proppage editor // // This is a bit of a backwards-compat work around. Many older ActiveX controls will show a // property page for all properties since the old grid would only put up the [...] button for // "(Custom)". If we have a conversion editor, don't allow this to override it. if (sender.ConvertingNativeType) { return; } Guid guid = GetPropertyPageGuid(ppb, sender.DISPID); if (!Guid.Empty.Equals(guid)) { gveevent.TypeEditor = new Com2PropertyPageUITypeEditor(sender, guid, (UITypeEditor)gveevent.TypeEditor); } } }