예제 #1
0
        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);
        }
예제 #3
0
        public static ComEventsSink?RemoveAll(ComEventsSink?sinks)
        {
            while (sinks != null)
            {
                sinks.Unadvise();
                sinks = sinks._next;
            }

            return(null);
        }
예제 #4
0
        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);
            }
        }
예제 #6
0
        /// <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 !);
 }
예제 #8
0
 public static ComEventsSink Add(ComEventsSink?sinks, ComEventsSink sink)
 {
     sink._next = sinks;
     return(sink);
 }