IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Utiliser DDE pour lire des valeurs


Sujet :

Windows

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 37
    Points : 17
    Points
    17
    Par défaut Utiliser DDE pour lire des valeurs
    Bonjour à tous.
    Je voudrais communiquer avec une application en utilisant DDE. J'ai essayé avec Excel en entrant une formule "=app|TOPIC!nom" et ça marche très bien.
    J'ai essayé de suivre ce tuto en C sous Visual C++ express mais je n'ai pas réussi.

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    char* szApplication = "app"; 
        char* szTopic = "TOPIC"; 
        ATOM atomApplication = *szApplication == 0 ? 
    		NULL     : GlobalAddAtom(szApplication); 
    	ATOM atomTopic = *szTopic == 0 ? 
    		NULL     : GlobalAddAtom(szTopic); 
    
    	printf("envoi du message...\n");
    	SendMessage(HWND_BROADCAST,
    		WM_DDE_INITIATE,
    		(WPARAM) NULL,
    		MAKELONG(atomApplication,  atomTopic));
    
    	printf("message envoye\n");
    
        if (atomApplication != NULL) 
            GlobalDeleteAtom(atomApplication); 
        if (atomTopic != NULL) 
            GlobalDeleteAtom(atomTopic);
    
    
    	printf("attente d'un message\n");
    	MSG message;
    	GetMessage(&message,
    		NULL,
    		0,
    		0);
            printf("message recu\n");
    L'envoi du message semble bien se passer mais je ne reçois aucune réponse.
    Si quelqu'un voit une erreur dans mon programme ou a un exemple (simple) d'utilisation de DDE en C ce serait sympa.

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 397
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 397
    Points : 20 509
    Points
    20 509
    Par défaut
    Citation Envoyé par bobo21 Voir le message
    L'envoi du message semble bien se passer mais je ne reçois aucune réponse.
    Si quelqu'un voit une erreur dans mon programme ou a un exemple (simple) d'utilisation de DDE en C ce serait sympa.

    Merci
    C'est normal tu ne boucles pas en attendant le message !
    Tu appelles GetMessage mais le programme il passe à autre chose lui !
    Si le lien DDE sur Excel prend quelques ms et plus tu ne recevras jamais rien
    Donc la solution basique c'est de faire un timer et de boucler sur GetMessage avec une valeur de timeout
    Quelque chose de plus sophistiqué serait avec un thread

    Regarder l'aide dans le MSDN sur GetMessage

    GetMessage Function


    The GetMessage function retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.

    Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning.


    An application typically uses the return value to determine whether to end the main message loop and exit the program.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    Tu appelles GetMessage mais le programme il passe à autre chose lui !
    Merci pour ta réponse mais GetMessage est bloquant :

    Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning.
    En effet, j'ai mis un printf après le GetMessage et le programme reste bloqué sur GetMessage, je ne reçois donc aucun message.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    Personne n'a d'idée ?
    Et avec la bibliothèque DDEML ce serait pas plus simple ?
    Si quelqu'un a du code je suis preneur.
    Merci.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    Ça y est j'ai trouvé.
    Je donne la solution pour ceux qui tomberaient par hasard sur ce topic :

    J'ai utilisé DDEML (inclus dans <windows.h>).
    Je me suis inspiré de cette aide.

    Mon code est fait pour JNI et la classe toto.DDE
    Pour compiler avec Visual C++ Express je n'utilise pas les en-têtes précompliées (sinon il y a un problème avec JNI).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    #include <windows.h>
    #include <stdio.h>
    #include "toto_DDE.h"
    
    HCONV hDdeConv = 0;
    DWORD idInst = 0;
    
    
    
    // Exécute une commande DDE et place le résultat dans pData
    bool DoDdeCommand( const char * pCmd,    /* -> Command string           */
                        const char * pParms, /* -> Command parameters       */
                        char * pData)  /* -> Buffer for returned data */
     {
       HSZ hDdeString;
       HDDEDATA hDdeResult;
       DWORD data_len;
       char * pString;
    
       /* Add parameters to command line. */
       if ( pParms == NULL ) {
    	   pParms = "";
       }
       int length = strlen( pCmd ) + strlen( pParms ) + 2 ;
       pString = new char[length];
       strcpy_s(pString, length, pCmd );
       strcat_s( pString, length, " " );
       strcat_s( pString, length, pParms );
    
       /* Perform OnDemand DDE command. */
       hDdeString = DdeCreateStringHandle( idInst, pCmd, 0 );
       UINT type = XTYP_REQUEST;
       hDdeResult = DdeClientTransaction( NULL,
                                          0,
                                          hDdeConv,
                                          hDdeString,
                                          CF_TEXT,
                                          type,
                                          10000L,
                                          NULL );
       DdeFreeStringHandle( idInst, hDdeString );
       delete pString;
    
       /* Process command result. */
       if ( hDdeResult == NULL )
       {
         /* This should never happen. */
         printf( "DDE Timeout.\n" );
         return false;
       }
       else
         {
         pString = (char*)DdeAccessData( hDdeResult, &data_len );
         DdeUnaccessData( hDdeResult );
    
    	 if (pString == NULL) {
    		pData[0] = '\0';
    		return false;
    	 }
    	 else {
    		strcpy_s(pData, 100, pString);
    		return true;
    	 }
       }
     }
    
    
    
    // Sert à rien pour l'instant
    HDDEDATA CALLBACK DdeCallback(
    UINT uType,       // transaction type 
    UINT uFmt,        // clipboard data format 
    HCONV hconv,      // handle to conversation 
    HSZ hsz1,         // handle to string 
    HSZ hsz2,         // handle to string 
    HDDEDATA hdata,   // handle to global memory object 
    DWORD dwData1,    // transaction-specific data 
    DWORD dwData2    // transaction-specific data 
    )
    { 
    	printf("DdeCallback\n");
        switch (uType) 
        { 
            case XTYP_REGISTER: 
            case XTYP_UNREGISTER: 
           
                return (HDDEDATA) NULL; 
     
            case XTYP_ADVDATA: 
              
                return (HDDEDATA) DDE_FACK; 
     
            case XTYP_XACT_COMPLETE: 
                
                // 
                
                return (HDDEDATA) NULL; 
     
            case XTYP_DISCONNECT: 
                
                // 
                
                return (HDDEDATA) NULL; 
     
            default: 
                return (HDDEDATA) NULL; 
        } 
    } 
    
    
    
    /*
     * public native void Connecter(String serveur, String topic);
     * Initialise une connexion avec le serveur
     */
    JNIEXPORT void JNICALL Java_toto_DDE_Connecter
    (JNIEnv *env, jobject, jstring serveurNameUTF, jstring topicNameUTF)
    {
    	const char *serveurName = env->GetStringUTFChars(serveurNameUTF, 0);
    	const char *topicName = env->GetStringUTFChars(topicNameUTF, 0);
    	
    	DdeInitialize(&idInst,         // receives instance identifier 
    		(PFNCALLBACK) DdeCallback, // pointer to callback function 
    		CBF_FAIL_EXECUTES |        // filter XTYPE_EXECUTE 
    		CBF_SKIP_ALLNOTIFICATIONS, // filter notifications 
    		0); 
    	
    	printf("init ok : idInst = %d\n", idInst);
    
    
    
    
    	HSZ hszServName; 
    	HSZ hszSysTopic; 
    	hszServName = DdeCreateStringHandle( 
    		idInst,         // instance identifier 
    		serveurName,     // string to register 
    		CP_WINANSI);    // Windows ANSI code page 
    	 
    	hszSysTopic = DdeCreateStringHandle( 
    		idInst,         // instance identifier 
    		topicName, // System topic 
    		CP_WINANSI);    // Windows ANSI code page 
    
    	hDdeConv = DdeConnect(idInst, hszServName, hszSysTopic, NULL);
    
    	env->ReleaseStringUTFChars(serveurNameUTF, serveurName);
    	env->ReleaseStringUTFChars(topicNameUTF, topicName);
    }
    
    
    /*
     * public native String getValue(String name);
     * renvoie la valeur correspondant à l'item "name"
     */
    JNIEXPORT jstring JNICALL Java_toto_DDE_getValue
    (JNIEnv * env, jobject, jstring itemNameUTF)
    {
    	const char *itemName = env->GetStringUTFChars(itemNameUTF, 0);
    	char pData[100];
    	bool result = DoDdeCommand( itemName,    /* -> Command string           */
    						NULL, /* -> Command parameters       */
    						pData);  /* -> Buffer for returned data */
    	if (!result) {
    		pData[0] = '\0';
    	}
    	
    	env->ReleaseStringUTFChars(itemNameUTF, itemName);
    	return env->NewStringUTF(pData);
    }

  6. #6
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 397
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 397
    Points : 20 509
    Points
    20 509
    Par défaut
    Salut DDE c'est préhistorique vaut mieux utiliser COM; on peut créer un lien OLE Automation/COM sur Excel pour lire /écrire dans un fichier Excel
    Sinon je pense qu'il vaille mieux dans la boucle de messages de l'appli traiter les messages DDE.

    Quel est le type de projet ? win32 console , UI ?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 37
    Points : 17
    Points
    17
    Par défaut
    Salut.
    C'est pour mon travail, il faut que je communique avec un logiciel propriétaire (assez vieux) qui ne gère que DDE.
    Qu'est-ce que tu entends par la boucle de messages ?

    C'est pour un projet Eclipse. C'est pour ça que j'ai utilisé du JNI.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Utilisation d'OffSet pour chercher des valeurs de cellules
    Par gobgobnob dans le forum Excel
    Réponses: 0
    Dernier message: 22/04/2014, 09h22
  2. Réponses: 3
    Dernier message: 20/07/2013, 12h42
  3. Réponses: 2
    Dernier message: 12/10/2012, 08h49
  4. Réponses: 5
    Dernier message: 19/05/2011, 14h15
  5. utiliser un tableau pour stocker des valeurs alphanum
    Par tibofo dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 26/03/2010, 09h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo