# Icq - Api



## Rodney (25. November 2003)

Hallo Leute,
gibt es irgendwo im Netz ein C++ Source-Grundcode von einer Anwendung die mit der ICQ Api arbeitet?
Weil ich bekomme das einfach nicht hin so mit der Api. 
Etwas ganz einfaches mit Verschickung einer einzelnen Message würde mir reichen...

DANKE IM VORRAUS , Rodney


----------



## Rodney (26. November 2003)

kann mir keiner helfen?


----------



## Rodney (28. November 2003)

schade... wär echt wichtig


----------



## Daniel Toplak (28. November 2003)

Gibt es denn zu dieser ICQ-API keine mitgelieferte Dokumentation?
Wenn ja, dann sollte sich doch da etwas daraus machen lassen.
Da ich keine Ahnung von dieser API habe (was kann sie, in welcher Form wird sie geliefert, statische lib, DLL oder so, welche Funktionen sind in der API vorhanden) kann ich dir auch nicht weiter helfen.
Vielleicht schilderst du mal ein konkretes Problem.

Gruß Homer


----------



## Rodney (30. November 2003)

es ist eine lib, doch da ist eine dokumentation dabei aber da steige ich einfach nicht durch, da steht auch nicht drin wie man eine SErververbindung erstellte etc!


----------



## com (16. Dezember 2003)

Die Doku hab ich mal angehängt, damit auch andere schauen können ...


----------



## Daniel Toplak (16. Dezember 2003)

Soweit ich das aus der Doku rauslesen konnt, kann man auch nicht über die API eine Serververbindung eingehen. Sondern man kann nur Den Status des Benutzers änder (Online, Offline, ....)
Außerdem steht doch eigenlich sonst alles drin in der Doku was man damit machen kann (is ja net allzuviel).
Wichtig ist dabei denke ich, daß diese API nicht frei ist, d.h. man benötigt eine Lizenz, bzw. ein Password, sonst geht da irgendwie garnix.
Das ganze wird auf 2 Arten verwendet.
1. Man verwendet die Exportierten Funktionen der DLL oder
2. Man linkt die .lib statisch in die Applikation rein.

Bei beiden Varianten müssen natürlich die entsprechenden Headerdateien includiert werden.
Und dann steht der Verwendung eigentlich nichts mehr im Wege.
Der Rest steht ja in der Doku.
Etwas komplizierter wird es bei den "Callback-Notifyern", da werden natürlich gewisse Kenntnise von Funktionszeigern vorrausgesetzt.

Gruß Homer


----------



## com (16. Dezember 2003)

Ja das linken der LIB und die Kennwörter / Lizenz ist kein Problem, die bekommt man 4 free von ICQ

Header einbinde etc. ist ja auch kein ding, the same bei der callback, das ding ist blos laut der doku soll man nur diesen einen aufruf machen um die lizenz zu aktivieren, aber das gleich problem bei mir, man bekommt immer false zurück (obwohl die werte stimmen)

das macht mich ein wenig stuzig..

und ich bin auch noch nicht ganz dahinter gestiegen ob man jetzt damit nur seinen client vernsteuern kann oder ob man sich quasi nen eigenen client bauen kann!?


----------



## Daniel Toplak (17. Dezember 2003)

> das ding ist blos laut der doku soll man nur diesen einen aufruf machen um die lizenz zu aktivieren, aber das gleich problem bei mir, man bekommt immer false zurück (obwohl die werte stimmen)


Hm evtl. mal bei ICQ anfragen, da kann ich auch nicht weiterhelfen.



> und ich bin auch noch nicht ganz dahinter gestiegen ob man jetzt damit nur seinen client vernsteuern kann oder ob man sich quasi nen eigenen client bauen kann!?


Also so wie ich das verstanden habe, ist es nicht möglich einen eigenen Client zu bauen, sondern nur mit dem bestehenden Client zu kommunizieren.

Gruß Homer


----------



## fld (26. Dezember 2003)

Dann will ich mal versuchen, etwas Licht ins Dunkel zu bringen:

Zuallererst vielleicht mal eine kurze Erklärung *was* genau diese ominöse ICQ API ist: Dabei handelt es sich um eine DDE (Dynamic data exchange) Implementation. Im Klartext heißt das, daß die API lediglich die Fernsteuerung eines ICQ Clients erlaubt, nicht aber, daß man z.B. einen eigenen Client auf Basis des ICQ Netzwerk Protokolls schreiben kann.


> laut der doku soll man nur diesen einen aufruf machen um die lizenz zu aktivieren


 Das stimmt so nicht ganz -- ICQAPICall_SetLicenseKey sagt lediglich der API, daß Du (theoretisch) registrierter und damit legaler Nutzer bist. Ohne diese Validierung der Daten sind keine weiteren API-Aufrufe möglich. Obwohl diese Funktion von zentraler Bedeutung für die Nutzung der API ist, ist sich die Dokumentation zu fein ihr auch die nötige Beachtung zu schenken.





> Das ganze wird auf 2 Arten verwendet.
> 1. Man verwendet die Exportierten Funktionen der DLL oder
> 2. Man linkt die .lib statisch in die Applikation rein.


 Hmmm, nein. Die .lib selbst bestimmt, ob sie statisch gelinkt werden kann, oder nur dem Linker die Möglichkeit für eine automatische Importierung der exportierten .dll-Funktionalität zur Verfügung stellt. Bei der vorliegenden Version der API ist lediglich die Nutzung in Form einer .dll möglich. Richtig ist, daß man dies auf unterschiedliche Arten bewerkstelligen kann:
Project -> Settings -> Link -> General [für MSVC]
#pragma comment( lib, "icqmapi" ) [für MSVC]
zur Laufzeit mittels LoadLibrary und GetProcAddress
zu 1.) wird _implizites_ Linken genannt, weil der Linker automatisch den Code generiert, um die Bibliothek bei Programmstart zu laden und die Adressen der exportierten Funktionen zu erfragen. Sollte dabei irgendetwas nicht funktionieren, bricht das Programm umgehend die Ausführung mit einer Fehlermeldung ab, noch bevor überhaupt main bzw. WinMain aufgerufen worden sind. Somit hat der Entwickler keinerlei Möglichkeiten selbst auf Fehler zu reagieren.

zu 2.) ist identisch zu 1.), hat allerdings den Vorteil, daß das #pragma direkt in den Code geschrieben wird und damit zum einen diesen aussagekräftiger macht, zum anderen der Code auch ohne das .dsp [MSVC] noch vollständig kompilierbar bleibt. Letzteres hilft, wenn man Source Code mit anderen Entwicklern austauscht.

zu 3.) wird _explizites_ Linken genannt. Der Entwickler hat die volle Kontrolle. Falls z.B. die Bibliothek nicht geladen, oder eine Funktion nicht importiert werden konnte, kann darauf von Programmseite reagiert werden, in welcher Form auch immer. Beim expliziten Linken braucht man auch keine .lib, da die enthaltenen Informationen nur für das implizite Linken gebraucht werden. Das explizite Linken bietet aber noch andere Vorteile. So muß die .dll nicht mehr mit der eigentlichen Applikation weiter gegeben werden, sondern die Applikation kann selbständig auf dem Zielrechner nach der installierten .dll suchen (ICQ-Installationspfad aus der Registry auslesen und ab geht's). Damit bleibt die Applikation auch mit zukünftigen .dll Versionen (theoretisch) lauffähig und kann dadurch von eventuellen Bugfixes profitieren. Da aber mittlerweile AOL und Macromedia ihre Finger im Spiel haben, und beide Unternehmen bei mir einen zweifelhaften Ruf genießen, was die Qualität der Produkte betrifft, würde ich mich auf die Abwärtskompatibilität nicht verlassen.

Was sonst noch wichtig sein könnte:
ICQAPICall_GetFullUserData hat in der ausgelieferten .dll (Version 1.0001) einen Bug: Wird die Funktion für einen User aufgerufen, der zwar in den Contacts ist, aber als Offline geführt wird, wird dieser fälschlicherweise als Online gemeldet (m_iStateFlags). Im Zuge des Umbaus meiner Anwendung auf explizites Linken will ich mal sehen, ob das in der aktuellen .dll (bei mir ist das v1.0002 - ICQ2003a) vielleicht behoben ist. Falls jemand Interesse hat, kann ich das Ergebnis hier posten.
So wie ich die Sache sehe, gibt es keine Möglichkeit in der API zuverlässig zu testen oder Notifications zu erhalten, wenn/ob der ICQ Client gestartet/beendet wurde. Im Moment fallen mir nur 2 Möglichkeiten ein:
Falls ICQAPICall_SetLicenseKey fehlschlägt einen Timer zu setzen, der alle n Sekunden erneut versucht, die Funktion aufzurufen, bis der Aufruf erfolgreich ist.
einen systemweiten Windows Hook zu setzen, der auf Erstellen und Zerstören von Toplevel-Windows anschlägt und entsprechend erneut versucht, ICQAPICall_SetLicenseKey aufzurufen, bzw. per ICQAPICall_GetWindowHandle und IsWindow überprüft, ob der Client noch läuft
Die erste Methode ist simpel, aber schlampig und wenig verlässlich, da man möglicherweise verpaßt, daß der Client kurz gelaufen ist. Die zweite Methode ist nicht ganz trivial und zwingt einen dazu, selbst eine .dll zu schreiben und über Prozessgrenzen hinweg zu kommunizieren. Machbar, aber irgendwie drängen sich dabei die Vokabeln _Spatzen_ und _Kanonen_ in meinem Kopf in den Vordergrund. Ist es wirklich zuviel verlangt, für dieses wirklich wichtige Ereignis eine Notification zu verschicken? Anscheinend....

Zum Schluß noch kurz was zum Versenden von Nachrichten: Das Problem an dieser scheinbar simplen Aktion ist, daß der Funktionsname selbst schon eine Lüge ist. Die Methode öffnet lediglich einen Message-Session-Dialog und schreibt den Text in das entsprechende Fenster. Das eigentliche Versenden der Nachricht wird verweigert. Um diesen Prozess zu automatisieren braucht man zunächst mal ein Window Handle (HWND). Dafür fallen mir im Moment nur 2 Möglichkeiten ein: FindWindow und EnumWindows, wobei die erste Methode wohl einfacher ist. Wenn Du dann ein entsprechendes Fenster gefunden hast, mußt du in diesem nach der Textbox suchen, die die ICQ-UIN enthält, diese in einen int umwandeln und mit der eigentlichen UIN vergleichen, um sicherzustellen, daß Du das richtige Fenster hast. Anschließend per SendInput ein [CTRL]+[RETURN] an das Fenster schicken, oder per SendMessage eine WM_COMMAND-Nachricht mit dem entsprechenden Control-Identifier schicken. Anschließen kannst Du dann noch mit einem WM_CLOSE oder DestroyWindow den Message-Session-Dialog schließen. Wenn Du allerdings komplett die Darstellung des Dialogs unterbinden willst, mußt Du unweigerlich Hooks benutzen und jedes ShowWindow( hWnd, SW_SHOW ) unterbinden. Wiederum alles machbar, aber der Aufwand ist wirklich schwer zu rechtfertigen.

Das soll's dann erstmal gewesen sein. Fragen? Kritik? Anregungen? Nur her damit.

.f


----------

