public virtual void StartAdvise(string item, int format, bool hot, bool acknowledge, int timeout, object adviseState) { if (IsDisposed) { throw new ObjectDisposedException(this.GetType().ToString()); } if (!IsConnected) { throw new InvalidOperationException(Resources.NotConnectedMessage); } if (item == null) { throw new ArgumentNullException("item"); } if (item.Length > Ddeml.MAX_STRING_SIZE) { throw new ArgumentException(Resources.StringParameterInvalidMessage, "item"); } if (timeout <= 0) { throw new ArgumentException(Resources.TimeoutParameterInvalidMessage, "timeout"); } if (_AdviseLoopTable.ContainsKey(item)) { string message = Resources.AlreadyBeingAdvisedMessage; message = message.Replace("${service}", _Service); message = message.Replace("${topic}", _Topic); message = message.Replace("${item}", item); throw new InvalidOperationException(message); } // Create a AdviseLoop object to associate with this advise loop and add it to the advise loop table. // The object is added to the advise loop table first because an advisory could come in synchronously during the call // DdeClientTransaction. The assumption is that the advise loop will be initiated successfully. If it is not then the object must // be removed from the advise loop table prior to leaving this method. AdviseLoop adviseLoop = new AdviseLoop(this); adviseLoop.Item = item; adviseLoop.Format = format; adviseLoop.State = adviseState; _AdviseLoopTable.Add(item, adviseLoop); // Determine whether the client should acknowledge an advisory before the server posts another. bool ack = acknowledge; // Create a string handle for the item name. IntPtr itemHandle = Ddeml.DdeCreateStringHandle(_InstanceId, item, Ddeml.CP_WINANSI); // Initiate an advise loop. int type = Ddeml.XTYP_ADVSTART; type = !hot ? type | Ddeml.XTYPF_NODATA : type; type = ack ? type | Ddeml.XTYPF_ACKREQ : type; int returnFlags = 0; IntPtr result = Ddeml.DdeClientTransaction( IntPtr.Zero, 0, _ConversationHandle, itemHandle, format, type, timeout, ref returnFlags); // Free the string handle created earlier. Ddeml.DdeFreeStringHandle(_InstanceId, itemHandle); // If the result is null then the server did not initate the advise loop. if (result == IntPtr.Zero) { // Remove the AdviseLoop object created earlier from the advise loop table. It is no longer valid. _AdviseLoopTable.Remove(item); int error = Ddeml.DdeGetLastError(_InstanceId); string message = Resources.StartAdviseFailedMessage; message = message.Replace("${service}", _Service); message = message.Replace("${topic}", _Topic); message = message.Replace("${item}", item); throw new DdemlException(message, error); } }
protected override IntPtr ProcessCallback( int uType, int uFmt, IntPtr hConv, IntPtr hsz1, IntPtr hsz2, IntPtr hData, IntPtr dwData1, IntPtr dwData2) { // If the data handle is null then the server did not initiate the advise loop. if (hData == IntPtr.Zero) { string message = Resources.StartAdviseFailedMessage; message = message.Replace("${service}", this.Client._Service); message = message.Replace("${topic}", this.Client._Topic); message = message.Replace("${item}", _Item); this.ExceptionObject = new DdemlException(message); } else { // Create a AdviseLoop object to associate with this advise loop and add it to the owner's advise loop table. AdviseLoop adviseLoop = new AdviseLoop(this.Client); adviseLoop.Item = _Item; adviseLoop.Format = _Format; adviseLoop.State = _State; this.Client._AdviseLoopTable.Add(_Item, adviseLoop); } // Return zero to indicate that there are no problems. return IntPtr.Zero; }