Toon posts:

[VC++] FriendlyName in MSN messenger veranderen.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Omdat we wel genoeg hadden van buggy Grimbo zijn Ericston en ik een projectje begonnen met het ultieme doel om de naam van het nummer dat je in winamp speelt in je MSN naam te zetten.

Deze natuurlijk onmisbare functionaliteit implementeren leek ons eerst een klusje van enkele uurtjes. Het huidige spelende nummer uit winamp halen bleek dan ook geen enkel probleem. Tot we de uitstekende (NOT) documentatie van microsoft over de MSN API tegenkwamen. over de interface werd wel het een en ander uitgelegd, maar met Visual Basic voorbeelden :|.

Na enige inspectie bleek er wel een get_FriendlyName methode te zijn, maar geen put_FriendlyName... Toch is het mogelijk want met deze library kun je in ieder geval in visual basic je FriendlyName veranderen. Eric en ik hebben echt van alles geprobeerd, maar we zijn nu echt ten einde raad. Tijd om er eens een frisse blik over te laten gaan :)

dit hebben we tot nu toe:
code:
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
// wat includes vanaf msdn download site
#include "msgrua.h"
#include "msgruaid.h"

int main()// dit is ons entry point
{
    HRESULT     hr;
    IMessenger* pIM;
    BSTR      bName;
    char      cName[64];

    // CLSID: B69003B3-C55E-4B48-836C-BC5946FC3B28
    static const GUID CLSID_Messenger =
    { 0xB69003B3, 0xC55E, 0x4B48, { 0x83, 0x6C, 0xBC, 0x59, 0x46, 0xFC, 0x3B, 0x28 } };
    
    // IID: D50C3186-0F89-48F8-B204-3604629DEE10
    static const GUID IID_IMessenger =
    { 0xD50C3186, 0x0F89, 0x48F8, { 0xB2, 0x04, 0x36, 0x04, 0x62, 0x9D, 0xEE, 0x10 } }; 

    CoInitialize(NULL);// noodzakelijk, zie ook CoUninitialize();

    hr = CoCreateInstance ( CLSID_Messenger,      // CLSID of coclass
                    NULL,            // not used - aggregation
                    CLSCTX_INPROC_SERVER,   // type of server
                    IID_IMessenger,    // IID of interface
                    (void**) &pIM );      // Pointer to our interface pointer

    if ( SUCCEEDED ( hr ) ) {
      // alles werkt...
      if ( SUCCEEDED ( pIM->get_MyFriendlyName(&bName) ) ) { // Naam ophalen uit msn.
        wcstombs (cName,bName,64);
        MessageBox(NULL,cName,0,0);
      } else {
        MessageBox(NULL,"MSN uit?",0,0);// MSN ws uit.
      }

      // Nu hier nog iets zoals put_MyFriendlyName()...

    } else {
      // Couldn't create the COM object.  hr holds the error code.
      
      MessageBox(NULL,"Gaat iets totaal fout...",0,0);
                      // Meestal als CoInitialize()
                      // niet aangeroepen wordt.
    }

    CoUninitialize();   // ook noodzakelijk maar doet ms
                // iets fout waardoor er com references
                // open blijven we niks meer doen en
                // we lekker een memory leak maken

    return 0; // doei
}

Hier is de API die wij gebruikt hebben te downloaden (dat bevat de .h files).

Het voorbeeld hebben we gedeeltelijk uit dit topic.

Om een duistere reden, ondanks de CoUninitialize() call, blijft het programma ook nog hangen in het geheugen.


source + header files (zipped)

Verwijderd

code:
1
2
3
4
    CoUninitialize();   // ook noodzakelijk maar doet ms
                // iets fout waardoor er com references
                // open blijven we niks meer doen en
                // we lekker een memory leak maken

Je zegt het zelf al, je vergeet'n reference vrij te geven, je bent waarschijnlijk een VB user en gaat er vanuit dat waneer je 'n object niet meer gebruikt de compiler 'm zelf wel released, helaas dat gaat niet op in VC dus je moet waneer je klaar bent met je object zelf netjes pIM->Release() aanroepen.

Verder staat put_friendlyname idd niet in de door jouw gedownloade headerfiles. Er was vorige week ook een topic over msn typelibs in vc, daarin staat uitgelegd hoe je de interfaces uit msmsgs.exe kunt importeren. (ik ben momenteel ff te lui om de link voor je te zoeken dus da mag je zelf doen *D )

  • NDF82
  • Registratie: Januari 2002
  • Laatst online: 26-08 21:49

NDF82

Doomed Space Marine

implementeer zelf het protocol doe ik ook >:)
zie hier

Pentium 233MHz MMX + Diamond Monster 3D 3DFX Voodoo II


  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
Op maandag 10 juni 2002 04:35 schreef Yarvieh het volgende:

[..] dus je moet waneer je klaar bent met je object zelf netjes pIM->Release() aanroepen.

Verder staat put_friendlyname idd niet in de door jouw gedownloade headerfiles. [..] de interfaces uit msmsgs.exe kunt importeren. [..]
Assumptions are deadly, geen VB users hoor, alleen hebben we wat weinig ervaring met COM. Waarom zouden VB coders eigenlijk met VC++ bezig gaan als er zoveel VB zut te vinden is? ;)

pIM->Release(); heb ik al geprobeerd, had geen effect, dus per ongeluk weggehaald en maar weggelaten. :)
Heb het even teruggezet en onze code is nu dus geworden:
code:
1
2
3
4
5
6
// [..]
if ( SUCCEEDED ( hr ) ) {
    // [..]
    pIM->Release();
}
// [..]

To no avail, alas, het is namelijk vrij irritant om te coden als je bij elke compile weer een process moet killen om de exe te laten schrijven...

Naar aanleiding van iemand die zei dat het misschien aan threads lag die nog open zaten viel dit op:
code:
1
2
3
4
5
6
7
8
Debug:
The thread 0x78C has exited with code 0 (0x0).
; hij is klaar, maar blijft in geheugen
; na het killen van de thread komt er dit in de monitor:
The thread 0x4D8 has exited with code 1 (0x1).
The thread 0x4B0 has exited with code 1 (0x1).
The thread 0x484 has exited with code 1 (0x1).
The program 'D:\DOCUMENTS AND SETTINGS\ERIC\MIJN DOCUMENTEN\DEV\C\winamp2msn\Debug\winamp2msn.exe' has exited with code 1 (0x1).

En daarnaast blijft ie zelfs nog hangen wanneer CoCreateInstance() failed. Het lijkt dus niet geheel op openstaande references.

---

En dan het andere probleem, de put_MyFriendlyName functie...

...we hebben de IMessengerService en IMessengerUser interfaces gelocaliseerd in die andere typelibs. Deze bevatten allebei een put_FriendlyName method.
Alleen we zijn geen COM helden, en we zitten nu totaal vast met het implementeren hiervan.
msmsgs.tlh:
code:
1
2
3
4
5
6
7
// [..]
struct __declspec(uuid("218cb453-20b6-11d2-8e17-0000f803a446"))
/* dual interface */ IMsgrUser;
// [..]
struct __declspec(uuid("659ecad9-a5c0-11d2-a440-00c04f795683"))
/* dual interface */ IMsgrService;
// [..]

Maar dit failed ( en als ik de IID van IMsgrUser ook ):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// [..]
// CLSID:
static const GUID CLSID_Messenger =
{ 0xB69003B3, 0xC55E, 0x4B48, { 0x83, 0x6C, 0xBC, 0x59, 0x46, 0xFC, 0x3B, 0x28 } };

// IID:
static const GUID IID_IMessengerService =
{ 0x659ECAD9, 0xA5C0, 0x11D2, { 0xA4, 0x40, 0x00, 0xC0, 0x4F, 0x79, 0x56, 0x83 } };
// [..]
hr = CoCreateInstance ( CLSID_Messenger,      // CLSID of coclass
                    NULL,            // not used - aggregation
                    CLSCTX_INPROC_SERVER,   // type of server
                    IID_IMessengerService,     // IID of interface
                    (void**) &pIMS );     // Pointer to our interface pointer
// [..]

---

Dan is er nog deze vraag aan Yarvieh, in dit topic: [topic=304685]
code:
1
2
3
// [..]
HRESULT HR=MesApp.CreateInstance("Messenger.MessengerApp");
// [..]

Hoe kom je op deze code? Dat Messenger.MessengerApp gedeelte bedoel ik. Want CreateInstance wordt aangeroepen door CoCreateInstance, dus is het resultaat van beide functies hetzelfde, alleen die parameter snap ik niet. Hier mag je "Messenger.MessengerApp" invullen, terwijl je in het andere geval met allemaal hexadecimale nummertjes moet werken?

---
Op maandag 10 juni 2002 09:28 schreef NDF82 het volgende:
implementeer zelf het protocol doe ik ook >:)
zie hier
-1 Overbodig, wij willen geen eigen client schrijven, maar communiceren met de bestaande client geschreven door Microsoft.

Trouwens...
http://www.hypothetic.org/docs/msn/index.php
http://www.venkydude.com/articles/msn.htm
...misschien zijn deze linkjes handig voor je, want versie 1 van het protocol is een beetje achterhaald. >:)

Verwijderd

Op maandag 10 juni 2002 15:21 schreef Ericston het volgende:
Waarom zouden VB coders eigenlijk met VC++ bezig gaan als er zoveel VB zut te vinden is? ;)
Omdat VB coders het gehack met api's in vb best es zat kunnen worden en denken "FUCK VB! ik move over naar VC!!" ik geef toe 't is een wat grote stap en vele zullen ook snel terug stappen naar hun oude vertrouwde VB maar een paar uitzonderingen heb je altijd ;)
To no avail, alas, het is namelijk vrij irritant om te coden als je bij elke compile weer een process moet killen om de exe te laten schrijven...
Ik heb jouw source hier gecompileerd gehad, maare die sloot gewoon netjes af? ik dacht dat 't jou alleen om het memory leak te doen was eigenlijk.
En daarnaast blijft ie zelfs nog hangen wanneer CoCreateInstance() failed. Het lijkt dus niet geheel op openstaande references.
't probleem komt me vaagjes bekend voor met de pdh library op deze pc, vertoont het zelfde gedrag (niet afsluitende app,terwijl vc wel denkt dat ie klaar is) als ik PdhBrowseCounters aanroep blijft het process ook idd hangen bij afsluiten, nooit een oplossing voor gevonden, gek genoeg draait dezelfde exefile op een w2k pc hier in huis vlekkeloos.
...we hebben de IMessengerService en IMessengerUser interfaces gelocaliseerd in die andere typelibs. Deze bevatten allebei een put_FriendlyName method.
Alleen we zijn geen COM helden, en we zitten nu totaal vast met het implementeren hiervan.
Ik zal es kijken of ik hier 'n sample app in elkaar kan draaien.
Dan is er nog deze vraag aan Yarvieh, in dit topic: [topic=304685]
code:
1
2
3
// [..]
HRESULT HR=MesApp.CreateInstance("Messenger.MessengerApp");
// [..]

Hoe kom je op deze code? Dat Messenger.MessengerApp gedeelte bedoel ik. Want CreateInstance wordt aangeroepen door CoCreateInstance, dus is het resultaat van beide functies hetzelfde, alleen die parameter snap ik niet. Hier mag je "Messenger.MessengerApp" invullen, terwijl je in het andere geval met allemaal hexadecimale nummertjes moet werken?
Correct, als je in ComImp.h kijkt zal je daar de volgende fucnties tegen komen
code:
1
2
3
4
5
6
7
8
9
    // Creates the class specified by clsidString.  clsidString may
    // contain a class id, or a prog id string.
    //
    HRESULT CreateInstance(LPOLESTR clsidString, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()

    // Loads an interface for the provided CLSID.
    // Returns an HRESULT.  Any previous interface is released.
    //
    HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()

Wat dan weer verklaard waarom je er zowel strings als IID's mee mag geven aan CreateInstance want hij zoekt automagish de juiste functie er bij. Dus ja het resultaat van 'n CoCreateInstance en 'n CreateInstance uit de wrapper classes is het zelfde, de laatste is alleen wat flexibeler.

Verwijderd

Hmmz die friendly name zat schijnbaar wel in de standaard interace? want dit draait als 'n dolle hier..
code:
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
/// 
/// Msn/Winamp Test app
///
/// Todo: Include some form of error handling

#import "c:\program files\messenger\msmsgs.exe" no_namespace
#include  <stdio.h>
int main(void)
{
/// 
/// Initalize COM 
///

    CoInitialize(NULL);

///
/// Get Instance of Messenger.MsgrObject
///

    IMsgrObject2Ptr oMsgrObj = NULL;    
    HRESULT HR=oMsgrObj.CreateInstance("Messenger.MsgrObject");

///
/// Get currently playing songname (Cut/Paste from Winamp.com)
///

    HWND hwndWinamp = FindWindow("Winamp v1.x",NULL); 
    char this_title[2048],*p;
    GetWindowText(hwndWinamp,this_title,sizeof(this_title));
    p = this_title+strlen(this_title)-8;
    while (p >= this_title)
    {
        if (!strnicmp(p,"- Winamp",8)) break;
        p--;
    }
    if (p >= this_title) p--;
    while (p >= this_title && *p == ' ') p--;
    *++p=0;

///
/// Make up new name
///

    char NewName[4096];
    sprintf(NewName,"Ray is playing : %s",  this_title);

///
/// Tell msn to use it
///
    
    oMsgrObj->Services->PrimaryService->FriendlyName=NewName;
    
///
/// Release the interface pointer
///

    oMsgrObj.Release();

///
/// Uninitalize COM and exit app
///
    
    CoUninitialize();
    return 0;
}

Viel best mee toch?

  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
Op maandag 10 juni 2002 17:40 schreef Yarvieh een grote uitleg.
[..]
Woei, ontzettend bedankt!
Op maandag 10 juni 2002 18:00 schreef Yarvieh het volgende:
Hmmz die friendly name zat schijnbaar wel in de standaard interace? want dit draait als 'n dolle hier..
code:
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
/// 
/// Msn/Winamp Test app
///
/// Todo: Include some form of error handling

#import "c:\program files\messenger\msmsgs.exe" no_namespace
#include  <stdio.h>
int main(void)
{
/// 
/// Initalize COM 
///

    CoInitialize(NULL);

///
/// Get Instance of Messenger.MsgrObject
///

    IMsgrObject2Ptr oMsgrObj = NULL;    
    HRESULT HR=oMsgrObj.CreateInstance("Messenger.MsgrObject");

///
/// Get currently playing songname (Cut/Paste from Winamp.com)
///

    HWND hwndWinamp = FindWindow("Winamp v1.x",NULL); 
    char this_title[2048],*p;
    GetWindowText(hwndWinamp,this_title,sizeof(this_title));
    p = this_title+strlen(this_title)-8;
    while (p >= this_title)
    {
        if (!strnicmp(p,"- Winamp",8)) break;
        p--;
    }
    if (p >= this_title) p--;
    while (p >= this_title && *p == ' ') p--;
    *++p=0;

///
/// Make up new name
///

    char NewName[4096];
    sprintf(NewName,"Ray is playing : %s",  this_title);

///
/// Tell msn to use it
///
    
    oMsgrObj->Services->PrimaryService->FriendlyName=NewName;
    
///
/// Release the interface pointer
///

    oMsgrObj.Release();

///
/// Uninitalize COM and exit app
///
    
    CoUninitialize();
    return 0;
}

Viel best mee toch?
Jeej het werkt!

Maar wel als Console Application, want pIM->Services->PrimaryService->FriendlyName geeft een access violation als Win32 Application en als ik dat weglaat sluit ie dus niet af... :(

Iig...
...nadat Jaapf iets dergelijks werkende had gekregen in C++Builder ( componentjes verslepen enzo, lijkt toch wel een beetje op VB :r ;) ), maakte ik ook zoiets als jij hier hebt! Alleen ik had, naast dat Win32 application probleempje...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// onder voorbehoud van wazige naamgeving
// door extensief coden
IMsgrObjectPtr pIM = NULL;
// ipv
IMsgrObject2Ptr oMsgrObj = NULL;
// wat op zich niets uitmaakt geloof ik

// en

mbstowcs(bName, cName, 64);   // naar bstr converten
pIM->GetServices()->GetPrimaryService()->put_FriendlyName(bName);
// wat kennelijk niet werkt...
// ipv
oMsgrObj->Services->PrimaryService->FriendlyName=NewName;

Daarnaast kreeg ik Access Violations doordat ik pIM->Release() aanriep, ipv pIM.Release(). |:(

In ieder geval het werkt hier. Hardstikke bedankt voor je hulp! Viel idd best mee. ;)

edit:
Vraag me nu alleen nog af of het mogelijk is om dit ook zonder zo'n dos venster te maken. Hmmmm. ;)

Verwijderd

Op maandag 10 juni 2002 19:22 schreef Ericston het volgende:
Vraag me nu alleen nog af of het mogelijk is om dit ook zonder zo'n dos venster te maken. Hmmmm. ;)
?? ik zie het probleem niet zo?

Standaard WTL wizzard app projectje

[edit]
code:
1
2
 mbstowcs(bName, cName, 64);   // naar bstr converten
// wat kennelijk niet werkt...

Nee correct want 'n wide string != BSTR, de manier om BSTR's te maken is SysAllocString.

  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
Op maandag 10 juni 2002 19:45 schreef Yarvieh het volgende:
[..]
?? ik zie het probleem niet zo?
Standaard WTL wizzard app projectje
Ik had dus een Empty Project ( lekker clean enzo ). Maar blijkt nu dat VC++ in dit geval een Simple Project beter eet. Ws had ik een aantal configuratie opties verkeerd. :z
Win32 werkt nu dus ook. Bedankt voor de hint. ;)
[..]
Nee correct want 'n wide string != BSTR, de manier om BSTR's te maken is SysAllocString.
Hm, meen al iets dergelijks gelezen te hebben, maar ben er niet achteraan gegaan want jouw manier werkt iets makkelijker. :)

Verwijderd

Topicstarter
Okay, het werkt nu allemaal maar er gaat nog iets behoorlijk fout. Op de client verandert de naam, maar op het scherm van een andere user verandert hij heel even in de nieuwe naam en daarna springt hij weer terug in de oude. Dit is alleen als er een chatvenster open staat, als er niks openstaat en je opent een venster wordt de naam geupdate. Het moet kunnen want Grimbo kan het ook.

Verwijderd

Ik begin me serieus af te vragen of jullie nou 'n app aan het schrijven zijn of ik? :?

  • Ericston
  • Registratie: Maart 2001
  • Laatst online: 05-08 18:36
Op maandag 10 juni 2002 23:28 schreef Yarvieh het volgende:
Ik begin me serieus af te vragen of jullie nou 'n app aan het schrijven zijn of ik? :?
Ja, let maar niet op hem... ;)
Jaap / Nerd mode on(8) :// Røyksopp - Eple (00:37:03:51)| zegt:
hmm ligt denk ik aan messenger
Eric (8) 1. Dave Matthews Band - Ants Marching zegt:
ja, HEHE
Eric (8) 1. Dave Matthews Band - Ants Marching zegt:
dat zeg ik een uur terug al
Eric (8) 1. Dave Matthews Band - Ants Marching zegt:
dat heeft niks met code te maken
Eric (8) 1. Dave Matthews Band - Ants Marching zegt:
en het heeft helemaal niks met oorspronkelijke topic te maken
Pagina: 1