Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Uma conversa entre um cliente e um servidor é sempre estabelecida a pedido do cliente. Quando uma conversa é estabelecida, cada parceiro recebe um identificador que identifica a conversa. Os parceiros usam esse identificador em outras funções DDEML (Dynamic Data Exchange Management Library) para enviar transações e gerenciar a conversa. Um cliente pode solicitar uma conversa com um único servidor ou pode solicitar várias conversas com um ou mais servidores.
Os tópicos a seguir descrevem como um aplicativo estabelece novas conversas e obtém informações sobre conversas existentes.
- de Conversas Simples
- várias conversas
Conversas Simples
Um aplicativo cliente solicita uma única conversa com um servidor chamando a função DdeConnect e especificando identificadores de cadeia de caracteres que identificam as cadeias de caracteres que contêm o nome do serviço do aplicativo do servidor e o nome do tópico da conversa. O DDEML responde enviando a transação XTYP_CONNECT para a função de retorno de chamada DDE (Dynamic Data Exchange) de cada aplicativo de servidor que registrou um nome de serviço que corresponde ao especificado em DdeConnect ou desativou a filtragem de nome de serviço chamando DdeNameService. Um servidor também pode filtrar transações XTYP_CONNECT especificando o sinalizador de filtro CBF_FAIL_CONNECTIONS na função DdeInitialize. Durante a transação XTYP_CONNECT, o DDEML passa o nome do serviço e o nome do tópico para o servidor. O servidor deve examinar os nomes e retornar verdadeiro se ele der suporte ao nome do serviço e ao par de nomes de tópico ou false se não o fizer.
Se nenhum servidor responder positivamente à solicitação do cliente para se conectar, o cliente receberá NULL de DdeConnect e nenhuma conversa será estabelecida. Se um servidor retornar TRUE, uma conversa será estabelecida e o cliente receberá um identificador de conversa — um valor DWORD que identifica a conversa. O cliente usa o identificador em chamadas DDEML subsequentes para obter dados do servidor. O servidor recebe a transação XTYP_CONNECT_CONFIRM (a menos que o servidor especificou o sinalizador de filtro CBF_SKIP_CONNECT_CONFIRMS). Essa transação passa o identificador de conversa para o servidor.
O exemplo a seguir solicita uma conversa no tópico sistema com um servidor que reconhece o nome do serviço MyServer. Os parâmetros hszServName e hszSysTopic são identificadores de cadeia de caracteres criados anteriormente.
HCONV hConv; // conversation handle
HWND hwndParent; // parent window handle
HSZ hszServName; // service name string handle
HSZ hszSysTopic; // System topic string handle
hConv = DdeConnect(
idInst, // instance identifier
hszServName, // service name string handle
hszSysTopic, // System topic string handle
(PCONVCONTEXT) NULL); // use default context
if (hConv == NULL)
{
MessageBox(hwndParent, "MyServer is unavailable.",
(LPSTR) NULL, MB_OK);
return FALSE;
}
No exemplo anterior, DdeConnect faz com que a função de retorno de chamada DDE do aplicativo MyServer receba uma transação XTYP_CONNECT.
No exemplo a seguir, o servidor responde à transação XTYP_CONNECT comparando o identificador de cadeia de caracteres de nome do tópico que o DDEML passou para o servidor com cada elemento na matriz da cadeia de caracteres de nome de tópico que manipula o suporte do servidor. Se o servidor encontrar uma correspondência, ele estabelecerá a conversa.
#define CTOPICS 5
HSZ hsz1; // string handle passed by DDEML
HSZ ahszTopics[CTOPICS]; // array of supported topics
int i; // loop counter
// Use a switch statement to examine transaction types.
// Here is the connect case.
case XTYP_CONNECT:
for (i = 0; i < CTOPICS; i++)
{
if (hsz1 == ahszTopics[i])
return TRUE; // establish a conversation
}
return FALSE; // Topic not supported; deny conversation.
// Process other transaction types.
Se o servidor retornar verdadeiro em resposta à transação XTYP_CONNECT, o DDEML enviará uma transação XTYP_CONNECT_CONFIRM para a função de retorno de chamada DDE do servidor. O servidor pode obter o identificador da conversa processando essa transação.
Um cliente pode estabelecer uma conversa curinga especificando NULL para o identificador de cadeia de caracteres do nome do serviço, o identificador de cadeia de caracteres do nome do tópico ou ambos em uma chamada para DdeConnect. Se pelo menos um dos identificadores de cadeia de caracteres for NULL, o DDEML enviará a transação XTYP_WILDCONNECT para as funções de retorno de chamada de todos os aplicativos DDE (exceto aqueles que filtram a transação XTYP_WILDCONNECT). Cada aplicativo de servidor deve responder retornando um identificador de dados que identifica uma matriz terminada em nulo de estruturas de HSZPAIR. Se o aplicativo de servidor não tiver chamado DdeNameService para registrar seus nomes de serviço e, se a filtragem estiver ativada, o servidor não receberá transações XTYP_WILDCONNECT. Para obter mais informações sobre identificadores de dados, consulte Data Management.
A matriz deve conter uma estrutura para cada nome de serviço e par de nomes de tópico que correspondam ao par especificado pelo cliente. O DDEML seleciona um dos pares para estabelecer uma conversa e retorna ao cliente um identificador que identifica a conversa. O DDEML envia a transação XTYP_CONNECT_CONFIRM para o servidor (a menos que o servidor filtre essa transação). O exemplo a seguir mostra uma resposta típica do servidor à transação XTYP_WILDCONNECT.
#define CTOPICS 2
UINT uType;
HSZPAIR ahszp[(CTOPICS + 1)];
HSZ ahszTopicList[CTOPICS];
HSZ hszServ, hszTopic;
WORD i, j;
if (uType == XTYP_WILDCONNECT)
{
// Scan the topic list and create an array of HSZPAIR structures.
j = 0;
for (i = 0; i < CTOPICS; i++)
{
if (hszTopic == (HSZ) NULL ||
hszTopic == ahszTopicList[i])
{
ahszp[j].hszSvc = hszServ;
ahszp[j++].hszTopic = ahszTopicList[i];
}
}
// End the list with an HSZPAIR structure that contains NULL
// string handles as its members.
ahszp[j].hszSvc = NULL;
ahszp[j++].hszTopic = NULL;
// Return a handle to a global memory object containing the
// HSZPAIR structures.
return DdeCreateDataHandle(
idInst, // instance identifier
(LPBYTE) &ahszp, // pointer to HSZPAIR array
sizeof(HSZ) * j, // length of the array
0, // start at the beginning
(HSZ) NULL, // no item name string
0, // return the same format
0); // let the system own it
}
O cliente ou o servidor podem encerrar uma conversa a qualquer momento chamando a função DdeDisconnect. Essa função faz com que a função de retorno de chamada do parceiro na conversa receba a transação XTYP_DISCONNECT (a menos que o parceiro especificou o sinalizador de filtro CBF_SKIP_DISCONNECTS). Normalmente, um aplicativo responde à transação XTYP_DISCONNECT usando a função DdeQueryConvInfo para obter informações sobre a conversa que terminou. Depois que a função de retorno de chamada retorna do processamento da transação XTYP_DISCONNECT, o identificador de conversa não é mais válido.
Um aplicativo cliente que recebe uma transação XTYP_DISCONNECT em sua função de retorno de chamada DDE pode tentar restabelecer a conversa chamando a função DdeReconnect. O cliente deve chamar DdeReconnect de dentro de sua função de retorno de chamada DDE.
Várias conversas
Um aplicativo cliente pode usar a função DdeConnectList para determinar se os servidores de interesse estão disponíveis no sistema. Um cliente especifica um nome de serviço e um nome de tópico quando chama DdeConnectList, fazendo com que o DDEML transmita a transação XTYP_WILDCONNECT para as funções de retorno de chamada DDE de todos os servidores que correspondem ao nome do serviço (exceto aqueles que filtram a transação). A função de retorno de chamada de um servidor deve retornar um identificador de dados que identifique uma matriz terminada em nulo de estruturas de HSZPAIR. A matriz deve conter uma estrutura para cada nome de serviço e par de nomes de tópico que correspondam ao par especificado pelo cliente. O DDEML estabelece uma conversa para cada estrutura de HSZPAIR preenchida pelo servidor e retorna um identificador de lista de conversa para o cliente. O servidor recebe o identificador de conversa por meio da transação XTYP_CONNECT (a menos que o servidor filtre essa transação).
Um cliente pode especificar NULL para o nome do serviço, o nome do tópico ou ambos quando chama DdeConnectList. Se o nome do serviço for NULL, todos os servidores no sistema que dão suporte ao nome do tópico especificado responderão. Uma conversa é estabelecida com cada servidor que responde, incluindo várias instâncias do mesmo servidor. Se o nome do tópico for NULL, uma conversa será estabelecida em cada tópico reconhecido por cada servidor que corresponde ao nome do serviço.
Um cliente pode usar as funções DdeQueryNextServer e DdeQueryConvInfo para identificar os servidores que respondem a DdeConnectList. DdeQueryNextServer retorna o próximo identificador de conversa em uma lista de conversas e DdeQueryConvInfo preenche uma estrutura de CONVINFO com informações sobre a conversa. O cliente pode manter os identificadores de conversa necessários e descartar o restante da lista de conversas.
O exemplo a seguir usa DdeConnectList para estabelecer conversas com todos os servidores que dão suporte ao tópico do Sistema e, em seguida, usa oDdeQueryNextServere funções DdeQueryConvInfo para obter os identificadores de cadeia de caracteres de nome de serviço dos servidores e armazená-los em um 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);
Um aplicativo pode encerrar uma conversa individual em uma lista de conversas chamando a função DdeDisconnect. Um aplicativo pode encerrar todas as conversas em uma lista de conversas chamando a função DdeDisconnectList. Ambas as funções fazem com que o DDEML envie transações XTYP_DISCONNECT para a função de retorno de chamada DDE de cada parceiro. DdeDisconnectList envia uma transação XTYP_DISCONNECT para cada identificador de conversa na lista.
Um cliente pode recuperar uma lista dos identificadores de conversa em uma lista de conversas passando um identificador de lista de conversa existente para DdeConnectList. O processo de enumeração remove os identificadores de conversas encerradas da lista e as conversas não duplicadas que se encaixam no nome do serviço especificado e no nome do tópico são adicionadas.
Se DdeConnectList especificar um identificador de lista de conversa existente, a função criará uma nova lista de conversas que contém os identificadores de novas conversas e os identificadores da lista existente.
Se houver conversas duplicadas, DdeConnectList tenta impedir identificadores de conversa duplicados na lista de conversas. Uma conversa duplicada é uma segunda conversa com o mesmo servidor no mesmo nome de serviço e nome do tópico. Duas dessas conversas teriam identificadores diferentes, mas identificariam a mesma conversa.