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

C++ Discussion :

Live Messenger : Accéder au message personnel


Sujet :

C++

  1. #1
    Membre actif

    Inscrit en
    Mars 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 241
    Points : 239
    Points
    239
    Par défaut Live Messenger : Accéder au message personnel
    Salut,

    Je tente d'écrire un programme en C++ plus ou moins standard pour modifier le message personnel de Live Messenger. En fait, c'est pour utiliser la fonction "Afficher ce que j'écoute".

    J'ai trouvé pas mal de trucs intéressant sur le net mais je n'y arrive pas.

    Donc en me basant sur le code C# fournit par frechy (qui fonctionne), d'ailleurs je pense que c'est le même sur CodeProject, j'ai réussi à faire ça :

    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
    #include <iostream>
    #include <string>
     
    #include <windows.h>
     
     
    #define WM_COPYDATA 74
     
     
    using namespace std;
     
     
    void sendMSNMessage(bool enable, string category, string message)
    {
    	COPYDATASTRUCT data;
    	HWND handle = NULL;
    	string buffer = "\\0" + category + "\\0" + (enable ? "1" : "0") + "\\0{0}\\0" + message + "\\0\\0\\0\\0\0";
     
    	data.dwData = 0x0547;
    	data.lpData = &buffer;
    	data.cbData = (buffer.length() * 2) + 2;
     
    	cout << "dwData: " << data.dwData << endl;
    	cout << "lpData: " << data.lpData << " : " << buffer.data() << " : " << (void*) buffer.data() << endl;
    	cout << "cbData: " << data.cbData << " : " << buffer.length() << endl;
     
    	handle = FindWindow("MsnMsgrUIManager", NULL);
    	cout << "handle: " << handle << endl;
    	cout << "&data : " << &data << " : " << (LPARAM) &data << endl;
    	while (handle)
    	{
    		SendMessage(handle, WM_COPYDATA, 0, (LPARAM) &data);
    	}
    }
     
    int main(int argc, string argv)
    {
    	sendMSNMessage(true, "Music", "test");
    	return 0;
    }
    Je me suis aussi un peu aider de ce code pour les fonctions FindWindow ou FindWindowEx et SendMessage, mais ne voulant pas utiliser les CString, j'ai aussi pris quelques idées à ce code.

    Le résultat est au dessus. Ca compile, il y a des valeurs qui s'affichent grâce aux "cout" et qui semblent correcte, mais rien dans la fenêtre MSN...

    J'ai essayé plusieurs méthodes mais aucun résultat...

    Pouvez-vous m'éclairer sur ce que je fais mal ?

  2. #2
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Salut,

    Je ne connais pas l'interface de MSN, mais le passage suivant me paraît un peu bizarre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (handle)
       {
          SendMessage(handle, WM_COPYDATA, 0, (LPARAM) &data);
       }
    N'est-ce pas un if que tu veux faire plutôt? Parce que là, tu envoies le message à MSN en boucle, et ça m'étonnerait pas qu'il y est un overflow...

    EDIT: après vérification du code C#, c'est bien un if qui est fait, et non un while...
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  3. #3
    Membre actif

    Inscrit en
    Mars 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 241
    Points : 239
    Points
    239
    Par défaut
    Oui j'avais mis le 'while' pour être sûre qu'il reçoive le message mais le 'if' n'y change pas grand chose. Sinon, il ne s'agit pas d'une API MSN mais plutôt de fonctions d'une fonction de l'API COM de windows il me semble.

    En fait, il s'agit de transmettre un message entre les applications.

    PS : Je compile avec GCC (Cygwin), cela aurait-il un impact ? J'aurais aimé essayer avec Visual Studio 2003 mais j'obtiens l'erreur : Erreur lors de la génération dynamique 'cl.exe' à la compilation.

  4. #4
    Membre éprouvé
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par Spack Voir le message
    PS : Je compile avec GCC (Cygwin), cela aurait-il un impact ? J'aurais aimé essayer avec Visual Studio 2003 mais j'obtiens l'erreur : Erreur lors de la génération dynamique 'cl.exe' à la compilation.
    Aucune idée, mais je ne vois rien dans ton code qui soit spécifique à ton IDE.
    Du coup je ne vois qu'un message mal formaté...
    "L'ordinateur obéit à vos ordres, pas à vos intentions." [Anonyme]

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Je ne connais absolument pas la structure COPYDATA, et je ne sais donc pas ce qui est représenté par le champs data.lpData dans ton code...

    Cependant, je serais quand même fort surpris de constater qu'il travaille avec un pointeur sur une string, et ceci, d'autant plus que tu utilise la classe std::string qui peut poser des problèmes de compatibilité lorsque l'on accède à une dll compilée avec un compilateur particulier sans utiliser le dit compilateur pour compiler la fonction qui tente d'y accéder.

    Ne serait-ce pas, plutot, un pointeur sur caractère, genre char* ou const char*

    Ce serait d'ailleurs bien plus cohérent avec le champs data.cbData qui, de toutes évidence, représente la longueur de la chaine.

    Si tu confirme mon intuition en ce qui concerne le type du champs lpData, la solution est toute simple:
    Modifier le
    qui m'a mis la puce à l'oreille en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data.lpData = buffer.cstr();
    qui aura pour résultat d'envoyer d'initialiser lpData avec... un const char*
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre actif

    Inscrit en
    Mars 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 241
    Points : 239
    Points
    239
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Je ne connais absolument pas la structure COPYDATA, et je ne sais donc pas ce qui est représenté par le champs data.lpData dans ton code...
    Voici la définition de la structure COPYDATASTRUCT telle qu'elle apparait dans le fichier winuser.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct tagCOPYDATASTRUCT {
    	DWORD dwData;
    	DWORD cbData;
    	PVOID lpData;
    } COPYDATASTRUCT,*PCOPYDATASTRUCT;
    Apparemment il s'agit bien d'un problème de type... J'ai repris exactement le même code qu'ici et ça marche parfaitement... Il semblerait que je ne peux pas utiliser les types "standard" (ou difficilement)... De plus, ça ne me parait pas très C++ tout ça

    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
    #include <iostream>
     
    #include <windows.h>
    #include <stdio.h>
    #include <string.h>
     
    #define MSGSTRING L"\\0%s\\0%d\\0%s\\0%s\\0\\0\\0\\0"
     
    #define WM_COPYDATA 74
     
     
    using namespace std;
     
     
    void sendMSNMessage()
    {
    	COPYDATASTRUCT data;
    	HWND handle = NULL;
    	WCHAR buffer[500];
     
    	wsprintfW(buffer, MSGSTRING, L"Music", 1, L"{0}", L"Test");
     
    	data.dwData = 0x0547;
    	data.lpData = &buffer;
    	data.cbData = (lstrlenW(buffer) * 2) + 2;
     
    	while (handle = FindWindowEx(NULL, handle, "MsnMsgrUIManager", NULL))
    		SendMessage(handle, WM_COPYDATA, 0, (LPARAM) &data);
    }
     
    int main(int argc, string argv)
    {
    	sendMSNMessage();
    	return 0;
    }

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    PVOID est un alias de type sur void*, comme son nom l'indique

    Autrement dit, dans le cas qui nous occupe, ce serait transformé en un char*, voire, si l'on se base sur le code d'exemple fourni, en un wchar_t* (pointeur sur caractère(s) unicode(s) )

    l'idéal est donc peut etre de passer par une chaine de caractère unicode (wstring), voire de la construire avec les flux de conversion adaptés (wstringstream), en veillant à en appeler la méthode c_str() qui convertira le tout en pointeur sur wchar_t

    Au final, ton code pourrait très bien ressembler à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void sendMessage(const std::wstring& title, const std::wstring& artist,
                     const std::wstring& album, const std::wstring& id)
    {
        std::wstringstream buffer;
        buffer<<L"\\0"<<title
              <<L"\\0"<<artist
              <<L"\\0"<<album
              <<L"\\0"<<id
              <<L"\\0";
        /* je pase les parties qui ne posent pas problème ;) */
        data.lpData = buffer.str().c_str();
        data.cbData = buffer.str().size();
       /* devrait suivre l'appel de la fonction finale ;) */
    }
    Les deux lignes qui pourraient te surprendre sont
    buffer.str().c_str() et buffer.str().size()...

    L'idée c'est qu'il faut demander à convertir ton... flux de conversion en une chaine de caractère, ce qui est le but de l'appel de la fonction str().

    Cette fonction renvoie une chaine de caractères constante, au départ de laquelle nous souhaitons obtenir un pointeur constant sur caractères dans la première et la taille pour la seconde, ce qui se fait en appelant respectivement les méthodes c_str() et size() sur une chaine de caractères existante

    PS (le code n'a pas été testé pour plusieurs raisons, donc il faudra peut etre l'adapter un tout petit peu (principalement au point de vue de l'introduction dans buffer )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre actif

    Inscrit en
    Mars 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 241
    Points : 239
    Points
    239
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Autrement dit, dans le cas qui nous occupe, ce serait transformé en un char*, voire, si l'on se base sur le code d'exemple fourni, en un wchar_t* (pointeur sur caractère(s) unicode(s) )

    l'idéal est donc peut etre de passer par une chaine de caractère unicode (wstring), voire de la construire avec les flux de conversion adaptés (wstringstream), en veillant à en appeler la méthode c_str() qui convertira le tout en pointeur sur wchar_t
    Oui j'avais vu ça en cherchant un peu sur le net et j'avoue que j'avais un peu la flème de m'y coller ...

    Cela dit les GCC de Cygwin ou MinGW ne supportent pas tout ce qui est en rapport avec le type wchar_t donc j'ai dû résoudre mon soucis avec Visual Studio (désinstallation, un bon nettoyage de la base de registre et des dossiers) et tout est nickel.

    Citation Envoyé par koala01 Voir le message
    PS (le code n'a pas été testé pour plusieurs raisons, donc il faudra peut etre l'adapter un tout petit peu (principalement au point de vue de l'introduction dans buffer )
    Je m'en occupe

    Après adaptation tout est parfait :
    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
    void sendMessage(const bool enable,const wstring category,
                     const wstring title, const wstring artist)
    {
    	wstringstream buffer;
     
    	buffer << L"\\0" << category
                  << L"\\0" << enable 
                  << L"\\0" << DEFAULT_FORMAT
                  << L"\\0" << title
                  << L"\\0" << artist
                  << L"\\0"
                  << L"\\0"
                  << L"\\0";
     
    	this->data.lpData = (void*) buffer.str().c_str();
    	this->data.cbData = (buffer.str().size() * 2) + 2;
    }
    Merci de ton aide !

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

Discussions similaires

  1. Probleme d'ajout de contact sur Windows Live Messenger
    Par maadadi dans le forum Messagerie instantanée
    Réponses: 6
    Dernier message: 20/09/2009, 10h08
  2. Windows Live Messenger : Comment changer le message perso ?
    Par MaTHieU_ dans le forum API, COM et SDKs
    Réponses: 0
    Dernier message: 13/11/2007, 01h18
  3. [Windows Live Messenger] Plantage du routeur
    Par Machjaghjolu dans le forum Windows XP
    Réponses: 1
    Dernier message: 06/07/2006, 11h10
  4. [Windows Live Messenger] Impossible de lancer l'installation.
    Par damien99 dans le forum Messagerie instantanée
    Réponses: 7
    Dernier message: 29/06/2006, 15h32
  5. [Windows Live Messenger]question sur les messages hors connexion
    Par jmclej dans le forum Messagerie instantanée
    Réponses: 9
    Dernier message: 21/06/2006, 14h34

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