public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) { rcw = ComEventsHelper.UnwrapIfTransparentProxy(rcw); object obj = rcw; Delegate result; lock (obj) { ComEventsInfo comEventsInfo = ComEventsInfo.Find(rcw); if (comEventsInfo == null) { result = null; } else { ComEventsSink comEventsSink = comEventsInfo.FindSink(ref iid); if (comEventsSink == null) { result = null; } else { ComEventsMethod comEventsMethod = comEventsSink.FindMethod(dispid); if (comEventsMethod == null) { result = null; } else { comEventsMethod.RemoveDelegate(d); if (comEventsMethod.Empty) { comEventsMethod = comEventsSink.RemoveMethod(comEventsMethod); } if (comEventsMethod == null) { comEventsSink = comEventsInfo.RemoveSink(comEventsSink); } if (comEventsSink == null) { Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), null); GC.SuppressFinalize(comEventsInfo); } result = d; } } } } return(result); }
/// <summary> /// Removes a delegate from the invocation list of events originating from the COM object. /// </summary> /// <param name="rcw">COM object the delegate is attached to</param> /// <param name="iid">identifier of the source interface used by COM object to fire events</param> /// <param name="dispid">dispatch identifier of the method on the source interface</param> /// <param name="d">delegate to remove from the invocation list</param> public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) { lock (rcw) { ComEventsInfo eventsInfo = ComEventsInfo.Find(rcw); if (eventsInfo == null) { return(null); } ComEventsSink sink = eventsInfo.FindSink(ref iid); if (sink == null) { return(null); } ComEventsMethod method = sink.FindMethod(dispid); if (method == null) { return(null); } method.RemoveDelegate(d); if (method.Empty) { // removed the last event handler for this dispid - need to remove dispid handler method = sink.RemoveMethod(method); } if (method == null) { // removed last dispid handler for this sink - need to remove the sink sink = eventsInfo.RemoveSink(sink); } if (sink == null) { // removed last sink for this rcw - need to remove all traces of event info Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), null); GC.SuppressFinalize(eventsInfo); } return(d); } }
public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) { rcw = ComEventsHelper.UnwrapIfTransparentProxy(rcw); lock (rcw) { ComEventsInfo local_2 = ComEventsInfo.Find(rcw); if (local_2 == null) { return((Delegate)null); } ComEventsSink local_3 = local_2.FindSink(ref iid); if (local_3 == null) { return((Delegate)null); } ComEventsMethod local_4 = local_3.FindMethod(dispid); if (local_4 == null) { return((Delegate)null); } local_4.RemoveDelegate(d); if (local_4.Empty) { local_4 = local_3.RemoveMethod(local_4); } if (local_4 == null) { local_3 = local_2.RemoveSink(local_3); } if (local_3 == null) { Marshal.SetComObjectData(rcw, (object)typeof(ComEventsInfo), (object)null); GC.SuppressFinalize((object)local_2); } return(d); } }
public static Delegate Remove(object rcw, Guid iid, int dispid, Delegate d) { rcw = UnwrapIfTransparentProxy(rcw); lock (rcw) { ComEventsInfo info = ComEventsInfo.Find(rcw); if (info == null) { return(null); } ComEventsSink sink = info.FindSink(ref iid); if (sink == null) { return(null); } ComEventsMethod method = sink.FindMethod(dispid); if (method == null) { return(null); } method.RemoveDelegate(d); if (method.Empty) { method = sink.RemoveMethod(method); } if (method == null) { sink = info.RemoveSink(sink); } if (sink == null) { Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), null); GC.SuppressFinalize(info); } return(d); } }
public void RemoveHandler(int dispid, object func) { ComEventsMethod sinkEntry = FindMethod(dispid); if (sinkEntry == null) { return; } if (func is Delegate d) { sinkEntry.RemoveDelegate(d); } else { // Remove the delegate from multicast delegate chain. // We will need to find the delegate that corresponds // to the func handler we want to remove. This will be // easy since we Target property of the delegate object // is a ComEventCallContext object. sinkEntry.RemoveDelegates(d => d.Target is SplatCallSite callContext && callContext._callable.Equals(func)); } // If the delegates chain is empty - we can remove // corresponding ComEvenSinkEntry if (sinkEntry.Empty) { RemoveMethod(sinkEntry); } if (_methods == null || _methods.Empty) { Unadvise(); _iidSourceItf = Guid.Empty; } }