private unsafe Guid GetPropertyPage(Ole32.DispatchID dispid) { try { Ole32.IPerPropertyBrowsing ippb = owner.GetPerPropertyBrowsing(); if (ippb == null) { return(Guid.Empty); } Guid rval = Guid.Empty; if (ippb.MapPropertyToPage(dispid, &rval).Succeeded()) { return(rval); } } catch (COMException) { } catch (Exception t) { Debug.Fail(t.ToString()); } return(Guid.Empty); }
internal static string GetDisplayString(Ole32.IPerPropertyBrowsing ppb, Ole32.DispatchID dispid, ref bool success) { HRESULT hr = ppb.GetDisplayString(dispid, out string strVal); if (hr != HRESULT.S_OK) { success = false; return(null); } success = strVal != null; return(strVal); }
private unsafe Guid GetPropertyPageGuid(Ole32.IPerPropertyBrowsing target, Ole32.DispatchID dispid) { // check for a property page Guid guid = Guid.Empty; HRESULT hr = target.MapPropertyToPage(dispid, &guid); if (hr == HRESULT.S_OK) { return(guid); } return(Guid.Empty); }
/*internal bool StandardValuesQueried { * get { * this.standardValuesQueried = value; * } * } */ // ensure that we have processed the caStructs into arrays // of values and strings // private void EnsureArrays() { if (arraysFetched) { return; } arraysFetched = true; try { // marshal the items. object[] nameItems = nameMarshaller.Items; object[] cookieItems = valueMarshaller.Items; Ole32.IPerPropertyBrowsing ppb = (Ole32.IPerPropertyBrowsing)target.TargetObject; int itemCount = 0; Debug.Assert(cookieItems != null && nameItems != null, "An item array is null"); if (nameItems.Length > 0) { object[] valueItems = new object[cookieItems.Length]; var var = new Ole32.VARIANT(); int cookie; Debug.Assert(cookieItems.Length == nameItems.Length, "Got uneven names and cookies"); // for each name item, we ask the object for it's corresponding value. // Type targetType = target.PropertyType; for (int i = nameItems.Length - 1; i >= 0; i--) { cookie = (int)cookieItems[i]; if (nameItems[i] == null || !(nameItems[i] is string)) { Debug.Fail("Bad IPerPropertyBrowsing item [" + i.ToString(CultureInfo.InvariantCulture) + "], name=" + (nameItems == null ? "(unknown)" : nameItems[i].ToString())); continue; } var.vt = Ole32.VARENUM.EMPTY; HRESULT hr = ppb.GetPredefinedValue(target.DISPID, (uint)cookie, var); if (hr == HRESULT.S_OK && var.vt != Ole32.VARENUM.EMPTY) { valueItems[i] = var.ToObject(); if (valueItems[i].GetType() != targetType) { if (targetType.IsEnum) { valueItems[i] = Enum.ToObject(targetType, valueItems[i]); } else { try { valueItems[i] = Convert.ChangeType(valueItems[i], targetType, CultureInfo.InvariantCulture); } catch { // oh well... } } } } var.Clear(); if (hr == NativeMethods.S_OK) { itemCount++; continue; } else if (itemCount > 0) { // shorten the arrays to ignore the failed ones. this isn't terribly // efficient but shouldn't happen very often. It's rare for these to fail. // Array.Copy(nameItems, i, nameItems, i + 1, itemCount); Array.Copy(valueItems, i, valueItems, i + 1, itemCount); } } // pass this data down to the base Com2Enum object... string[] strings = new string[itemCount]; Array.Copy(nameItems, 0, strings, 0, itemCount); base.PopulateArrays(strings, valueItems); } } catch (Exception ex) { base.PopulateArrays(Array.Empty <string>(), Array.Empty <object>()); Debug.Fail("Failed to build IPerPropertyBrowsing editor. " + ex.GetType().Name + ", " + ex.Message); } }
/// <summary> /// Called externally to update the editor or type converter. /// This simply sets flags so this will happen, it doesn't actually to the update... /// we wait and do that on-demand for perf. /// </summary> internal unsafe void UpdateTypeConverterAndTypeEditorInternal(bool force, Ole32.DispatchID dispid) { // check to see if we're being forced here or if the work really // needs to be done. // if (GetFlag(FlagUpdatedEditorAndConverter) && !force) { return; } if (owner.GetOcx() == null) { return; } try { Ole32.IPerPropertyBrowsing ppb = owner.GetPerPropertyBrowsing(); if (ppb != null) { bool hasStrings = false; // check for enums var caStrings = new Ole32.CA_STRUCT(); var caCookies = new Ole32.CA_STRUCT(); HRESULT hr = HRESULT.S_OK; try { hr = ppb.GetPredefinedStrings(dispid, &caStrings, &caCookies); } catch (ExternalException ex) { hr = (HRESULT)ex.ErrorCode; Debug.Fail("An exception occurred inside IPerPropertyBrowsing::GetPredefinedStrings(dispid=" + dispid + "), object type=" + new ComNativeDescriptor().GetClassName(ppb)); } if (hr != HRESULT.S_OK) { hasStrings = false; // Destroy the existing editor if we created the current one // so if the items have disappeared, we don't hold onto the old // items. if (converter is Com2EnumConverter) { converter = null; } } else { hasStrings = true; } if (hasStrings) { OleStrCAMarshaler stringMarshaler = new OleStrCAMarshaler(caStrings); Int32CAMarshaler intMarshaler = new Int32CAMarshaler(caCookies); if (stringMarshaler.Count > 0 && intMarshaler.Count > 0) { if (converter == null) { converter = new AxEnumConverter(this, new AxPerPropertyBrowsingEnum(this, owner, stringMarshaler, intMarshaler, true)); } else if (converter is AxEnumConverter) { ((AxEnumConverter)converter).RefreshValues(); if (((AxEnumConverter)converter).com2Enum is AxPerPropertyBrowsingEnum axEnum) { axEnum.RefreshArrays(stringMarshaler, intMarshaler); } } } else { //hasStrings = false; } } else { // if we didn't get any strings, try the proppage edtior // // Check to see if this is a property that we have already massaged to be a // .Net type. If it is, don't bother with custom property pages. We already // have a .Net Editor for this type. // ComAliasNameAttribute comAlias = (ComAliasNameAttribute)baseProp.Attributes[typeof(ComAliasNameAttribute)]; if (comAlias == null) { Guid g = GetPropertyPage(dispid); if (!Guid.Empty.Equals(g)) { editor = new AxPropertyTypeEditor(this, g); // Show any non-browsable property that has an editor through a // property page. // if (!IsBrowsable) { Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Making property: " + Name + " browsable because we found an editor."); AddAttribute(new BrowsableAttribute(true)); } } } } } SetFlag(FlagUpdatedEditorAndConverter, true); } catch (Exception e) { Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "could not get the type editor for property: " + Name + " Exception: " + e); } }
// ensure that we have processed the caStructs into arrays // of values and strings // private void EnsureArrays() { if (arraysFetched) { return; } arraysFetched = true; try { // marshal the items. object[] nameItems = nameMarshaller.Items; object[] cookieItems = valueMarshaller.Items; Ole32.IPerPropertyBrowsing ppb = (Ole32.IPerPropertyBrowsing)owner.GetPerPropertyBrowsing(); int itemCount = 0; Debug.Assert(cookieItems != null && nameItems != null, "An item array is null"); if (nameItems.Length > 0) { object[] valueItems = new object[cookieItems.Length]; var var = new Ole32.VARIANT(); int cookie; Debug.Assert(cookieItems.Length == nameItems.Length, "Got uneven names and cookies"); // for each name item, we ask the object for it's corresponding value. // for (int i = 0; i < nameItems.Length; i++) { cookie = (int)cookieItems[i]; if (nameItems[i] == null || !(nameItems[i] is string)) { Debug.Fail("Bad IPerPropertyBrowsing item [" + i.ToString(CultureInfo.InvariantCulture) + "], name=" + (nameItems == null ? "(unknown)" : nameItems[i].ToString())); continue; } var.vt = (short)Ole32.VARENUM.EMPTY; HRESULT hr = ppb.GetPredefinedValue(target.Dispid, (uint)cookie, var); if (hr == HRESULT.S_OK && var.vt != Ole32.VARENUM.EMPTY) { valueItems[i] = var.ToObject(); } var.Clear(); itemCount++; } // pass this data down to the base Com2Enum object... if (itemCount > 0) { string[] strings = new string[itemCount]; Array.Copy(nameItems, 0, strings, 0, itemCount); base.PopulateArrays(strings, valueItems); } } } catch (Exception ex) { Debug.Fail("Failed to build IPerPropertyBrowsing editor. " + ex.GetType().Name + ", " + ex.Message); } }