Esempio n. 1
0
            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;
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 5
0
                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);
                            }
                    }
Esempio n. 6
0
        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);
                }
            }
Esempio n. 8
0
        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();
        }
Esempio n. 9
0
                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);
        }
Esempio n. 12
0
                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);
                    }
Esempio n. 13
0
        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);
            }
        }
Esempio n. 14
0
        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);
        }
Esempio n. 16
0
                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();
        }
Esempio n. 20
0
        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;
 }
Esempio n. 22
0
        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);
            }
        }
Esempio n. 23
0
        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);
            }
        }
Esempio n. 24
0
        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);
            }
        }
Esempio n. 25
0
        private void OnError(Ddeml.MONERRSTRUCT mon)
        {
            DdemlErrorActivityEventArgs args = new DdemlErrorActivityEventArgs(mon.wLastError, mon.hTask);

            if (ErrorActivity != null)
            {
                ErrorActivity(this, args);
            }
        }
Esempio n. 26
0
        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);
            }
        }
Esempio n. 27
0
        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')
Esempio n. 29
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;
 }
Esempio n. 30
0
        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;
                }
            }