Example #1
0
        // it is caller's responsibility to call this method under lock(rcw)
        public static ComEventsInfo FromObject(object rcw)
        {
            ComEventsInfo?eventsInfo = Find(rcw);

            if (eventsInfo == null)
            {
                eventsInfo = new ComEventsInfo(rcw);
                Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), eventsInfo);
            }
            return(eventsInfo);
        }
Example #2
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) ?? eventsInfo.AddSink(ref iid);

                ComEventsMethod method = sink.FindMethod(dispid) ?? sink.AddMethod(dispid);

                method.AddDelegate(d);
            }
        }
Example #3
0
        /// <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);
            }
        }
Example #4
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);
            }
        }