Multiple Conversations

A client application can use the DdeConnectList function to determine whether any servers of interest are available in the system. A client specifies a service name and topic name when it calls DdeConnectList, causing the DDEML to broadcast the XTYP_WILDCONNECT transaction to the DDE callback functions of all servers that match the service name (except those that filter the transaction). A server's callback function should return a data handle that identifies a null-terminated array of HSZPAIR structures. The array should contain one structure for each service name and topic name pair that matches the pair specified by the client. The DDEML establishes a conversation for each HSZPAIR structure filled by the server and returns a conversation list handle to the client. The server receives the conversation handle by way of the XTYP_CONNECT_CONFIRM transaction (unless the server filters this transaction).

A client can specify NULL for the service name, topic name, or both when it calls DdeConnectList. If the service name is NULL, all servers in the system that support the specified topic name respond. A conversation is established with each responding server, including multiple instances of the same server. If the topic name is NULL, a conversation is established on each topic recognized by each server that matches the service name.

A client can use the DdeQueryNextServer and DdeQueryConvInfo functions to identify the servers that respond to DdeConnectList. DdeQueryNextServer returns the next conversation handle in a conversation list, and DdeQueryConvInfo fills a CONVINFO structure with information about the conversation. The client can keep the conversation handles that it needs and discard the rest from the conversation list.

The following example uses DdeConnectList to establish conversations with all servers that support the System topic and then uses the DdeQueryNextServer and DdeQueryConvInfo functions to obtain the servers' service name string handles and store them in a buffer.

HCONVLIST hconvList; /* conversation list */

DWORD idInst; /* instance identifier */

HSZ hszSystem; /* System topic */

HCONV hconv = NULL; /* conversation handle */

CONVINFO ci; /* holds conversation data */

UINT cConv = 0; /* count of conv. handles */

HSZ *pHsz, *aHsz; /* point to string handles */

/* Connect to all servers that support the System topic. */

hconvList = DdeConnectList(idInst, NULL, hszSystem, NULL, NULL);

/* Count the number of handles in the conversation list. */

while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)

cConv++;

/* Allocate a buffer for the string handles. */

hconv = NULL;

aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ));

/* Copy the string handles to the buffer. */

pHsz = aHsz;

while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL) {

DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci);

DdeKeepStringHandle(idInst, ci.hszSvcPartner);

*pHsz++ = ci.hszSvcPartner;

}

.

. /* Use the handles; converse with the servers. */

.

/* Free the memory and terminate the conversations. */

LocalFree((HANDLE) aHsz);

DdeDisconnectList(hconvList);

An application can terminate an individual conversation in a conversation list by calling the DdeDisconnect function. An application can terminate all conversations in a conversation list by calling the DdeDisconnectList function. Both functions cause the DDEML to send XTYP_DISCONNECT transactions to each partner's DDE callback function. DdeDisconnectList sends an XTYP_DISCONNECT transaction for each conversation handle in the list.

A client can retrieve a list of the conversation handles in a conversation list by passing an existing conversation list handle to DdeConnectList. The enumeration process removes the handles of terminated conversations from the list, and nonduplicate conversations that fit the specified service name and topic name are added.

If DdeConnectList specifies an existing conversation list handle, the function creates a new conversation list that contains the handles of any new conversations and the handles from the existing list.

If duplicate conversations exist, DdeConnectList attempts to prevent duplicate conversation handles in the conversation list. A duplicate conversation is a second conversation with the same server on the same service name and topic name. Two such conversations would have different handles, yet they would identify the same conversation.