private IntPtr ODdeNetCallback(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;
        }
        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_ADVDATA:
                {
                    // 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();

                    // Delegate processing to the advise loop object.
                    if (_AdviseLoopTable.ContainsKey(item))
                    {
                        t.dwRet = _AdviseLoopTable[item].Process(t.uType, t.uFmt, t.hConv, t.hsz1, t.hsz2, t.hData, t.dwData1, t.dwData2);
                        return true;
                    }

                    // This transaction could not be processed here.
                    return false;
                }
                case Ddeml.XTYP_XACT_COMPLETE:
                {
                    // Get the transaction identifier from dwData1.
                    int transactionId = t.dwData1.ToInt32();

                    // Get the IAsyncResult from the asynchronous transaction table and delegate processing to it.
                    if (_AsynchronousTransactionTable.ContainsKey(transactionId))
                    {
                        AsyncResultBase arb = _AsynchronousTransactionTable[transactionId];

                        // Remove the IAsyncResult from the asynchronous transaction table.
                        _AsynchronousTransactionTable.Remove(arb.TransactionId);

                        t.dwRet = arb.Process(t.uType, t.uFmt, t.hConv, t.hsz1, t.hsz2, t.hData, t.dwData1, t.dwData2);
                        return true;
                    }

                    // This transaction could not be processed here.
                    return false;
                }
                case Ddeml.XTYP_DISCONNECT:
                {
                    // Assign each active asynchronous transaction an exception so that the EndXXX methods do not deadlock.
                    foreach (AsyncResultBase arb in _AsynchronousTransactionTable.Values)
                    {
                        arb.Process(new DdemlException(Resources.NotConnectedMessage));
                    }

                    // Make sure the asynchronous transaction and advise loop tables are empty.
                    _AsynchronousTransactionTable.Clear();
                    _AdviseLoopTable.Clear();

                    // Unregister this client from the context so that it will not receive DDEML callbacks.
                    _Context.UnregisterClient(this);

                    // Indicate that this object is no longer connected or paused.
                    _Paused = false;
                    _ConversationHandle = IntPtr.Zero;
                    _InstanceId = 0;

                    // Raise the StateChange event.
                    if (StateChange != null)
                    {
                        StateChange(this, EventArgs.Empty);
                    }

                    // Raise the Disconnected event.
                    if (Disconnected != null)
                    {
                        Disconnected(this, new DdemlDisconnectedEventArgs(true, false));
                    }

                    // Return zero to indicate that there are no problems.
                    t.dwRet = IntPtr.Zero;
                    return true;
                }
            }

            // This transaction could not be processed here.
            return false;
        }
Example #3
0
        private IntPtr ODdeNetCallback(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;
        }
 internal DdeTransaction(DdemlTransaction transaction)
 {
     _DdemlObject = transaction;
 }
 public bool PreFilterTransaction(DdemlTransaction t)
 {
     return _OuterFilter.PreFilterTransaction(new DdeTransaction(t));
 }
        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;
        }