/// <summary> /// Adds an advisory connection for the specified format. /// </summary> /// <param name="pFormatetc">The format for which this sink is called for changes.</param> /// <param name="advf">Advisory flags to specify callback behavior.</param> /// <param name="adviseSink">The IAdviseSink to call for this connection.</param> /// <param name="connection">Returns the new connection's ID.</param> /// <returns>An HRESULT.</returns> public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection) { // Check that the specified advisory flags are supported. const ADVF ADVF_ALLOWED = ADVF.ADVF_NODATA | ADVF.ADVF_ONLYONCE | ADVF.ADVF_PRIMEFIRST; if ((int)((advf | ADVF_ALLOWED) ^ ADVF_ALLOWED) != 0) { connection = 0; return(OLE_E_ADVISENOTSUPPORTED); } // Create and insert an entry for the connection list var entry = new AdviseEntry(ref pFormatetc, advf, adviseSink); connections.Add(nextConnectionId, entry); connection = nextConnectionId; nextConnectionId++; // If the ADVF_PRIMEFIRST flag is specified and the data exists, // raise the DataChanged event now. if ((advf & ADVF.ADVF_PRIMEFIRST) == ADVF.ADVF_PRIMEFIRST) { KeyValuePair <FORMATETC, STGMEDIUM> dataEntry; if (GetDataEntry(ref pFormatetc, out dataEntry)) { RaiseDataChanged(connection, ref dataEntry); } } // S_OK return(0); }
/// <summary> /// Creates a connection between a data object and an advisory sink. This method is called by an object /// that supports an advisory sink and enables the advisory sink to be notified of changes in the object's data.</summary> /// <returns>This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, /// as well as the following: /// ValueDescriptionS_OK -- The advisory connection was created. /// E_NOTIMPL -- This method is not implemented on the data object. /// DV_E_LINDEX -- There is an invalid value for <see cref="F:System.Runtime.InteropServices.ComTypes.FORMATETC.lindex"/>; /// currently, only -1 is supported. /// DV_E_FORMATETC -- There is an invalid value for the <paramref name="pFormatetc"/> parameter. /// OLE_E_ADVISENOTSUPPORTED -- The data object does not support change notification.</returns> /// <param name="pFormatetc">A <see cref="T:System.Runtime.InteropServices.ComTypes.FORMATETC"/> structure, /// passed by reference, that defines the format, target device, aspect, and medium that will be used for /// future notifications.</param> /// <param name="advf">One of the ADVF values that specifies a group of flags for controlling the advisory /// connection.</param> /// <param name="adviseSink">A pointer to the IAdviseSink interface on the advisory sink that will receive /// the change notification.</param> /// <param name="connection">When this method returns, contains a pointer to a DWORD token that identifies /// this connection. You can use this token later to delete the advisory connection by passing it to /// <see cref="M:System.Runtime.InteropServices.ComTypes.IDataObject.DUnadvise(System.Int32)"/>. /// If this value is zero, the connection was not established. This parameter is passed uninitialized.</param> public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection) { // Check that the specified advisory flags are supported. const ADVF c_advfAllowed = ADVF.ADVF_NODATA | ADVF.ADVF_ONLYONCE | ADVF.ADVF_PRIMEFIRST; if ((int)((advf | c_advfAllowed) ^ c_advfAllowed) != 0) { connection = 0; return OLE_E_ADVISENOTSUPPORTED; } // Create and insert an entry for the connection list var entry = new AdviseEntry { Format = pFormatetc, Advf = advf, Sink = adviseSink, }; m_connections.Add(m_nextConnectionId, entry); connection = m_nextConnectionId; m_nextConnectionId++; // If the ADVF_PRIMEFIRST flag is specified and the data exists, // raise the DataChanged event now. if ((advf & ADVF.ADVF_PRIMEFIRST) == ADVF.ADVF_PRIMEFIRST) { OleData dataEntry; if (GetDataEntry(ref pFormatetc, out dataEntry)) RaiseDataChanged(connection, ref dataEntry); } return 0; }
/// <summary> /// Adds an advisory connection for the specified format. /// </summary> /// <param name="pFormatetc">The format for which this sink is called for changes.</param> /// <param name="advf">Advisory flags to specify callback behavior.</param> /// <param name="adviseSink">The IAdviseSink to call for this connection.</param> /// <param name="connection">Returns the new connection's ID.</param> /// <returns>An HRESULT.</returns> public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection) { // Check that the specified advisory flags are supported. const ADVF ADVF_ALLOWED = ADVF.ADVF_NODATA | ADVF.ADVF_ONLYONCE | ADVF.ADVF_PRIMEFIRST; if ((int) ((advf | ADVF_ALLOWED) ^ ADVF_ALLOWED) != 0) { connection = 0; return OLE_E_ADVISENOTSUPPORTED; } // Create and insert an entry for the connection list var entry = new AdviseEntry(ref pFormatetc, advf, adviseSink); connections.Add(nextConnectionId, entry); connection = nextConnectionId; nextConnectionId++; // If the ADVF_PRIMEFIRST flag is specified and the data exists, // raise the DataChanged event now. if ((advf & ADVF.ADVF_PRIMEFIRST) == ADVF.ADVF_PRIMEFIRST) { KeyValuePair<FORMATETC, STGMEDIUM> dataEntry; if (GetDataEntry(ref pFormatetc, out dataEntry)) RaiseDataChanged(connection, ref dataEntry); } // S_OK return 0; }
/// <summary> /// Raises the DataChanged event for the specified connection. /// </summary> /// <param name="connection">The connection id.</param> /// <param name="dataEntry">The data entry for which to raise the event.</param> private void RaiseDataChanged(int connection, ref KeyValuePair <FORMATETC, STGMEDIUM> dataEntry) { AdviseEntry adviseEntry = connections[connection]; FORMATETC format = dataEntry.Key; STGMEDIUM medium; if ((adviseEntry.advf & ADVF.ADVF_NODATA) != ADVF.ADVF_NODATA) { medium = dataEntry.Value; } else { medium = default(STGMEDIUM); } adviseEntry.sink.OnDataChange(ref format, ref medium); if ((adviseEntry.advf & ADVF.ADVF_ONLYONCE) == ADVF.ADVF_ONLYONCE) { connections.Remove(connection); } }
/// <summary> /// Creates a connection between a data object and an advisory sink. This method is called by an object /// that supports an advisory sink and enables the advisory sink to be notified of changes in the object's data.</summary> /// <returns>This method supports the standard return values E_INVALIDARG, E_UNEXPECTED, and E_OUTOFMEMORY, /// as well as the following: /// ValueDescriptionS_OK -- The advisory connection was created. /// E_NOTIMPL -- This method is not implemented on the data object. /// DV_E_LINDEX -- There is an invalid value for <see cref="F:System.Runtime.InteropServices.ComTypes.FORMATETC.lindex"/>; /// currently, only -1 is supported. /// DV_E_FORMATETC -- There is an invalid value for the <paramref name="pFormatetc"/> parameter. /// OLE_E_ADVISENOTSUPPORTED -- The data object does not support change notification.</returns> /// <param name="pFormatetc">A <see cref="T:System.Runtime.InteropServices.ComTypes.FORMATETC"/> structure, /// passed by reference, that defines the format, target device, aspect, and medium that will be used for /// future notifications.</param> /// <param name="advf">One of the ADVF values that specifies a group of flags for controlling the advisory /// connection.</param> /// <param name="adviseSink">A pointer to the IAdviseSink interface on the advisory sink that will receive /// the change notification.</param> /// <param name="connection">When this method returns, contains a pointer to a DWORD token that identifies /// this connection. You can use this token later to delete the advisory connection by passing it to /// <see cref="M:System.Runtime.InteropServices.ComTypes.IDataObject.DUnadvise(System.Int32)"/>. /// If this value is zero, the connection was not established. This parameter is passed uninitialized.</param> public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection) { // Check that the specified advisory flags are supported. const ADVF c_advfAllowed = ADVF.ADVF_NODATA | ADVF.ADVF_ONLYONCE | ADVF.ADVF_PRIMEFIRST; if ((int)((advf | c_advfAllowed) ^ c_advfAllowed) != 0) { connection = 0; return(OLE_E_ADVISENOTSUPPORTED); } // Create and insert an entry for the connection list var entry = new AdviseEntry { Format = pFormatetc, Advf = advf, Sink = adviseSink, }; m_connections.Add(m_nextConnectionId, entry); connection = m_nextConnectionId; m_nextConnectionId++; // If the ADVF_PRIMEFIRST flag is specified and the data exists, // raise the DataChanged event now. if ((advf & ADVF.ADVF_PRIMEFIRST) == ADVF.ADVF_PRIMEFIRST) { OleData dataEntry; if (GetDataEntry(ref pFormatetc, out dataEntry)) { RaiseDataChanged(connection, ref dataEntry); } } return(0); }