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.
Depois de estabelecer uma conversa com um servidor, um cliente pode enviar transações para obter dados e serviços do servidor.
Os tópicos a seguir descrevem os tipos de transações que os clientes podem usar para interagir com um servidor.
- de transação de solicitação
- de transação de cutucar
- aconselhar de transação
- executar de transação
- transações síncronas e assíncronas
- de controle de transação
- classes de transação
- tipos de transação
Transação de solicitação
Um aplicativo cliente pode usar a transação XTYP_REQUEST para solicitar um item de dados de um aplicativo de servidor. O cliente chama a função DdeClientTransaction, especificando XTYP_REQUEST como o tipo de transação e especificando o item de dados de que o aplicativo precisa.
A DDEML (Dynamic Data Exchange Management Library) passa a transação XTYP_REQUEST para o servidor, especificando o nome do tópico, o nome do item e o formato de dados solicitados pelo cliente. Se o servidor der suporte ao tópico, item e formato solicitados, o servidor deverá retornar um identificador de dados que identifique o valor atual do item. O DDEML passa esse identificador para o cliente como o valor retornado de DdeClientTransaction. O servidor deverá retornar NULL se não der suporte ao tópico, item ou formato solicitado.
DdeClientTransaction usa o parâmetro lpdwResult para retornar um sinalizador de status de transação ao cliente. Se o servidor não processar a transação XTYP_REQUEST, DdeClientTransaction retornará NULL e lpdwResult apontará para o sinalizador DDE_FNOTPROCESSED ou DDE_FBUSY. Se o sinalizador DDE_FNOTPROCESSED for retornado, o cliente não poderá determinar por que o servidor não processou a transação.
Se um servidor não der suporte à transação de XTYP_REQUEST, ele deverá especificar o sinalizador de filtro CBF_FAIL_REQUESTS na função DdeInitialize. Esse sinalizador impede que o DDEML envie a transação para o servidor.
Transação de cutucar
Um cliente pode enviar dados não solicitados para um servidor usando DdeClientTransaction para enviar uma transação XTYP_POKE para a função de retorno de chamada de um servidor.
O aplicativo cliente primeiro cria um buffer que contém os dados a serem enviados para o servidor e, em seguida, passa um ponteiro para o buffer como um parâmetro para DdeClientTransaction. Como alternativa, o cliente pode usar a função DdeCreateDataHandle para obter um identificador de dados que identifica os dados e, em seguida, passar o identificador para DdeClientTransaction. Em ambos os casos, o cliente também especifica o nome do tópico, o nome do item e o formato de dados quando chama DdeClientTransaction.
O DDEML passa a transação XTYP_POKE para o servidor, especificando o nome do tópico, o nome do item e o formato de dados solicitados pelo cliente. Para aceitar o item de dados e o formato, o servidor deve retornar DDE_FACK. Para rejeitar os dados, o servidor deve retornar DDE_FNOTPROCESSED. Se o servidor estiver muito ocupado para aceitar os dados, o servidor deverá retornar DDE_FBUSY.
Quando DdeClientTransaction retorna, o cliente pode usar o parâmetro lpdwResult para acessar o sinalizador de status da transação. Se o sinalizador for DDE_FBUSY, o cliente deverá enviar a transação novamente mais tarde.
Se um servidor não der suporte à transação de XTYP_POKE, ele deverá especificar o sinalizador de filtro CBF_FAIL_POKES em DdeInitialize. Esse sinalizador impede que o DDEML envie essa transação para o servidor.
Aconselhar transação
Um aplicativo cliente pode usar o DDEML para estabelecer um ou mais links para itens em um aplicativo de servidor. Quando esse link for estabelecido, o servidor enviará atualizações periódicas sobre o item vinculado ao cliente (normalmente, sempre que o valor do item associado ao aplicativo do servidor for alterado). A vinculação estabelece um loop de consultoria entre os dois aplicativos que permanece em vigor até que o cliente o encerre.
Há dois tipos de loops de aconselhamento: "quente" e "quente". Em um loop de aviso frequente, o servidor envia imediatamente um identificador de dados que identifica o valor alterado. Em um loop de consultoria frequente, o servidor notifica o cliente de que o valor do item foi alterado, mas não envia o identificador de dados até que o cliente o solicite.
Um cliente pode solicitar um loop de consultoria frequente com um servidor especificando o tipo de transação XTYP_ADVSTART em uma chamada para DdeClientTransaction. Para solicitar um loop de aconselhamento frequente, o cliente deve combinar o sinalizador de XTYPF_NODATA com o tipo de transação XTYP_ADVSTART. Em qualquer um dos eventos, o DDEML passa a transação XTYP_ADVSTART para a função de retorno de chamada DDE (Dynamic Data Exchange) do servidor. A função de retorno de chamada DDE do servidor deve examinar os parâmetros que acompanham a transação de XTYP_ADVSTART (incluindo o formato solicitado, o nome do tópico e o nome do item) e, em seguida, retornar verdadeiro para permitir que o loop de aconselhamento ou false negá-lo.
Depois que um loop de consultoria tiver sido estabelecido, o aplicativo do servidor deverá chamar a função DdePostAdvise sempre que o valor do item associado ao nome do item solicitado for alterado. Essa chamada resulta em uma transação XTYP_ADVREQ sendo enviada para a função de retorno de chamada DDE do próprio servidor. A função de retorno de chamada DDE do servidor deve retornar um identificador de dados que identifique o novo valor do item de dados. Em seguida, o DDEML notifica o cliente de que o item especificado foi alterado enviando a transação XTYP_ADVDATA para a função de retorno de chamada DDE do cliente.
Se o cliente solicitou um loop de aviso frequente, o DDEML passa o identificador de dados para o item alterado para o cliente durante a transação XTYP_ADVDATA. Caso contrário, o cliente poderá enviar uma transação XTYP_REQUEST para obter o identificador de dados.
É possível que um servidor envie atualizações mais rapidamente do que um cliente pode processar os novos dados. A velocidade das atualizações pode ser um problema para um cliente que deve executar longas operações de processamento nos dados. Nesse caso, o cliente deve especificar o sinalizador de XTYPF_ACKREQ quando solicitar um loop de consultoria. Esse sinalizador faz com que o servidor aguarde até que o cliente reconheça que recebeu e processou um item de dados antes que o servidor envie o próximo item de dados. Informe que os loops estabelecidos com o sinalizador XTYPF_ACKREQ são mais robustos com servidores rápidos, mas que ocasionalmente podem perder atualizações. Recomendamos que os loops estabelecidos sem o sinalizador de XTYPF_ACKREQ não percam as atualizações, desde que o cliente acompanhe o servidor.
Um cliente pode encerrar um loop de consultoria especificando o tipo de transação XTYP_ADVSTOP em uma chamada para DdeClientTransaction.
Se um servidor não der suporte a loops de consultoria, ele deverá especificar o sinalizador de filtro CBF_FAIL_ADVISES na função DdeInitialize. Esse sinalizador impede que o DDEML envie as transações XTYP_ADVSTART e XTYP_ADVSTOP para o servidor.
Executar transação
Um cliente pode usar a transação XTYP_EXECUTE para fazer com que um servidor execute um comando ou uma série de comandos.
Para executar um comando de servidor, o cliente primeiro cria um buffer que contém uma cadeia de caracteres de comando para o servidor executar e, em seguida, passa um ponteiro para o buffer ou um identificador de dados que identifica o buffer quando ele chama DdeClientTransaction. Outros parâmetros necessários incluem o identificador de conversa, o identificador de cadeia de caracteres do nome do item, a especificação de formato e o tipo de transação XTYP_EXECUTE. Um aplicativo que cria um identificador de dados para passar dados de execução deve especificar NULL para o parâmetro hszItem da função DdeCreateDataHandle e zero para o parâmetro uFmt.
O DDEML passa a transação XTYP_EXECUTE para a função de retorno de chamada DDE do servidor e especifica o nome do formato, o identificador de conversa, o nome do tópico e o identificador de dados que identificam a cadeia de caracteres de comando. Se o servidor der suporte ao comando, ele deverá usar a função DdeAccessData para obter um ponteiro para a cadeia de caracteres de comando, executar o comando e retornar DDE_FACK. Se o servidor não der suporte ao comando ou não puder concluir a transação, ele deverá retornar DDE_FNOTPROCESSED. O servidor deverá retornar DDE_FBUSY se estiver muito ocupado para concluir a transação.
Em geral, a função de retorno de chamada de um servidor deve processar a transação XTYP_EXECUTE antes de retornar com as seguintes exceções:
- Quando o comando passado com a transação XTYP_EXECUTE solicita que o servidor seja encerrado, o servidor não deverá ser encerrado até que sua função de retorno de chamada retorne do processamento XTYP_EXECUTE.
- Se o servidor precisar executar uma operação, como processar uma caixa de diálogo ou uma transação DDE que possa causar problemas de recursão DDEML, o servidor deverá retornar a CBR_BLOCK código de retorno para bloquear a transação de execução, executar a operação e, em seguida, retomar o processamento da transação de execução.
Quando DdeClientTransaction retorna, o cliente pode usar o parâmetro lpdwResult para acessar o sinalizador de status da transação. Se o sinalizador for DDE_FBUSY, o cliente deverá enviar a transação novamente mais tarde.
Se um servidor não der suporte à transação XTYP_EXECUTE, ele deverá especificar o sinalizador de filtro CBF_FAIL_EXECUTES na função DdeInitialize. Isso impede que o DDEML envie a transação para o servidor.
Transações síncronas e assíncronas
Um cliente pode enviar transações síncronas ou assíncronas. Em uma transação síncrona, o cliente especifica um valor de tempo limite que indica o tempo máximo que aguardará o servidor processar a transação. DdeClientTransaction não retorna até que o servidor processe a transação, a transação falhe ou o valor de tempo limite expire. O cliente especifica o valor de tempo limite quando chama DdeClientTransaction.
Durante uma transação síncrona, o cliente insere um loop modal enquanto aguarda o processamento da transação. O cliente ainda pode processar a entrada do usuário, mas não pode enviar outra transação síncrona até que DdeClientTransaction retorne.
Um cliente envia uma transação assíncrona especificando o sinalizador TIMEOUT_ASYNC em DdeClientTransaction. A função retorna depois que a transação é iniciada, passando um identificador de transação para o cliente. Quando o servidor termina de processar a transação assíncrona, o DDEML envia uma transação XTYP_XACT_COMPLETE para o cliente. Um dos parâmetros que o DDEML passa para o cliente durante a transação XTYP_XACT_COMPLETE é o identificador de transação. Comparando esse identificador de transação com o identificador retornado por DdeClientTransaction, o cliente identifica qual transação assíncrona o servidor concluiu o processamento.
Um cliente pode usar a funçãoDdeSetUserHandle como um auxílio no processamento de uma transação assíncrona. Essa função possibilita que um cliente associe um valor definido pelo aplicativo a um identificador de conversa e a um identificador de transação. O cliente pode usar a funçãoDdeQueryConvInfo durante a transação XTYP_XACT_COMPLETE para obter o valor definido pelo aplicativo. Devido a essa função, um aplicativo não precisa manter uma lista de identificadores de transação ativos.
Quando um cliente conclui com êxito uma solicitação de dados usando uma transação síncrona, o DDEML não tem como informar quando o cliente terminou de usar os dados recebidos. O aplicativo cliente deve passar o identificador de dados recebido para a função DdeFreeDataHandle, notificando o DDEML de que o identificador não será mais usado. Os identificadores de dados retornados por transações síncronas pertencem efetivamente ao cliente.
Se um servidor não processar uma transação assíncrona em tempo hábil, o cliente poderá abandonar a transação chamando a função DdeAbandonTransaction. O DDEML libera todos os recursos associados à transação e descarta os resultados da transação quando o servidor termina de processá-la. Um tempo limite durante uma transação síncrona cancela efetivamente a transação.
O método de transação assíncrona é fornecido para aplicativos que devem enviar um alto volume de transações DDE ao mesmo tempo em que executam uma quantidade substancial de processamento, como a execução de cálculos. O método assíncrono também é útil em aplicativos que devem parar de processar transações DDE temporariamente para que possam concluir outras tarefas sem interrupção. Na maioria das outras situações, um aplicativo deve usar o método síncrono.
Transações síncronas são mais simples de manter e são mais rápidas do que transações assíncronas. No entanto, apenas uma transação síncrona pode ser executada de cada vez, enquanto muitas transações assíncronas podem ser executadas simultaneamente. Com transações síncronas, um servidor lento pode fazer com que um cliente permaneça ocioso enquanto aguarda uma resposta. Além disso, transações síncronas fazem com que o cliente insira um loop modal que possa ignorar a filtragem de mensagens no loop de mensagem do próprio aplicativo.
Se o cliente tiver instalado um procedimento de gancho para filtrar mensagens (ou seja, especificou o tipo de gancho WH_MSGFILTER em uma chamada para a função SetWindowsHookEx), uma transação síncrona não fará com que o sistema ignore o procedimento de gancho. Quando um evento de entrada ocorre enquanto o cliente aguarda o término de uma transação síncrona, o procedimento de gancho recebe um código de gancho MSGF_DDEMGR. O principal perigo de usar um loop modal de transação síncrona é que um loop modal criado por uma caixa de diálogo pode interferir em sua operação. Transações assíncronas sempre devem ser usadas quando o DDEML está sendo usado por uma DLL.
Controle de transação
Um aplicativo pode suspender transações para sua função de retorno de chamada DDE, seja essas transações associadas a um identificador de conversa específico ou todas as transações, independentemente do identificador de conversa. Essa funcionalidade é útil quando um aplicativo recebe uma transação que requer processamento longo. Nesse caso, o aplicativo pode retornar o código de retorno CBR_BLOCK para suspender transações futuras associadas ao identificador de conversa da transação, de modo que o aplicativo seja livre para processar outras conversas.
Quando o processamento for concluído, o aplicativo chamará a função DdeEnableCallback para retomar as transações associadas à conversa suspensa. Chamar DdeEnableCallback faz com que o DDEML reenviar a transação que resultou na suspensão da conversa pelo aplicativo. Portanto, o aplicativo deve armazenar o resultado da transação de forma que possa obter e retornar o resultado sem reprocessar a transação.
Um aplicativo pode suspender todas as transações associadas a um identificador de conversa específico especificando o identificador e o sinalizador de EC_DISABLE em uma chamada para DdeEnableCallback. Ao especificar um identificador de NULL, um aplicativo pode suspender todas as transações para todas as conversas.
Quando uma conversa é suspensa, o DDEML salva transações para a conversa em uma fila de transações. Quando o aplicativo reabilita a conversa, o DDEML remove as transações salvas da fila e passa cada transação para a função de retorno de chamada apropriada. A capacidade da fila de transações é grande, mas um aplicativo deve reabilitar uma conversa suspensa o mais rápido possível para evitar a perda de transações.
Um aplicativo pode retomar o processamento de transações usuais especificando o sinalizador EC_ENABLEALL em DdeEnableCallback. Para uma retomada mais controlada do processamento de transações, o aplicativo pode especificar o sinalizador de EC_ENABLEONE. Esse sinalizador remove uma transação da fila de transações e a passa para a função de retorno de chamada apropriada; depois que essa transação tiver sido processada, todas as conversas serão desabilitadas novamente.
Se o sinalizador EC_ENABLEONE e um identificador de conversa forem especificados na chamada para DdeEnableCallback, somente essa conversa será bloqueada após o processamento da transação. Se um NULL identificador de conversa for especificado, todas as conversas serão bloqueadas depois que uma transação for processada em qualquer conversa.
Classes de transação
O DDEML tem quatro classes de transações. Cada classe é identificada por uma constante que começa com o prefixo XCLASS_. As classes são definidas no arquivo de cabeçalho DDEML. O valor da classe é combinado com o valor do tipo transação e é passado para a função de retorno de chamada DDE do aplicativo receptor.
A classe de uma transação determina o valor retornado que uma função de retorno de chamada deverá retornar se processar a transação. Os valores retornados a seguir e os tipos de transação são associados a cada uma das quatro classes de transação.
| Classe | Valor de retorno | Transação |
|---|---|---|
| XCLASS_BOOL | TRUE ou FALSE |
XTYP_ADVSTART XTYP_CONNECT |
| XCLASS_DATA | Um identificador de dados, o código de retorno CBR_BLOCK ou NULL |
XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT |
| XCLASS_FLAGS | Um sinalizador de transação: DDE_FACK, DDE_FBUSY ou DDE_FNOTPROCESSED |
XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE |
| XCLASS_NOTIFICATION | Nenhum |
XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_REGISTER XTYP_UNREGISTER XTYP_XACT_COMPLETE |
Tipos de transação
Cada tipo de transação DDE tem um receptor e uma atividade associada que faz com que o DDEML gere cada tipo.
| Tipo de transação | Receptor | Causa |
|---|---|---|
| XTYP_ADVDATA | Cliente | Um servidor respondeu a uma transação XTYP_ADVREQ retornando um identificador de dados. |
| XTYP_ADVREQ | Servidor | Um servidor chamado função DdePostAdvise, indicando que o valor de um item de dados em um loop de consultoria havia sido alterado. |
| XTYP_ADVSTART | Servidor | Um cliente especificou o tipo de transação XTYP_ADVSTART em uma chamada para a funçãoDdeClientTransaction. |
| XTYP_ADVSTOP | Servidor | Um cliente especificou o tipo de transação XTYP_ADVSTOP em uma chamada para DdeClientTransaction. |
| XTYP_CONNECT | Servidor | Um cliente chamado função DdeConnect e especificou um nome de serviço e um nome de tópico com suporte pelo servidor. |
| XTYP_CONNECT_CONFIRM | Servidor | O servidor retornou TRUE em resposta a uma transação de XTYP_CONNECT ou XTYP_WILDCONNECT. |
| XTYP_DISCONNECT | Cliente/Servidor | Um parceiro em uma conversa chamada função DdeDisconnect, fazendo com que ambos os parceiros recebam essa transação. |
| XTYP_ERROR | Cliente/Servidor | Ocorreu um erro crítico. O DDEML pode não ter recursos suficientes para continuar. |
| XTYP_EXECUTE | Servidor | Um cliente especificou o tipo de transação XTYP_EXECUTE em uma chamada para DdeClientTransaction. |
| XTYP_MONITOR | Aplicativo de monitoramento de DDE | Um evento DDE ocorreu no sistema. Para obter mais informações sobre aplicativos de monitoramento de DDE, consulte Aplicativos de Monitoramento. |
| XTYP_POKE | Servidor | Um cliente especificou o tipo de transação XTYP_POKE em uma chamada para DdeClientTransaction. |
| XTYP_REGISTER | Cliente/Servidor | Um aplicativo de servidor usou a função DdeNameService para registrar um nome de serviço. |
| XTYP_REQUEST | Servidor | Um cliente especificou o tipo de transação XTYP_REQUEST em uma chamada para DdeClientTransaction. |
| XTYP_UNREGISTER | Cliente/Servidor | Um aplicativo de servidor usado DdeNameService para cancelar o registro de um nome de serviço. |
| XTYP_WILDCONNECT | Servidor | Um cliente chamadoDdeConnectou função DdeConnectList, especificando NULL para o nome do serviço, o nome do tópico ou ambos. |
| XTYP_XACT_COMPLETE | Cliente | Uma transação assíncrona, enviada quando o cliente especificou o sinalizador TIMEOUT_ASYNC em uma chamada para DdeClientTransaction, foi concluída. |