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 :

Envoi de message entre 2 applications


Sujet :

Windows

  1. #1
    Futur Membre du Club
    Inscrit en
    Juin 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Envoi de message entre 2 applications
    Salut,
    Je ne m'y connais pas trop en programmation windows. je dois interagir avec un logiciel commercial. la boite en question m'a fait la proposition suivante (moyennant bcp d'argent!!) : je dois leurs envoyer un message du nom de VM_DEMARRER qui permettra de declencher un fonctionnalité du logiciel (c'est exactement ce que je veux faire).

    Ma question est : comment envoyer un message vers une autre application! j'ai deja navigé un peu sur le web et sur le forum (je n'ai pas reussi a faire une recherche sur un forum en particulier), je suppose que je dois utiliser la fct SendMessage de l'api win... comment fonctionne t elle (succintement)?

    EST ce possible de creer des messages comme VM_DEMARRER??? (ils me decrivent aussi un fichier : param.ini :
    [Pilotage Demarrage Acquisition]
    Pilotage=0
    Message Windows=VM_DEMARRER


    enfin , pour cette boite qui fournit le logiciel, cela ne doit pas etre compliqué de rajouter une gestion d'un message supplementaire dans la file des messages??
    merci de votre aide.

  2. #2
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 938
    Points : 59 416
    Points
    59 416
    Billets dans le blog
    2
    Par défaut
    Bonjour !

    Euh... Ben il existe un protocole tout fait pour ça : le DDE. C'est facile à programmer et ça a l'avantage d'être un standard Microsoft.
    Enormément de logiciels commerciaux proposent cette fonctionnalité.

    Personnellement, je trouve la solution que l'on te propose un peu... bizarre ?!?
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
    La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Personnellement, je trouve la solution que l'on te propose un peu... bizarre ?!?
    Ouais, c'est un peu bricolage (alors COM ou DDE sont fait pour cela)... mais ça doit marcher :-)

    1. L'identifiant d'un message Windows est un nombre (souvent représenté sous forme d'une constante : WM_QUERYENDSESSION, WM_***,...). Dans ton cas, j'espère qu'on t'a donné la valeur de ta constante WM_DEMARRER (qui vaut sans doute WM_USER + UnNombre), ou au moins qu'elle est définie dans un .h / .pas / etc.

    2. Oui, ensuite tu utilises PostMessage ou SendMessage pour envoyer un message de "code" WM_DEMARRER. Le "problème" c'est que ces deux fonctions attendent un identifieur de fenêtre (handle) destinatrice, que tu dois récupérer par un moyen ou un autre (généralement en utilisant FindWindow ou FindWindowClass).

    enfin , pour cette boite qui fournit le logiciel, cela ne doit pas etre compliqué de rajouter une gestion d'un message supplementaire dans la file des messages??
    Je ne comprends pas... Si on te demande de faire celà, c'est que à priori le traitement de ce message est déjà implémenté, non ?
    "It's more fun to compute !"

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 296
    Points : 1 803
    Points
    1 803
    Par défaut
    Perso je prefere la solution des mailbox sous windows : simple a mettre en place, non bloquante et "ouverte" principe :
    un programme creer une mail box puis attend d'eventuelle message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	// creation du serveur de boite au lettre
       	hms = CreateMailslot(NOM_BOITE_AU_LETTRE,
        			0,	// Any length of message
        			1000,	// Read timeout 1 second
        			NULL	// Security disabled
        	     );
    boucle d'attente non bloquante sur declanchement de timer:
    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
      	err = GetMailslotInfo( hms, NULL, &nxtMsgSize, &nMsgs, NULL );
       	if( err == FALSE )
        	ErrMsg( "Problem getting mailslot information", FALSE );
    
    	while( nxtMsgSize != MAILSLOT_NO_MESSAGE )
        {
        	err = ReadFile( hms, msgBuf, nxtMsgSize, &nBytes, NULL );
       		if( err == FALSE )
       			ErrMsg( "Problem reading mailslot", FALSE );
       		msgBuf[nBytes] = '\0';	// Just in case it's unterminated!
    		// traitement message recu
    	    err = GetMailslotInfo( hms, NULL, &nxtMsgSize, &nMsgs, NULL );
        	if( err == FALSE )
       	   		ErrMsg( "Problem getting mailslot information", FALSE );
    	}
    l'avantage est que le nom de cette boite est de type string donc facilement gerable dans un fichier type "ini", le format du message en string aussi permet ce que l'on veut, le traitement des messages est garantie sequentiel
    le programme "client " utilise les fonctions CreateFile, WriteFile .....

    Ceci evite d'avoir a "courir" apres le handle de l'application a contacter

    Sa fonctionne a travers un reseau "Microsoft"
    enfin juste mon avis
    Marc
    Slackware for ever ......
    BASH - KSH ( http://marcg.developpez.com/ksh/ )

  5. #5
    Futur Membre du Club
    Inscrit en
    Juin 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    >Je ne comprends pas... Si on te demande de faire celà, c'est que à priori >le traitement de ce message est déjà implémenté, non ?

    Ils n'ont pas encore implementé ce message, mais il vont le faire si je leur donne ... 9000€!!

    donc je voulais savoir si c'etait du boulot pour eux d'implementer le traitement d'un message (traitement qui existe deja) je m'explique:
    sur leur application , on fait des reglages, et une fois qu'on a reglé ce que l'on veux, on clic sur start: et c'est la que j'intervient! au lieux que ceux soit un utilisateur qui clic sur start, c'est moi qui envoie le message VM_DEMARRER!

    sinon je pense que je vais utiliser les methodes PostMessage et FindWindowClass.(ces methodes font t elle parties de COM / DDE ou bien y a t il encore d'autre methodes dans COM/DDE???

    En revanche, pour le mailbox je pense pas que cela convient, car ce n'est pas moi qui fait la boucle de message.

    Merci de votre aide!!!

  6. #6
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Ils n'ont pas encore implementé ce message, mais il vont le faire si je leur donne ... 9000€!!
    Si j'utilises Delphi, je n'ai qu'à rajouter une procédure avec devant l'identifiant message suivi du message à intercepter, et je mets mon code dedans. Ca me prends environ 5min, à 40€ de l'heure, je te fais payer ça 1/4 d'heure soit 10 € Soit on te prends pour un pigeon, soit des données manquent (contraintes externes, contraintes de langage, de personnes, etc.) pour que seul la modification du code suffise à justifier la somme qu'on te demande.

    sinon je pense que je vais utiliser les methodes PostMessage et FindWindowClass.(ces methodes font t elle parties de COM / DDE ou bien y a t il encore d'autre methodes dans COM/DDE???
    Ces méthodes font partie des API Windows.
    Utiliser COM ou DDE nécessite que l'application serveur soit conçue pour être pilotée, ce qui semble ne pas être le cas ici : à oublier donc.
    "It's more fun to compute !"

  7. #7
    Membre du Club

    Homme Profil pro
    Inscrit en
    Juin 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 43
    Points : 69
    Points
    69
    Par défaut
    Pour ceux que ça intéresse, voici un bout de code Windev qui permet de la faire simplement. Il facilement possible de transformer ce code en un autre langage car c'est l'utilisation de l'API Windows :

    Code de la classe :
    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
    PartageMem est une classe
    PRIVÉE
    	handle_FicMap 	est un entier
    	pt_FicMap 		est un entier
    	i_Taille		est un entier
    FIN
    
    //-o0o------------------------------------------o0o-
    //-o0o- Constructeur de classe		       -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Constructeur()
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Destrcuteur de classe		       -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Destructeur()
    :Close()
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Création zone mémoire partagée	       -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Creation(E_cNomZone, E_iLong = 65000)
    
    Handle_Fic 		est un entier
    i_Securite		est un entier
    i_Permission	est un entier
    i_TailleMax		est un entier
    i_TailleMin		est un entier
    c_Nom			est une chaîne ASCIIZ sur 128 = E_cNomZone
    
    :i_Taille 		= E_iLong
    Handle_Fic		= 0xffffffff
    i_Securite		= Null
    i_Permission	= 4
    i_TailleMax		= 0
    i_TailleMin		= :i_Taille
    
    :handle_FicMap	= API("KERNEL32", "CreateFileMappingA", handle_Fic, i_Securite, i_Permission, i_TailleMax, i_TailleMin, &c_Nom)
    SI :handle_FicMap ALORS
    	i_Permission	= 2
    	i_TailleMax		= 0
    	i_TailleMin		= 0
    	:pt_FicMap		= API("KERNEL32", "MapViewOfFile", :handle_FicMap, i_Permission, i_TailleMax, i_TailleMin, i_TailleMin)
    	SI PAS :pt_FicMap ALORS
    		API("KERNEL32", "CloseHandle", :handle_FicMap)
    		RENVOYER Faux
    	FIN	
    SINON
    	RENVOYER Faux
    FIN
    RENVOYER Vrai
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Fermeture de la zone mémoire partagée  -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Close()
    
    SI :handle_FicMap 	ALORS API("KERNEL32","UnmapViewOfFile", :pt_FicMap)
    SI :pt_FicMap		ALORS API("KERNEL32","CloseHandle", 	:handle_FicMap)
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Ouverture de la zone mémoire partagée  -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Ouvre(E_cNomZone, E_iLong = 65000)
    
    Handle_Fic 		est un entier
    i_Securite		est un entier
    i_Permission	est un entier
    i_TailleMax		est un entier
    i_TailleMin		est un entier
    c_Nom			est une chaîne ASCIIZ sur 128 = E_cNomZone
    
    :i_Taille 		= E_iLong
    i_Permission	= 2
    :handle_FicMap	= API("KERNEL32", "OpenFileMappingA", i_Permission, Faux, c_Nom)
    SI :handle_FicMap ALORS
    	i_Permission	= 2
    	i_TailleMax		= 0
    	i_TailleMin		= 0
    	:pt_FicMap		= API("KERNEL32", "MapViewOfFile", :handle_FicMap, i_Permission, i_TailleMax, i_TailleMin, i_TailleMin)
    	SI PAS :pt_FicMap ALORS
    		API("KERNEL32", "CloseHandle", :handle_FicMap)
    		RENVOYER Faux
    	FIN	
    SINON
    	RENVOYER Faux
    FIN
    RENVOYER Vrai
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Obtenir le pointeur sur la zone mémoire-o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE GetPointeur()
    
    RENVOYER :pt_FicMap
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Modifier le contenu de la zone mémoire -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Set_Contenu(E_cContenu)
    
    c_Contenu est une chaîne ASCIIZ sur 65000
    c_Contenu = E_cContenu
    Transfert(:GetPointeur(), &c_Contenu, :i_Taille)
    //-o0o------------------------------------------o0o-
    
    //-o0o------------------------------------------o0o-
    //-o0o- Récuparétion du contenu de la zone mem -o0o-
    //-o0o------------------------------------------o0o-
    PROCEDURE Get_Contenu()
    
    c_Contenu est une chaîne ASCIIZ sur 65000
    Transfert(&c_Contenu, :GetPointeur(), :i_Taille)
    RENVOYER c_Contenu
    //-o0o------------------------------------------o0o-
    Code coté serveur :
    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
    //-o0o----------------------------o0o-
    //-o0o- Déclaration des globales -o0o-
    //-o0o----------------------------o0o-
    GLOBAL
    	ZoneMem est un objet PartageMem
    	IdEvenement est un entier = Evénement("EVEN","SERVEUR",0x0400)
    
    //-o0o---------------------------------------o0o-
    //-o0o- Code initialisation fenêtre serveur -o0o-
    //-o0o---------------------------------------o0o-
    SI PAS ZoneMem:Creation("Partage") ALORS
    	Erreur("Erreur !","Impossible de créer la zone de mémoire partagée.")
    SINON
    	ZoneMem:Set_Contenu(Handle(MoiMême))
    	SI PAS DDELance("CLIENT.EXE") ALORS
    		Erreur("Erreur !","Impossible de lancer le client.")
    	FIN
    FIN
    
    //-o0o-----------------------------------o0o-
    //-o0o- fermeture de la fenêtre SERVEUR -o0o-
    //-o0o-----------------------------------o0o-
    ZoneMem:Close()
    SI IdEvenement ALORS FinEvénement(IdEvenement)
    
    //-o0o---------------------------------------------------o0o-
    //-o0o- Procédure de récupération de l'évènement 0x0400 -o0o-
    //-o0o---------------------------------------------------o0o-
    c_Commande est une chaîne = ZoneMem:Get_Contenu()
    
    SELON _EVE.wParam
    	CAS 0
    		Info("Le contenu reçu est : "+c_Commande)
    		
    	AUTRE CAS
    		ZoneMem:Set_Contenu("???")
    FIN
    Code coté client :
    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
    //-o0o----------------------------o0o-
    //-o0o- Déclaration des globales -o0o-
    //-o0o----------------------------o0o-
    GLOBAL
    	ZoneMem est un objet PartageMem
    	Handle_ZoneMem est un entier
    
    //-o0o---------------------------------o0o-
    //-o0o- Code initialisation du CLIENT -o0o-
    //-o0o---------------------------------o0o-
    SI PAS ZoneMem:Ouvre("Partage") ALORS
    	Erreur("Erreur !","Impossible d'ouvrir la zone mémoire")
    	Ferme()
    FIN
    
    Handle_ZoneMem = ZoneMem:Get_Contenu()
    
    SI PAS SysHandleValide(Handle_ZoneMem) ALORS
    	Erreur("Erreur !","Handle du serveur invalide.")
    	Ferme()
    FIN
    
    ZoneMem:Set_Contenu("INITIALISATION")
    SendMessage(Handle_ZoneMem,0x0400,0,0)
    Info("Le serveur nous a répondu : "+ZoneMem:Get_Contenu())
    
    //-o0o----------------------------------o0o-
    //-o0o- fermeture de la fenêtre CLIENT -o0o-
    //-o0o----------------------------------o0o-
    ZoneMem:Close()

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Ton probleme me fait un peut penser a ce que j'ai rencontré quand j'ai voulu commander winamp a distance...

    Winamp implémente déjà (evidement) le comportement qui intervient lorsque l'on clique sur son bouton "play". Dans la pratique, quand tu cliques sur play, windows envoie a winamp un message correspondant a cet evenement.

    Le principe pour simuler un clic sur play depuis une autre application est similaire : il te suffit de "recuperer winamp" (un handle, cd FindWindow), et de lui envoyer le bon message.

    Il te faut donc connaitre
    1- Le moyen de recuperer un handle vers la fenetre de ton appli (winamp ici)
    2- Le code du message.

    Pour winamp, ces codes sont definis dans un .h quelque part sur leur site. Pour ton appli, c'est aux gars qui l'ont codee de te les fournir.

    Au final, ces quelques lignes simulent un clic sur le bouton "play" d'un winamp (winamp doit deja etre lance et avoir qqch dans sa playlist, evidement) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Constantes, fournies par l'equipe de winamp
    // (cf frontend.h)
    #define WM_WA_IPC        WM_USER
    #define IPC_STARTPLAY    102
    #define WA_CAPTION       "Winamp v1.x"
    
    ...
    
    // Et zou, on y va porkas, on verifie pas les code retour :) 
    HWND hwnd_winamp = FindWindow(WA_CAPTION,NULL);
    SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
    Je pense que le principe est tres tres tres similaire pour ce que tu veux faire Et je pense aussi qu'ils te prennent pour un gogo pour oser te reclamer 9ke alors qu'ils ont juste 3 pauvres constantes a te donner...

    En esperant t'avoir aidé

    Bonne chance !!

  9. #9
    Futur Membre du Club
    Inscrit en
    Juin 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Merci!

    effectivement, c'est exactement cela que je veux faire ,comme simuler un clic sur "play" de winamp!

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par floweez
    Merci!

    effectivement, c'est exactement cela que je veux faire ,comme simuler un clic sur "play" de winamp!
    8)

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/06/2015, 10h53
  2. Envoi de données entre deux applications
    Par DotNET74 dans le forum Windows Phone
    Réponses: 3
    Dernier message: 13/01/2014, 22h31
  3. Envoie de messages dans une application
    Par rtg57 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 16/01/2011, 18h40
  4. envoi de message entre winform
    Par lao.patrick dans le forum C#
    Réponses: 2
    Dernier message: 10/05/2010, 10h06
  5. Envoi de messages entre applications
    Par splash68 dans le forum C++
    Réponses: 2
    Dernier message: 24/07/2009, 12h15

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