bool IMessageFilter.PreFilterMessage(ref Message m) { if (m.Msg == WM_APP + 3) { // Unregister the service name. Ddeml.DdeNameService(m.WParam.ToInt32(), m.LParam, IntPtr.Zero, Ddeml.DNS_UNREGISTER); // Free the service string handle. Ddeml.DdeFreeStringHandle(m.WParam.ToInt32(), m.LParam); } return false; }
internal static DdemlContext GetDefault() { lock (_Instances) { var context = _Instances[Ddeml.GetCurrentThreadId()]; if (context == null) { context = new DdemlContext(); _Instances.Add(Ddeml.GetCurrentThreadId(), context); } return context; } }
public virtual void Disconnect() { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); // Terminate all conversations. foreach (var conversation in _ConversationTable.Values) Ddeml.DdeDisconnect(conversation.Handle); // clear the conversation table. _ConversationTable.Clear(); }
public virtual void Disconnect(DdemlConversation conversation) { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); if (conversation == null) throw new ArgumentNullException(nameof(conversation)); if (!_ConversationTable.ContainsKey(conversation.Handle)) return; // Terminate the conversation. Ddeml.DdeDisconnect(conversation.Handle); // Remove the Conversation from the conversation table. _ConversationTable.Remove(conversation.Handle); }
public virtual void Advise(string topic, string item) { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); if (topic == null) throw new ArgumentNullException("topic"); if (topic.Length > Ddeml.MAX_STRING_SIZE) throw new ArgumentException(Resources.StringParameterInvalidMessage, "topic"); if (item == null) throw new ArgumentNullException("item"); if (item.Length > Ddeml.MAX_STRING_SIZE) throw new ArgumentException(Resources.StringParameterInvalidMessage, "item"); // Assume the topic name and item name are wild. var topicHandle = IntPtr.Zero; var itemHandle = IntPtr.Zero; // Create a string handle for the topic name if it is not wild. if (topic != "*") topicHandle = Ddeml.DdeCreateStringHandle(_InstanceId, topic, Ddeml.CP_WINANSI); // Create a string handle for the item name if it is not wild. if (item != "*") itemHandle = Ddeml.DdeCreateStringHandle(_InstanceId, item, Ddeml.CP_WINANSI); // Post an advise notification. This will cause an XTYP_ADVREQ transaction for each conversation. bool result = Ddeml.DdePostAdvise(_InstanceId, topicHandle, itemHandle); // Free the string handles created earlier. Ddeml.DdeFreeStringHandle(_InstanceId, itemHandle); Ddeml.DdeFreeStringHandle(_InstanceId, topicHandle); // Check the result to see if the post failed. if (!result) { int error = Ddeml.DdeGetLastError(_InstanceId); string message = Resources.AdviseFailedMessage; message = message.Replace("${service}", _Service); message = message.Replace("${topic}", topic); message = message.Replace("${item}", item); throw new DdemlException(message, error); } }
public virtual void Register() { if (IsDisposed) { throw new ObjectDisposedException(this.GetType().ToString()); } if (IsRegistered) { throw new InvalidOperationException(Resources.AlreadyRegisteredMessage); } // Make sure the context is initialized. if (!_Context.IsInitialized) { _Context.Initialize(); } // Get a local copy of the DDEML instance identifier so that it can be used in the finalizer. _InstanceId = _Context.InstanceId; // Make sure the conversation table is empty. _ConversationTable.Clear(); // Register the service name. _ServiceHandle = RegistrationManager.Register(_InstanceId, _Service); // If the service handle is null then the service name could not be registered. if (_ServiceHandle == IntPtr.Zero) { int error = Ddeml.DdeGetLastError(_InstanceId); string message = Resources.RegisterFailedMessage; message = message.Replace("${service}", _Service); throw new DdemlException(message, error); } // Register this server with the context so that it can receive DDEML callbacks. _Context.RegisterServer(this); // Raise the StateChange event. if (StateChange != null) { StateChange(this, EventArgs.Empty); } }
public static void Uninitialize(int instanceId) { // This method could be called by the GC finalizer thread. If it is then a direct call to the DDEML will fail since the DDEML is // thread specific. A message will be posted to the DDEML thread instead. lock (_Table) { if (!_Table.ContainsKey(instanceId)) return; // Determine if the current thread matches what is in the table. var threadId = _Table[instanceId]; if (threadId == Ddeml.GetCurrentThreadId()) Ddeml.DdeUninitialize(instanceId); else PostThreadMessage(threadId, WM_APP + 1, new IntPtr(instanceId), IntPtr.Zero); // Remove the instance identifier from the table because it is no longer in use. _Table.Remove(instanceId); } }
public virtual void Disconnect() { if (IsDisposed) { throw new ObjectDisposedException(this.GetType().ToString()); } if (!IsRegistered) { throw new InvalidOperationException(DDE.NotRegisteredMessage); } // Terminate all conversations. foreach (DdemlConversation conversation in _ConversationTable.Values) { Ddeml.DdeDisconnect(conversation.Handle); } // clear the conversation table. _ConversationTable.Clear(); }
public virtual void Pause() { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); // Disable the DDEML callback for all conversations. bool result = Ddeml.DdeEnableCallback(_InstanceId, IntPtr.Zero, Ddeml.EC_DISABLE); // Check the result to see if the DDEML callback was disabled. if (!result) { int error = Ddeml.DdeGetLastError(_InstanceId); throw new DdemlException(Resources.ServerPauseAllFailedMessage, error); } // Increment each conversation's waiting count. foreach (var conversation in _ConversationTable.Values) conversation.IncrementWaiting(); }
public virtual void Resume() { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); // Enable the DDEML callback for all conversations. var result = Ddeml.DdeEnableCallback(_InstanceId, IntPtr.Zero, Ddeml.EC_ENABLEALL); // Check the result to see if the DDEML callback was enabled. if (!result) { var error = Ddeml.DdeGetLastError(_InstanceId); throw new DdemlException(Resources.ServerResumeAllFailedMessage, error); } // Decrement each conversation's waiting count. The conversation will only resume if the count is zero. foreach (var conversation in _ConversationTable.Values) conversation.DecrementWaiting(); }
private void OnString(Ddeml.MONHSZSTRUCT mon) { // Get the string from the hsz string handle. // TODO: For some reason this does not work correctly. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hsz, psz, psz.Capacity, Ddeml.CP_WINANSI); var str = psz.ToString(); var action = mon.fsAction switch { Ddeml.MH_CLEANUP => DdemlStringActivityType.CleanUp, Ddeml.MH_CREATE => DdemlStringActivityType.Create, Ddeml.MH_DELETE => DdemlStringActivityType.Delete, Ddeml.MH_KEEP => DdemlStringActivityType.Keep, _ => DdemlStringActivityType.CleanUp }; var args = new DdemlStringActivityEventArgs(str, action, mon.hTask); StringActivity?.Invoke(this, args); }
private void OnLink(Ddeml.MONLINKSTRUCT mon) { StringBuilder psz; int length; // Get the service name from the hszSvc string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszSvc, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); // Get the topic name from the hszTopic string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszTopic, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); // Get the item name from the hszItem string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszItem, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); var args = new DdemlLinkActivityEventArgs( service, topic, item, mon.wFmt, !mon.fNoData, mon.fEstablished, mon.fServer, mon.hConvClient, mon.hConvServer, mon.hTask); if (LinkActivity != null) LinkActivity(this, args); }
public virtual void Disconnect(DdemlConversation conversation) { if (IsDisposed) { throw new ObjectDisposedException(this.GetType().ToString()); } if (!IsRegistered) { throw new InvalidOperationException(DDE.NotRegisteredMessage); } if (conversation == null) { throw new ArgumentNullException("conversation"); } if (_ConversationTable.ContainsKey(conversation.Handle)) { // Terminate the conversation. Ddeml.DdeDisconnect(conversation.Handle); // Remove the Conversation from the conversation table. _ConversationTable.Remove(conversation.Handle); } }
private void OnString(Ddeml.MONHSZSTRUCT mon) { // Get the string from the hsz string handle. // For some reason this does not work correctly. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hsz, psz, psz.Capacity, Ddeml.CP_WINANSI); string str = psz.ToString(); DdemlStringActivityType action = DdemlStringActivityType.CleanUp; switch (mon.fsAction) { case Ddeml.MH_CLEANUP: action = DdemlStringActivityType.CleanUp; break; case Ddeml.MH_CREATE: action = DdemlStringActivityType.Create; break; case Ddeml.MH_DELETE: action = DdemlStringActivityType.Delete; break; case Ddeml.MH_KEEP: action = DdemlStringActivityType.Keep; break; } DdemlStringActivityEventArgs args = new DdemlStringActivityEventArgs(str, action, mon.hTask); if (StringActivity != null) { StringActivity(this, args); } }
private void OnConversation(Ddeml.MONCONVSTRUCT mon) { // Get the service name from the hszSvc string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszSvc, psz, psz.Capacity, Ddeml.CP_WINANSI); var service = psz.ToString(); // Get the topic name from the hszTopic string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszTopic, psz, psz.Capacity, Ddeml.CP_WINANSI); var topic = psz.ToString(); var args = new DdemlConversationActivityEventArgs( service, topic, mon.fConnect, mon.hConvClient, mon.hConvServer, mon.hTask); ConversationActivity?.Invoke(this, args); }
public virtual void Pause(DdemlConversation conversation) { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); if (conversation == null) throw new ArgumentNullException("conversation"); if (conversation.IsPaused) throw new InvalidOperationException(Resources.AlreadyPausedMessage); // Disable the DDEML callback for the specified conversation only. bool result = Ddeml.DdeEnableCallback(_InstanceId, conversation.Handle, Ddeml.EC_DISABLE); // Check the result to see if the DDEML callback was disabled. if (!result) { int error = Ddeml.DdeGetLastError(_InstanceId); throw new DdemlException(Resources.ServerPauseFailedMessage, error); } // Increment the conversation's waiting count. conversation.IncrementWaiting(); }
public static int Initialize(Ddeml.DdeCallback pfnCallback, int afCmd) { lock (_Table) { // Initialize a DDEML instance. var instanceId = 0; Ddeml.DdeInitialize(ref instanceId, pfnCallback, afCmd, 0); if (instanceId == 0) return instanceId; // Make sure this thread has an IMessageFilter on it. var slot = Thread.GetNamedDataSlot(DataSlot); if (Thread.GetData(slot) == null) { var filter = new InstanceManager(); Application.AddMessageFilter(filter); Thread.SetData(slot, filter); } // Add an entry to the table that maps the instance identifier to the current thread. _Table.Add(instanceId, Ddeml.GetCurrentThreadId()); return instanceId; } }
public static IntPtr Register(int instanceId, string service) { lock (_Table) { // Create a string handle for the service name. var serviceHandle = Ddeml.DdeCreateStringHandle(instanceId, service, Ddeml.CP_WINANSI); // Register the service name. var result = Ddeml.DdeNameService(instanceId, serviceHandle, IntPtr.Zero, Ddeml.DNS_REGISTER); if (result != IntPtr.Zero) { // Make sure this thread has an IMessageFilter on it. var slot = Thread.GetNamedDataSlot(DataSlot); if (Thread.GetData(slot) == null) { var filter = new RegistrationManager(); Application.AddMessageFilter(filter); Thread.SetData(slot, filter); } // Add an entry to the table that maps the service handle to the current thread. _Table.Add(serviceHandle, Ddeml.GetCurrentThreadId()); } else { // Free the string handle created earlier. Ddeml.DdeFreeStringHandle(instanceId, serviceHandle); serviceHandle = IntPtr.Zero; } return serviceHandle; } }
public virtual void Resume(DdemlConversation conversation) { if (IsDisposed) throw new ObjectDisposedException(GetType().ToString()); if (!IsRegistered) throw new InvalidOperationException(Resources.NotRegisteredMessage); if (conversation == null) throw new ArgumentNullException(nameof(conversation)); if (!conversation.IsPaused) throw new InvalidOperationException(Resources.NotPausedMessage); // Enable the DDEML callback for the specified conversation only. var result = Ddeml.DdeEnableCallback(_InstanceId, conversation.Handle, Ddeml.EC_ENABLEALL); // Check the result to see if the DDEML callback was enabled. if (!result) { var error = Ddeml.DdeGetLastError(_InstanceId); throw new DdemlException(Resources.ServerResumeFailedMessage, error); } // Decrement the conversation's waiting count. The conversation will only resume if the count is zero. conversation.DecrementWaiting(); }
internal bool ProcessCallback(DdemlTransaction transaction) { // This is here to alias the transaction object with a shorter variable name. DdemlTransaction t = transaction; switch (t.uType) { case Ddeml.XTYP_ADVREQ: { StringBuilder psz; int length; // Get the topic name from the hsz1 string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); // Get the item name from the hsz2 string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); // Create the advise request cache key. string key = topic + "!" + item + ":" + t.uFmt.ToString(); // Get the data being advised if the cache does not contain it already. if (!_AdviseRequestCache.ContainsKey(key)) { // Get the data from the subclass. byte[] data = OnAdvise(topic, item, t.uFmt); // Add the data to the cache because it will be needed later. _AdviseRequestCache.Add(key, data); } // Get the data from the advise request cache. byte[] cached = _AdviseRequestCache[key]; // Get the number of remaining transactions of this type for the same topic name, item name, and format tuple. int remaining = t.dwData1.ToInt32(); // If this is the last transaction then free the data handle. if (remaining == 0) { // TODO: Does the data handle really need to be freed here? // Remove the data from the cache because it is no longer needed. _AdviseRequestCache.Remove(key); } // Create and return the data handle representing the data being advised. if (cached != null && cached.Length > 0) { t.dwRet = Ddeml.DdeCreateDataHandle(_InstanceId, cached, cached.Length, 0, t.hsz2, t.uFmt, 0); return true; } // This transaction could not be processed here. return false; } case Ddeml.XTYP_ADVSTART: { // Get the item name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Get a value indicating whether an advise loop should be initiated from the subclass. t.dwRet = OnStartAdvise(conversation, item, t.uFmt) ? new IntPtr(1) : IntPtr.Zero; return true; } case Ddeml.XTYP_ADVSTOP: { // Get the item name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Inform the subclass that the advise loop has been terminated. OnStopAdvise(conversation, item); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_CONNECT: { // Get the topic name from the hsz1 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); // Get a value from the subclass indicating whether the connection should be allowed. t.dwRet = OnBeforeConnect(topic) ? new IntPtr(1) : IntPtr.Zero; return true; } case Ddeml.XTYP_CONNECT_CONFIRM: { // Get the topic name from the hsz1 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); // Create a Conversation object and add it to the conversation table. _ConversationTable.Add(t.hConv, new DdemlConversation(t.hConv, _Service, topic)); // Inform the subclass that a conversation has been established. OnAfterConnect(_ConversationTable[t.hConv]); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_DISCONNECT: { // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Remove the Conversation from the conversation table. _ConversationTable.Remove(t.hConv); // Inform the subclass that the conversation has been disconnected. OnDisconnect(conversation); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_EXECUTE: { // Get the command from the data handle. int length = Ddeml.DdeGetData(t.hData, null, 0, 0); byte[] data = new byte[length]; length = Ddeml.DdeGetData(t.hData, data, data.Length, 0); string command = _Context.Encoding.GetString(data, 0, data.Length); if (command[command.Length - 1] == '\0') { command = command.Substring(0, command.Length - 1); } // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Send the command to the subclass and get the result. ExecuteResult result = OnExecute(conversation, command); // Return DDE_FACK if the subclass processed the command successfully. if (result == ExecuteResult.Processed) { t.dwRet = new IntPtr(Ddeml.DDE_FACK); return true; } // Return CBR_BLOCK if the subclass needs time to process the command. if (result == ExecuteResult.PauseConversation) { // Increment the conversation's waiting count. conversation.IncrementWaiting(); t.dwRet = new IntPtr(Ddeml.CBR_BLOCK); return true; } // Return DDE_FBUSY if the subclass is too busy. if (result == ExecuteResult.TooBusy) { t.dwRet = new IntPtr(Ddeml.DDE_FBUSY); return true; } // Return DDE_FNOTPROCESSED if the subclass did not process the command. t.dwRet = new IntPtr(Ddeml.DDE_FNOTPROCESSED); return true; } case Ddeml.XTYP_POKE: { // Get the item name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); // Get the data from the data handle. length = Ddeml.DdeGetData(t.hData, null, 0, 0); byte[] data = new byte[length]; length = Ddeml.DdeGetData(t.hData, data, data.Length, 0); // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Send the data to the subclass and get the result. PokeResult result = OnPoke(conversation, item, data, t.uFmt); // Return DDE_FACK if the subclass processed the data successfully. if (result == PokeResult.Processed) { t.dwRet = new IntPtr(Ddeml.DDE_FACK); return true; } // Return CBR_BLOCK if the subclass needs time to process the data. if (result == PokeResult.PauseConversation) { // Increment the conversation's waiting count. conversation.IncrementWaiting(); t.dwRet = new IntPtr(Ddeml.CBR_BLOCK); return true; } // Return DDE_FBUSY if the subclass is too busy. if (result == PokeResult.TooBusy) { t.dwRet = new IntPtr(Ddeml.DDE_FBUSY); return true; } // Return DDE_FNOTPROCESSED if the subclass did not process the data. t.dwRet = new IntPtr(Ddeml.DDE_FNOTPROCESSED); return true; } case Ddeml.XTYP_REQUEST: { // Get the item name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); // Get the Conversation from the conversation table. DdemlConversation conversation = _ConversationTable[t.hConv]; // Send the request to the subclass and get the result. RequestResult result = OnRequest(conversation, item, t.uFmt); // Return a data handle if the subclass processed the request successfully. if (result == RequestResult.Processed) { // Create and return the data handle for the data being requested. if (result.Data != null) { t.dwRet = Ddeml.DdeCreateDataHandle(_InstanceId, result.Data, result.Data.Length, 0, t.hsz2, t.uFmt, 0); } return true; } // Return CBR_BLOCK if the subclass needs time to process the request. if (result == RequestResult.PauseConversation) { conversation.IncrementWaiting(); t.dwRet = new IntPtr(Ddeml.CBR_BLOCK); return true; } // Return DDE_FNOTPROCESSED if the subclass did not process the command. t.dwRet = new IntPtr(Ddeml.DDE_FNOTPROCESSED); return true; } } // This transaction could not be processed here. return false; }
bool IMessageFilter.PreFilterMessage(ref Message m) { if (m.Msg == WM_APP + 1) Ddeml.DdeUninitialize(m.WParam.ToInt32()); return false; }
private void OnString(Ddeml.MONHSZSTRUCT mon) { // Get the string from the hsz string handle. // TODO: For some reason this does not work correctly. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hsz, psz, psz.Capacity, Ddeml.CP_WINANSI); string str = psz.ToString(); DdemlStringActivityType action = DdemlStringActivityType.CleanUp; switch (mon.fsAction) { case Ddeml.MH_CLEANUP: action = DdemlStringActivityType.CleanUp; break; case Ddeml.MH_CREATE: action = DdemlStringActivityType.Create; break; case Ddeml.MH_DELETE: action = DdemlStringActivityType.Delete; break; case Ddeml.MH_KEEP: action = DdemlStringActivityType.Keep; break; } DdemlStringActivityEventArgs args = new DdemlStringActivityEventArgs(str, action, mon.hTask); if (StringActivity != null) { StringActivity(this, args); } }
private void OnSend(Ddeml.MONMSGSTRUCT mon) { Message m = new Message(); m.HWnd = mon.hwndTo; m.Msg = mon.wMsg; m.LParam = mon.lParam; m.WParam = mon.wParam; DdemlMessageActivityEventArgs args = new DdemlMessageActivityEventArgs(DdemlMessageActivityKind.Send, m, mon.hTask); if (MessageActivity != null) { MessageActivity(this, args); } }
private void OnLink(Ddeml.MONLINKSTRUCT mon) { StringBuilder psz; int length; // Get the service name from the hszSvc string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszSvc, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); // Get the topic name from the hszTopic string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszTopic, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); // Get the item name from the hszItem string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszItem, psz, psz.Capacity, Ddeml.CP_WINANSI); string item = psz.ToString(); DdemlLinkActivityEventArgs args = new DdemlLinkActivityEventArgs( service, topic, item, mon.wFmt, !mon.fNoData, mon.fEstablished, mon.fServer, mon.hConvClient, mon.hConvServer, mon.hTask); if (LinkActivity != null) { LinkActivity(this, args); } }
private void OnError(Ddeml.MONERRSTRUCT mon) { DdemlErrorActivityEventArgs args = new DdemlErrorActivityEventArgs(mon.wLastError, mon.hTask); if (ErrorActivity != null) { ErrorActivity(this, args); } }
private void OnConversation(Ddeml.MONCONVSTRUCT mon) { StringBuilder psz; int length; // Get the service name from the hszSvc string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszSvc, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); // Get the topic name from the hszTopic string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_Context.InstanceId, mon.hszTopic, psz, psz.Capacity, Ddeml.CP_WINANSI); string topic = psz.ToString(); DdemlConversationActivityEventArgs args = new DdemlConversationActivityEventArgs( service, topic, mon.fConnect, mon.hConvClient, mon.hConvServer, mon.hTask); if (ConversationActivity != null) { ConversationActivity(this, args); } }
private void OnCallback(Ddeml.MONCBSTRUCT mon) { DdemlCallbackActivityEventArgs args = new DdemlCallbackActivityEventArgs( mon.wType, mon.wFmt, mon.hConv, mon.hsz1, mon.hsz2, mon.hData, mon.dwData1, mon.dwData2, mon.dwRet, mon.hTask); if (CallbackActivity != null) { CallbackActivity(this, args); } }
internal bool ProcessCallback(DdemlTransaction transaction) { // This is here to alias the transaction object with a shorter variable name. var t = transaction; switch (t.uType) { case Ddeml.XTYP_ADVREQ: { // Get the topic name from the hsz1 string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); var topic = psz.ToString(); // Get the item name from the hsz2 string handle. psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); var item = psz.ToString(); // Create the advise request cache key. var key = topic + "!" + item + ":" + t.uFmt; // Get the data being advised if the cache does not contain it already. if (!_AdviseRequestCache.ContainsKey(key)) { // Get the data from the subclass. var data = OnAdvise(topic, item, t.uFmt); // Add the data to the cache because it will be needed later. _AdviseRequestCache.Add(key, data); } // Get the data from the advise request cache. var cached = _AdviseRequestCache[key]; // Get the number of remaining transactions of this type for the same topic name, item name, and format tuple. var remaining = t.dwData1.ToInt32(); // If this is the last transaction then free the data handle. if (remaining == 0) _AdviseRequestCache.Remove(key); // Create and return the data handle representing the data being advised. if (cached == null || cached.Length <= 0) return false; t.dwRet = Ddeml.DdeCreateDataHandle(_InstanceId, cached, cached.Length, 0, t.hsz2, t.uFmt, 0); return true; // This transaction could not be processed here. } case Ddeml.XTYP_ADVSTART: { // Get the item name from the hsz2 string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); var item = psz.ToString(); // Get the Conversation from the conversation table. var conversation = _ConversationTable[t.hConv]; // Get a value indicating whether an advise loop should be initiated from the subclass. t.dwRet = OnStartAdvise(conversation, item, t.uFmt) ? new IntPtr(1) : IntPtr.Zero; return true; } case Ddeml.XTYP_ADVSTOP: { // Get the item name from the hsz2 string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_InstanceId, t.hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); var item = psz.ToString(); // Get the Conversation from the conversation table. var conversation = _ConversationTable[t.hConv]; // Inform the subclass that the advise loop has been terminated. OnStopAdvise(conversation, item); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_CONNECT: { // Get the topic name from the hsz1 string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); var topic = psz.ToString(); // Get a value from the subclass indicating whether the connection should be allowed. t.dwRet = OnBeforeConnect(topic) ? new IntPtr(1) : IntPtr.Zero; return true; } case Ddeml.XTYP_CONNECT_CONFIRM: { // Get the topic name from the hsz1 string handle. var psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); var length = Ddeml.DdeQueryString(_InstanceId, t.hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); var topic = psz.ToString(); // Create a Conversation object and add it to the conversation table. _ConversationTable.Add(t.hConv, new DdemlConversation(t.hConv, _Service, topic)); // Inform the subclass that a conversation has been established. OnAfterConnect(_ConversationTable[t.hConv]); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_DISCONNECT: { // Get the Conversation from the conversation table. var conversation = _ConversationTable[t.hConv]; // Remove the Conversation from the conversation table. _ConversationTable.Remove(t.hConv); // Inform the subclass that the conversation has been disconnected. OnDisconnect(conversation); // Return zero to indicate that there are no problems. t.dwRet = IntPtr.Zero; return true; } case Ddeml.XTYP_EXECUTE: { // Get the command from the data handle. var length = Ddeml.DdeGetData(t.hData, null, 0, 0); var data = new byte[length]; length = Ddeml.DdeGetData(t.hData, data, data.Length, 0); var command = _Context.Encoding.GetString(data, 0, data.Length); if (command[^1] == '\0')
public bool PreFilterTransaction(DdemlTransaction t) { if (t.uType == Ddeml.XTYP_MONITOR) { switch (t.dwData2.ToInt32()) { case Ddeml.MF_CALLBACKS: { // Get the MONCBSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONCBSTRUCT mon = (Ddeml.MONCBSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONCBSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnCallback(mon); break; } case Ddeml.MF_CONV: { // Get the MONCONVSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONCONVSTRUCT mon = (Ddeml.MONCONVSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONCONVSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnConversation(mon); break; } case Ddeml.MF_ERRORS: { // Get the MONERRSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONERRSTRUCT mon = (Ddeml.MONERRSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONERRSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnError(mon); break; } case Ddeml.MF_HSZ_INFO: { // Get the MONHSZSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONHSZSTRUCT mon = (Ddeml.MONHSZSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONHSZSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnString(mon); break; } case Ddeml.MF_LINKS: { // Get the MONLINKSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONLINKSTRUCT mon = (Ddeml.MONLINKSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONLINKSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnLink(mon); break; } case Ddeml.MF_POSTMSGS: { // Get the MONMSGSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONMSGSTRUCT mon = (Ddeml.MONMSGSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONMSGSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnPost(mon); break; } case Ddeml.MF_SENDMSGS: { // Get the MONMSGSTRUCT object. int length = 0; IntPtr phData = Ddeml.DdeAccessData(t.hData, ref length); Ddeml.MONMSGSTRUCT mon = (Ddeml.MONMSGSTRUCT)Marshal.PtrToStructure(phData, typeof(Ddeml.MONMSGSTRUCT)); Ddeml.DdeUnaccessData(t.hData); _Parent.OnSend(mon); break; } } } return true; }
private IntPtr OnDdeCallback(int uType, int uFmt, IntPtr hConv, IntPtr hsz1, IntPtr hsz2, IntPtr hData, IntPtr dwData1, IntPtr dwData2) { // Create a new transaction object that will be dispatched to a DdemlClient, DdemlServer, or ITransactionFilter. DdemlTransaction t = new DdemlTransaction(uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); // Run each transaction filter. foreach (IDdemlTransactionFilter filter in _Filters) { if (filter.PreFilterTransaction(t)) { return t.dwRet; } } // Dispatch the transaction. switch (uType) { case Ddeml.XTYP_ADVDATA: { DdemlClient client = _ClientTable[hConv] as DdemlClient; if (client != null) { if (client.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_ADVREQ: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_ADVSTART: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_ADVSTOP: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_CONNECT: { // Get the service name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); DdemlServer server = _ServerTable2[service] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_CONNECT_CONFIRM: { // Get the service name from the hsz2 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, hsz2, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); DdemlServer server = _ServerTable2[service] as DdemlServer; if (server != null) { _ServerTable1[hConv] = server; if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_DISCONNECT: { DdemlClient client = _ClientTable[hConv] as DdemlClient; if (client != null) { _ClientTable[hConv] = null; if (client.ProcessCallback(t)) { return t.dwRet; } } DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { _ServerTable1[hConv] = null; if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_EXECUTE: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_POKE: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_REQUEST: { DdemlServer server = _ServerTable1[hConv] as DdemlServer; if (server != null) { if (server.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_XACT_COMPLETE: { DdemlClient client = _ClientTable[hConv] as DdemlClient; if (client != null) { if (client.ProcessCallback(t)) { return t.dwRet; } } break; } case Ddeml.XTYP_WILDCONNECT: { // This library does not support wild connects. return IntPtr.Zero; } case Ddeml.XTYP_MONITOR: { // Monitors are handled separately in DdemlMonitor. return IntPtr.Zero; } case Ddeml.XTYP_ERROR: { // Get the error code, but do nothing with it at this time. int error = dwData1.ToInt32(); return IntPtr.Zero; } case Ddeml.XTYP_REGISTER: { if (Register != null) { // Get the service name from the hsz1 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); Register(this, new DdemlRegistrationEventArgs(service)); } return IntPtr.Zero; } case Ddeml.XTYP_UNREGISTER: { if (Unregister != null) { // Get the service name from the hsz1 string handle. StringBuilder psz = new StringBuilder(Ddeml.MAX_STRING_SIZE); int length = Ddeml.DdeQueryString(_InstanceId, hsz1, psz, psz.Capacity, Ddeml.CP_WINANSI); string service = psz.ToString(); Unregister(this, new DdemlRegistrationEventArgs(service)); } return IntPtr.Zero; } } return IntPtr.Zero; }
public static int Initialize(Ddeml.DdeCallback pfnCallback, int afCmd) { lock (_Table) { // Initialize a DDEML instance. int instanceId = 0; Ddeml.DdeInitialize(ref instanceId, pfnCallback, afCmd, 0); if (instanceId != 0) { // Make sure this thread has an IMessageFilter on it. LocalDataStoreSlot slot = Thread.GetNamedDataSlot(DataSlot); if (Thread.GetData(slot) == null) { InstanceManager filter = new InstanceManager(); Application.AddMessageFilter(filter); Thread.SetData(slot, filter); } // Add an entry to the table that maps the instance identifier to the current thread. _Table.Add(instanceId, Ddeml.GetCurrentThreadId()); } return instanceId; } }