/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Apache License, Version 2.0. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Apache License, Version 2.0, please send an email to * vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Apache License, Version 2.0. * * You must not remove this notice, or any other, from this software. * * ***************************************************************************/ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Microsoft.VisualStudio; using Microsoft.VisualStudio.OLE.Interop; namespace Microsoft.VisualStudio.Project { /// /// Class used to identify a source of events of type SinkType. /// [ComVisible(false)] public interface IEventSource where SinkType : class { void OnSinkAdded(SinkType sink); void OnSinkRemoved(SinkType sink); } [ComVisible(true)] public class ConnectionPointContainer : IConnectionPointContainer { private Dictionary connectionPoints; public ConnectionPointContainer() { connectionPoints = new Dictionary(); } public void AddEventSource(IEventSource source) where SinkType : class { if (null == source) { throw new ArgumentNullException("source"); } if (connectionPoints.ContainsKey(typeof(SinkType).GUID)) { throw new ArgumentException("EventSource guid already added to the list of connection points", "source"); } connectionPoints.Add(typeof(SinkType).GUID, new ConnectionPoint(this, source)); } #region IConnectionPointContainer Members void IConnectionPointContainer.EnumConnectionPoints(out IEnumConnectionPoints ppEnum) { throw new NotImplementedException(); ; } void IConnectionPointContainer.FindConnectionPoint(ref Guid riid, out IConnectionPoint ppCP) { ppCP = connectionPoints[riid]; } #endregion } public class ConnectionPoint : IConnectionPoint where SinkType : class { Dictionary sinks; private uint nextCookie; private ConnectionPointContainer container; private IEventSource source; public ConnectionPoint(ConnectionPointContainer container, IEventSource source) { if (null == container) { throw new ArgumentNullException("container"); } if (null == source) { throw new ArgumentNullException("source"); } this.container = container; this.source = source; sinks = new Dictionary(); nextCookie = 1; } #region IConnectionPoint Members public void Advise(object pUnkSink, out uint pdwCookie) { SinkType sink = pUnkSink as SinkType; if (null == sink) { Marshal.ThrowExceptionForHR(VSConstants.E_NOINTERFACE); } sinks.Add(nextCookie, sink); pdwCookie = nextCookie; source.OnSinkAdded(sink); nextCookie += 1; } public void EnumConnections(out IEnumConnections ppEnum) { throw new NotImplementedException(); ; } public void GetConnectionInterface(out Guid pIID) { pIID = typeof(SinkType).GUID; } public void GetConnectionPointContainer(out IConnectionPointContainer ppCPC) { ppCPC = this.container; } public void Unadvise(uint dwCookie) { // This will throw if the cookie is not in the list. SinkType sink = sinks[dwCookie]; sinks.Remove(dwCookie); source.OnSinkRemoved(sink); } #endregion } }