Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Après avoir établi une conversation avec un serveur, un client peut envoyer des transactions pour obtenir des données et des services à partir du serveur.
Les rubriques suivantes décrivent les types de transactions que les clients peuvent utiliser pour interagir avec un serveur.
- demander une transaction
- de transaction Poke
- conseiller les transactions
- exécuter des de transaction
- transactions synchrones et asynchrones
- de contrôle des transactions
- classes de transactions
- types de transactions
Transaction de requête
Une application cliente peut utiliser la transaction XTYP_REQUEST pour demander un élément de données à partir d’une application serveur. Le client appelle la fonction DdeClientTransaction, en spécifiant XTYP_REQUEST comme type de transaction et en spécifiant l’élément de données dont l’application a besoin.
La bibliothèque de gestion Dynamic Data Exchange (DDEML) transmet la transaction XTYP_REQUEST au serveur, en spécifiant le nom de la rubrique, le nom de l’élément et le format de données demandé par le client. Si le serveur prend en charge la rubrique, l’élément et le format demandés, le serveur doit retourner un handle de données qui identifie la valeur actuelle de l’élément. Le DDEML transmet ce handle au client en tant que valeur de retour de DdeClientTransaction. Le serveur doit retourner NULL s’il ne prend pas en charge la rubrique, l’élément ou le format demandé.
DdeClientTransaction utilise le paramètre lpdwResult pour renvoyer un indicateur d’état de transaction au client. Si le serveur ne traite pas la transaction XTYP_REQUEST, DdeClientTransaction retourne NULL et lpdwResult pointe vers l’indicateur DDE_FNOTPROCESSED ou DDE_FBUSY. Si l’indicateur DDE_FNOTPROCESSED est retourné, le client ne peut pas déterminer pourquoi le serveur n’a pas traité la transaction.
Si un serveur ne prend pas en charge la transaction XTYP_REQUEST, il doit spécifier l’indicateur de filtre CBF_FAIL_REQUESTS dans la fonction DdeInitialize. Cet indicateur empêche le DDEML d’envoyer la transaction au serveur.
Poke Transaction
Un client peut envoyer des données non sollicitées à un serveur à l’aide de DdeClientTransaction pour envoyer une transaction XTYP_POKE à la fonction de rappel d’un serveur.
L’application cliente crée d’abord une mémoire tampon qui contient les données à envoyer au serveur, puis transmet un pointeur à la mémoire tampon en tant que paramètre pour DdeClientTransaction. Le client peut également utiliser la fonction DdeCreateDataHandle pour obtenir un handle de données qui identifie les données, puis passer le handle à DdeClientTransaction. Dans les deux cas, le client spécifie également le nom de la rubrique, le nom de l’élément et le format de données lorsqu’il appelle DdeClientTransaction.
Le DDEML transmet la transaction XTYP_POKE au serveur, en spécifiant le nom de la rubrique, le nom de l’élément et le format de données demandés par le client. Pour accepter l’élément de données et le format, le serveur doit retourner DDE_FACK. Pour rejeter les données, le serveur doit retourner DDE_FNOTPROCESSED. Si le serveur est trop occupé pour accepter les données, le serveur doit retourner DDE_FBUSY.
Quand DdeClientTransaction retourne, le client peut utiliser le paramètre lpdwResult pour accéder à l’indicateur d’état de transaction. Si l’indicateur est DDE_FBUSY, le client doit renvoyer la transaction ultérieurement.
Si un serveur ne prend pas en charge la transaction XTYP_POKE, il doit spécifier l’indicateur de filtre CBF_FAIL_POKES dans DdeInitialize. Cet indicateur empêche le DDEML d’envoyer cette transaction au serveur.
Conseiller la transaction
Une application cliente peut utiliser le DDEML pour établir un ou plusieurs liens vers des éléments d’une application serveur. Lorsqu’un tel lien a été établi, le serveur envoie des mises à jour périodiques sur l’élément lié au client (généralement, chaque fois que la valeur de l’élément associé à l’application serveur change). La liaison établit une boucle d’avis entre les deux applications qui restent en place jusqu’à ce que le client le termine.
Il existe deux types de boucles de conseil : « chaud » et « chaud ». Dans une boucle d’avis à chaud, le serveur envoie immédiatement un handle de données qui identifie la valeur modifiée. Dans une boucle d’avis chaude, le serveur informe le client que la valeur de l’élément a changé, mais n’envoie pas le handle de données tant que le client ne le demande pas.
Un client peut demander une boucle d’avis à chaud avec un serveur en spécifiant le type de transaction XTYP_ADVSTART dans un appel à DdeClientTransaction. Pour demander une boucle d’avis chaude, le client doit combiner l’indicateur XTYPF_NODATA avec le type de transaction XTYP_ADVSTART. Dans les deux cas, le DDEML transmet la transaction XTYP_ADVSTART à la fonction de rappel DDE (Dynamic Data Exchange) du serveur. La fonction de rappel DDE du serveur doit examiner les paramètres qui accompagnent la transaction XTYP_ADVSTART (y compris le format demandé, le nom de rubrique et le nom de l’élément), puis retourner TRUE pour autoriser la boucle de conseil ou FALSE le refuser.
Une fois qu’une boucle de conseil a été établie, l’application serveur doit appeler la fonction DdePostAdvise chaque fois que la valeur de l’élément associé au nom de l’élément demandé change. Cet appel entraîne l’envoi d’une transaction XTYP_ADVREQ à la fonction de rappel DDE du serveur. La fonction de rappel DDE du serveur doit retourner un handle de données qui identifie la nouvelle valeur de l’élément de données. Le DDEML informe ensuite le client que l’élément spécifié a changé en envoyant la transaction XTYP_ADVDATA à la fonction de rappel DDE du client.
Si le client a demandé une boucle d’avis à chaud, le DDEML transmet le handle de données à l’élément modifié au client pendant la transaction XTYP_ADVDATA. Sinon, le client peut envoyer une transaction XTYP_REQUEST pour obtenir le handle de données.
Il est possible qu’un serveur envoie des mises à jour plus rapidement qu’un client peut traiter les nouvelles données. La vitesse des mises à jour peut être un problème pour un client qui doit effectuer des opérations de traitement longues sur les données. Dans ce cas, le client doit spécifier l’indicateur XTYPF_ACKREQ lorsqu’il demande une boucle d’avis. Cet indicateur entraîne l’attente du serveur pour que le client reconnaisse qu’il a reçu et traité un élément de données avant que le serveur envoie l’élément de données suivant. Les boucles de conseil établies avec l’indicateur de XTYPF_ACKREQ sont plus robustes avec les serveurs rapides, mais peuvent parfois manquer des mises à jour. Les boucles de conseil établies sans l’indicateur de XTYPF_ACKREQ sont garanties de ne pas manquer les mises à jour tant que le client continue avec le serveur.
Un client peut mettre fin à une boucle d’avis en spécifiant le type de transaction XTYP_ADVSTOP dans un appel à DdeClientTransaction.
Si un serveur ne prend pas en charge les boucles d’avis, il doit spécifier l’indicateur de filtre CBF_FAIL_ADVISES dans la fonction DdeInitialize. Cet indicateur empêche le DDEML d’envoyer les transactions XTYP_ADVSTART et XTYP_ADVSTOP au serveur.
Exécuter la transaction
Un client peut utiliser la transaction XTYP_EXECUTE pour provoquer l’exécution d’une commande ou d’une série de commandes sur un serveur.
Pour exécuter une commande de serveur, le client crée d’abord une mémoire tampon qui contient une chaîne de commande pour que le serveur s’exécute, puis passe un pointeur vers la mémoire tampon ou un handle de données identifiant la mémoire tampon lorsqu’il appelle DdeClientTransaction. Les autres paramètres requis incluent le handle de conversation, le handle de chaîne de nom d’élément, la spécification de format et le type de transaction XTYP_EXECUTE. Une application qui crée un handle de données pour transmettre des données d’exécution doit spécifier NULL pour le paramètre hszItem de la fonctionDdeCreateDataHandleet zéro pour le paramètre uFmt.
Le DDEML transmet la transaction XTYP_EXECUTE à la fonction de rappel DDE du serveur et spécifie le nom de format, le handle de conversation, le nom de rubrique et le handle de données identifiant la chaîne de commande. Si le serveur prend en charge la commande, il doit utiliser la fonction DdeAccessData pour obtenir un pointeur vers la chaîne de commande, exécuter la commande, puis retourner DDE_FACK. Si le serveur ne prend pas en charge la commande ou ne peut pas terminer la transaction, il doit retourner DDE_FNOTPROCESSED. Le serveur doit retourner DDE_FBUSY s’il est trop occupé pour terminer la transaction.
En général, la fonction de rappel d’un serveur doit traiter la transaction XTYP_EXECUTE avant de retourner avec les exceptions suivantes :
- Lorsque la commande passée avec la transaction XTYP_EXECUTE demande au serveur de s’arrêter, le serveur ne doit pas se terminer tant que sa fonction de rappel ne doit pas être retournée par le traitement XTYP_EXECUTE.
- Si le serveur doit effectuer une opération, telle que le traitement d’une boîte de dialogue ou d’une transaction DDE susceptible de provoquer des problèmes de récursivité DDEML, le serveur doit retourner le code CBR_BLOCK retourner le code pour bloquer la transaction d’exécution, effectuer l’opération, puis reprendre le traitement de la transaction d’exécution.
Quand DdeClientTransaction retourne, le client peut utiliser le paramètre lpdwResult pour accéder à l’indicateur d’état de la transaction. Si l’indicateur est DDE_FBUSY, le client doit renvoyer la transaction ultérieurement.
Si un serveur ne prend pas en charge la transaction XTYP_EXECUTE, il doit spécifier l’indicateur de filtre CBF_FAIL_EXECUTES dans la fonction DdeInitialize. Cela empêche le DDEML d’envoyer la transaction au serveur.
Transactions synchrones et asynchrones
Un client peut envoyer des transactions synchrones ou asynchrones. Dans une transaction synchrone, le client spécifie une valeur de délai d’attente qui indique la durée maximale pendant laquelle il attend que le serveur traite la transaction. DdeClientTransaction ne retourne pas tant que le serveur ne traite pas la transaction, que la transaction échoue ou que la valeur de délai d’expiration expire. Le client spécifie la valeur de délai d’attente lorsqu’il appelle DdeClientTransaction.
Pendant une transaction synchrone, le client entre une boucle modale en attendant que la transaction soit traitée. Le client peut toujours traiter l’entrée utilisateur, mais ne peut pas envoyer une autre transaction synchrone tant que DdeClientTransaction retourne.
Un client envoie une transaction asynchrone en spécifiant l’indicateur TIMEOUT_ASYNC dans DdeClientTransaction . La fonction retourne une fois la transaction commencée, en passant un identificateur de transaction au client. Lorsque le serveur termine le traitement de la transaction asynchrone, le DDEML envoie une transaction XTYP_XACT_COMPLETE au client. L’un des paramètres que le DDEML transmet au client pendant la transaction XTYP_XACT_COMPLETE est l’identificateur de transaction. En comparant cet identificateur de transaction à l’identificateur retourné par DdeClientTransaction, le client identifie quelle transaction asynchrone le serveur a terminé le traitement.
Un client peut utiliser la fonction DdeSetUserHandle comme aide au traitement d’une transaction asynchrone. Cette fonction permet à un client d’associer une valeur définie par l’application à un handle de conversation et à un identificateur de transaction. Le client peut utiliser la fonction DdeQueryConvInfo pendant la transaction XTYP_XACT_COMPLETE pour obtenir la valeur définie par l’application. En raison de cette fonction, une application n’a pas besoin de conserver une liste d’identificateurs de transaction actifs.
Lorsqu’un client termine correctement une demande de données à l’aide d’une transaction synchrone, le DDEML n’a aucun moyen de savoir quand le client a terminé d’utiliser les données reçues. L’application cliente doit transmettre le handle de données reçu à la fonctionDdeFreeDataHandle, en informant le DDEML que le handle ne sera plus utilisé. Les handles de données retournés par les transactions synchrones appartiennent effectivement au client.
Si un serveur ne traite pas une transaction asynchrone en temps opportun, le client peut abandonner la transaction en appelant la fonction DdeAbandonTransaction. Le DDEML libère toutes les ressources associées à la transaction et ignore les résultats de la transaction une fois le serveur terminé de le traiter. Un délai d’attente pendant une transaction synchrone annule efficacement la transaction.
La méthode de transaction asynchrone est fournie pour les applications qui doivent envoyer un volume élevé de transactions DDE tout en effectuant simultanément une quantité importante de traitement, comme l’exécution de calculs. La méthode asynchrone est également utile dans les applications qui doivent arrêter de traiter temporairement les transactions DDE afin qu’elles puissent effectuer d’autres tâches sans interruption. Dans la plupart des autres cas, une application doit utiliser la méthode synchrone.
Les transactions synchrones sont plus simples à gérer et sont plus rapides que les transactions asynchrones. Toutefois, une seule transaction synchrone peut être effectuée à la fois, tandis que de nombreuses transactions asynchrones peuvent être effectuées simultanément. Avec les transactions synchrones, un serveur lent peut entraîner l’inactivité d’un client pendant qu’il attend une réponse. En outre, les transactions synchrones entraînent l’entrée d’une boucle modale qui peut contourner le filtrage des messages dans la boucle de message de l’application.
Si le client a installé une procédure de raccordement pour filtrer les messages (autrement dit, spécifié le type de hook WH_MSGFILTER dans un appel à la fonction SetWindowsHookEx), une transaction synchrone n’entraîne pas le contournement de la procédure de hook. Lorsqu’un événement d’entrée se produit pendant que le client attend la fin d’une transaction synchrone, la procédure de raccordement reçoit un code de hook MSGF_DDEMGR. Le principal danger d’utiliser une boucle modale transactionnelle synchrone est qu’une boucle modale créée par une boîte de dialogue peut interférer avec son opération. Les transactions asynchrones doivent toujours être utilisées lorsque le DDEML est utilisé par une DLL.
Contrôle de transaction
Une application peut suspendre les transactions à sa fonction de rappel DDE soit celles associées à un handle de conversation spécifique, soit toutes les transactions, quel que soit le handle de conversation. Cette fonctionnalité est utile lorsqu’une application reçoit une transaction nécessitant un traitement long. Dans ce cas, l’application peut retourner le code de retour CBR_BLOCK pour suspendre les futures transactions associées au handle de conversation de la transaction, afin que l’application soit libre de traiter d’autres conversations.
Une fois le traitement terminé, l’application appelle la fonction DdeEnableCallback pour reprendre les transactions associées à la conversation suspendue. L’appel de DdeEnableCallback entraîne le renvoi de la transaction à la suite de la suspension de la conversation par l’application. Par conséquent, l’application doit stocker le résultat de la transaction de telle sorte qu’elle puisse obtenir et retourner le résultat sans retraiter la transaction.
Une application peut suspendre toutes les transactions associées à un handle de conversation spécifique en spécifiant le handle et l’indicateur EC_DISABLE dans un appel à DdeEnableCallback. En spécifiant une handle de NULL, une application peut suspendre toutes les transactions pour toutes les conversations.
Lorsqu’une conversation a été suspendue, le DDEML enregistre les transactions pour la conversation dans une file d’attente de transactions. Lorsque l’application réenable la conversation, la DDEML supprime les transactions enregistrées de la file d’attente et transmet chaque transaction à la fonction de rappel appropriée. La capacité de la file d’attente des transactions est importante, mais une application doit réactiver une conversation suspendue dès que possible pour éviter de perdre des transactions.
Une application peut reprendre le traitement habituel des transactions en spécifiant l’indicateur EC_ENABLEALL dans DdeEnableCallback. Pour une reprise plus contrôlée du traitement des transactions, l’application peut spécifier l’indicateur de EC_ENABLEONE. Cet indicateur supprime une transaction de la file d’attente des transactions et la transmet à la fonction de rappel appropriée ; une fois cette transaction traitée, toutes les conversations sont à nouveau désactivées.
Si l’indicateur EC_ENABLEONE et un handle de conversation sont spécifiés dans l’appel à DdeEnableCallback, seule cette conversation est bloquée une fois la transaction traitée. Si un null de handle de conversation est spécifié, toutes les conversations sont bloquées une fois qu’une transaction a été traitée dans n’importe quelle conversation.
Transaction Classes
Le DDEML comporte quatre classes de transactions. Chaque classe est identifiée par une constante commençant par le préfixe XCLASS_. Les classes sont définies dans le fichier d’en-tête DDEML. La valeur de classe est combinée à la valeur de type transaction et est passée à la fonction de rappel DDE de l’application de réception.
La classe d’une transaction détermine la valeur de retour qu’une fonction de rappel est censée retourner si elle traite la transaction. Les valeurs de retour et les types de transactions suivants sont associés à chacune des quatre classes de transaction.
Classe | Valeur de retour | Transaction |
---|---|---|
XCLASS_BOOL | TRUE ou FALSE |
XTYP_ADVSTART XTYP_CONNECT |
XCLASS_DATA | Un handle de données, le code de retour CBR_BLOCK ou NULL |
XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT |
XCLASS_FLAGS | Indicateur de transaction : DDE_FACK, DDE_FBUSY ou DDE_FNOTPROCESSED |
XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE |
XCLASS_NOTIFICATION | Aucun |
XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_REGISTER XTYP_UNREGISTER XTYP_XACT_COMPLETE |
Types de transactions
Chaque type de transaction DDE a un récepteur et une activité associée qui provoque la génération de chaque type par DDEML.
Type de transaction | Récepteur | Cause |
---|---|---|
XTYP_ADVDATA | Client | Un serveur a répondu à une transaction XTYP_ADVREQ en retournant un handle de données. |
XTYP_ADVREQ | Serveur | Un serveur appelé fonction DdePostAdvise, indiquant que la valeur d’un élément de données dans une boucle de conseil a changé. |
XTYP_ADVSTART | Serveur | Un client a spécifié le type de transaction XTYP_ADVSTART dans un appel à la fonctionDdeClientTransaction. |
XTYP_ADVSTOP | Serveur | Un client a spécifié le type de transaction XTYP_ADVSTOP dans un appel à DdeClientTransaction. |
XTYP_CONNECT | Serveur | Un client a appelé la fonction DdeConnect et spécifié un nom de service et un nom de rubrique pris en charge par le serveur. |
XTYP_CONNECT_CONFIRM | Serveur | Le serveur a retourné TRUE en réponse à une transaction XTYP_CONNECT ou XTYP_WILDCONNECT. |
XTYP_DISCONNECT | Client/serveur | Un partenaire dans une conversation a appelé la fonction DdeDisconnect, ce qui entraîne la réception de cette transaction par les deux partenaires. |
XTYP_ERROR | Client/serveur | Une erreur critique s’est produite. Le DDEML peut ne pas avoir suffisamment de ressources pour continuer. |
XTYP_EXECUTE | Serveur | Un client a spécifié le type de transaction XTYP_EXECUTE dans un appel à DdeClientTransaction. |
XTYP_MONITOR | Application de supervision DDE | Un événement DDE s’est produit dans le système. Pour plus d’informations sur les applications de surveillance DDE, consultez Monitoring Applications. |
XTYP_POKE | Serveur | Un client a spécifié le type de transaction XTYP_POKE dans un appel à DdeClientTransaction. |
XTYP_REGISTER | Client/serveur | Une application serveur a utilisé la fonction DdeNameService pour inscrire un nom de service. |
XTYP_REQUEST | Serveur | Un client a spécifié le type de transaction XTYP_REQUEST dans un appel à DdeClientTransaction. |
XTYP_UNREGISTER | Client/serveur | Une application serveur utilisée DdeNameService pour annuler l’inscription d’un nom de service. |
XTYP_WILDCONNECT | Serveur | Un client appelé fonction DdeConnect ou DdeConnectList, en spécifiant NULL pour le nom du service, le nom de la rubrique ou les deux. |
XTYP_XACT_COMPLETE | Client | Une transaction asynchrone, envoyée lorsque le client a spécifié l’indicateur TIMEOUT_ASYNC dans un appel à DdeClientTransaction, a conclu. |