internal DdeConversation(DdemlConversation conversation)
 {
     _DdemlObject = conversation;
     _DdemlObject.StateChange += this.OnStateChange;
     _Service = _DdemlObject.Service;
     _Topic = _DdemlObject.Topic;
     _Handle = _DdemlObject.Handle;
     _IsPaused = _DdemlObject.IsPaused;
 }
Exemple #2
0
 protected virtual RequestResult OnRequest(DdemlConversation conversation, string item, int format)
 {
     return RequestResult.NotProcessed;
 }
Exemple #3
0
 protected virtual PokeResult OnPoke(DdemlConversation conversation, string item, byte[] data, int format)
 {
     return PokeResult.NotProcessed;
 }
Exemple #4
0
 protected virtual ExecuteResult OnExecute(DdemlConversation conversation, string command)
 {
     return ExecuteResult.NotProcessed;
 }
Exemple #5
0
 protected virtual void OnDisconnect(DdemlConversation conversation)
 {
 }
Exemple #6
0
 protected virtual void OnAfterConnect(DdemlConversation conversation)
 {
 }
Exemple #7
0
        public virtual void Resume(DdemlConversation conversation)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().ToString());
            }
            if (!IsRegistered)
            {
                throw new InvalidOperationException(Resources.NotRegisteredMessage);
            }
            if (conversation == null)
            {
                throw new ArgumentNullException("conversation");
            }
            if (!conversation.IsPaused)
            {
                throw new InvalidOperationException(Resources.NotPausedMessage);
            }

            // Enable the DDEML callback for the specified conversation only.
            bool result = Ddeml.DdeEnableCallback(_InstanceId, conversation.Handle, Ddeml.EC_ENABLEALL);

            // Check the result to see if the DDEML callback was enabled.
            if (!result)
            {
                int 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();
        }
Exemple #8
0
 protected override void OnAfterConnect(DdemlConversation conversation)
 {
     DdeConversation c = new DdeConversation(conversation);
     conversation.Tag = c;
     _Parent.OnAfterConnect(c);
 }
Exemple #9
0
 protected override void OnStopAdvise(DdemlConversation conversation, string item)
 {
     _Parent.OnStopAdvise((DdeConversation)conversation.Tag, item);
 }
Exemple #10
0
 protected override RequestResult OnRequest(DdemlConversation conversation, string item, int format)
 {
     DdeServer.RequestResult result = _Parent.OnRequest((DdeConversation)conversation.Tag, item, format);
     if (result == DdeServer.RequestResult.NotProcessed)
     {
         return RequestResult.NotProcessed;
     }
     if (result == DdeServer.RequestResult.PauseConversation)
     {
         return RequestResult.PauseConversation;
     }
     if (result == DdeServer.RequestResult.Processed)
     {
         return new RequestResult(result.Data);
     }
     return RequestResult.NotProcessed;
 }
Exemple #11
0
 protected override bool OnStartAdvise(DdemlConversation conversation, string item, int format)
 {
     return _Parent.OnStartAdvise((DdeConversation)conversation.Tag, item, format);
 }
Exemple #12
0
 protected override PokeResult OnPoke(DdemlConversation conversation, string item, byte[] data, int format)
 {
     DdeServer.PokeResult result = _Parent.OnPoke((DdeConversation)conversation.Tag, item, data, format);
     if (result == DdeServer.PokeResult.NotProcessed)
     {
         return PokeResult.NotProcessed;
     }
     if (result == DdeServer.PokeResult.PauseConversation)
     {
         return PokeResult.PauseConversation;
     }
     if (result == DdeServer.PokeResult.Processed)
     {
         return PokeResult.Processed;
     }
     if (result == DdeServer.PokeResult.TooBusy)
     {
         return PokeResult.TooBusy;
     }
     return PokeResult.NotProcessed;
 }
Exemple #13
0
 protected override ExecuteResult OnExecute(DdemlConversation conversation, string command)
 {
     DdeServer.ExecuteResult result = _Parent.OnExecute((DdeConversation)conversation.Tag, command);
     if (result == DdeServer.ExecuteResult.NotProcessed)
     {
         return ExecuteResult.NotProcessed;
     }
     if (result == DdeServer.ExecuteResult.PauseConversation)
     {
         return ExecuteResult.PauseConversation;
     }
     if (result == DdeServer.ExecuteResult.Processed)
     {
         return ExecuteResult.Processed;
     }
     if (result == DdeServer.ExecuteResult.TooBusy)
     {
         return ExecuteResult.TooBusy;
     }
     return ExecuteResult.NotProcessed;
 }
Exemple #14
0
 protected override void OnDisconnect(DdemlConversation conversation)
 {
     _Parent.OnDisconnect((DdeConversation)conversation.Tag);
 }
Exemple #15
0
 protected virtual bool OnStartAdvise(DdemlConversation conversation, string item, int format)
 {
     return true;
 }
Exemple #16
0
        public virtual void Disconnect(DdemlConversation conversation)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().ToString());
            }
            if (!IsRegistered)
            {
                throw new InvalidOperationException(Resources.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);
            }
        }
Exemple #17
0
 protected virtual void OnStopAdvise(DdemlConversation conversation, string item)
 {
 }
Exemple #18
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;
        }