public static ComEventsSink?Remove(ComEventsSink sinks, ComEventsSink sink) { Debug.Assert(sinks != null, "removing event sink from empty sinks collection"); Debug.Assert(sink != null, "specify event sink is null"); ComEventsSink?toReturn = sinks; if (sink == sinks) { toReturn = sinks._next; } else { ComEventsSink?current = sinks; while (current != null && current._next != sink) { current = current._next; } if (current != null) { current._next = sink._next; } } sink.Unadvise(); return(toReturn); }
// it is caller's responsibility to call this method under lock(rcw) public ComEventsSink AddSink(ref Guid iid) { ComEventsSink sink = new ComEventsSink(_rcw, iid); _sinks = ComEventsSink.Add(_sinks, sink); return(_sinks); }
public static ComEventsSink?RemoveAll(ComEventsSink?sinks) { while (sinks != null) { sinks.Unadvise(); sinks = sinks._next; } return(null); }
public static ComEventsSink?Find(ComEventsSink?sinks, ref Guid iid) { ComEventsSink?sink = sinks; while (sink != null && sink._iidSourceItf != iid) { sink = sink._next; } return(sink); }
/// <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); } }
/// <summary> /// Adds a delegate to the invocation list of events originating from the COM object. /// </summary> /// <param name="rcw">COM object firing the events the caller would like to respond 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 invoke when specified COM event is fired</param> public static void Combine(object rcw, Guid iid, int dispid, Delegate d) { lock (rcw) { ComEventsInfo eventsInfo = ComEventsInfo.FromObject(rcw); ComEventsSink?sink = eventsInfo.FindSink(ref iid); if (sink == null) { sink = eventsInfo.AddSink(ref iid); } ComEventsMethod?method = sink.FindMethod(dispid); if (method == null) { method = sink.AddMethod(dispid); } method.AddDelegate(d); } }
// it is caller's responsibility to call this method under lock(rcw) internal ComEventsSink RemoveSink(ComEventsSink sink) { _sinks = ComEventsSink.Remove(_sinks !, sink); return(_sinks !); }
public static ComEventsSink Add(ComEventsSink?sinks, ComEventsSink sink) { sink._next = sinks; return(sink); }