Help - Search - Members - Calendar
Full Version: C++ event handling
Skype Community > English > Development, Betas and Skype Garage > Skype Public API
oferc_
I'm trying to use the skype4com to work with skype from c++ code.
All the strait forward commands works great, but I don't get the events.

I'm attaching the basics of my code, maybe someone know why it's notworking.

10x,

Ofer


/*----------- Activation code -------------------------*/
CComPtr<_ISkypeEvents> evnt;
CComPtr<ISkype> app = NULL;
CComPtr<IApplication> pApp;
CComPtr<IConnectionPoint> pIConnectionPoint = NULL;
CComPtr<IConnectionPointContainer> pIConnectionPointContainer = NULL;
HRESULT hr;

hr=CoCreateInstance(CLSID_EventsDispatcher,
NULL,CLSCTX_ALL,
DIID__ISkypeEvents,
(void**)&evnt);
if (hr != S_OK)
{
return hr;
}

hr = CoCreateInstance(CLSID_Skype, NULL, CLSCTX_ALL, IID_ISkype, (LPVOID *)&app);
if (hr != S_OK)
{
return hr;
}

app->ChangeUserStatus(cusDoNotDisturb);

hr=app->Attach(3, -1);
// query the Messenger Object for connection point container

hr=app->QueryInterface(IID_IConnectionPointContainer,(void**)&pIConnectionPointContainer);

// find the DMessengerEvents to see if it is supported

hr=pIConnectionPointContainer->FindConnectionPoint(DIID__ISkypeEvents,&pIConnectionPoint);

//finally advise the Messenger Object to get events

DWORD pdwCookie = NULL;//Pointer to the connection point identifier used by Unadvise
hr=pIConnectionPoint->Advise(evnt,&pdwCookie);

Sleep(100000);


/*--------------------- Class to get events -----------------------*/
class ATL_NO_VTABLE CEventsDispatcher :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CEventsDispatcher, &CLSID_EventsDispatcher>,
public ISupportErrorInfo,
// public IDispatchImpl<IEventsDispatcher, &IID_IEventsDispatcher, &LIBID_IMEventsCatchLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
public IDispatchImpl<_ISkypeEvents, &DIID__ISkypeEvents, &LIBID_IMEventsCatchLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CEventsDispatcher()
{
m_pUnkMarshaler = NULL;
}

DECLARE_REGISTRY_RESOURCEID(IDR_EVENTSDISPATCHER)


BEGIN_COM_MAP(CEventsDispatcher)
// COM_INTERFACE_ENTRY(IEventsDispatcher)
COM_INTERFACE_ENTRY(_ISkypeEvents)
// COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()

// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);

DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_GET_CONTROLLING_UNKNOWN()

HRESULT FinalConstruct()
{
return CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
}

void FinalRelease()
{
m_pUnkMarshaler.Release();
}

CComPtr<IUnknown> m_pUnkMarshaler;

public:
STDMETHODIMP CEventsDispatcher::Invoke(DISPID dispidMember,
REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pvarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
int x;
x=1;
return S_OK;
}
STDMETHODIMP CEventsDispatcher::Command( ICommand* pCommand){return S_OK;}
STDMETHODIMP CEventsDispatcher::Reply( ICommand* pCommand){return S_OK;}
STDMETHODIMP CEventsDispatcher::Error(
ICommand* pCommand,
long Number,
BSTR Description){return S_OK;}
STDMETHODIMP CEventsDispatcher::AttachmentStatus( TAttachmentStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::ConnectionStatus( TConnectionStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::UserStatus( TUserStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::OnlineStatus(
IUser* pUser,
TOnlineStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::CallStatus(
ICall* pCall,
TCallStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::CallHistory(){return S_OK;}
STDMETHODIMP CEventsDispatcher::Mute( VARIANT_BOOL Mute){return S_OK;}
STDMETHODIMP CEventsDispatcher::MessageStatus(
IChatMessage* pMessage,
TChatMessageStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::MessageHistory( BSTR Username){return S_OK;}
STDMETHODIMP CEventsDispatcher::AutoAway( VARIANT_BOOL Automatic){return S_OK;}
STDMETHODIMP CEventsDispatcher::CallDtmfReceived(
ICall* pCall,
BSTR code){return S_OK;}
STDMETHODIMP CEventsDispatcher::VoicemailStatus(
IVoicemail* pMail,
TVoicemailStatus Status){return S_OK;}
STDMETHODIMP CEventsDispatcher::ApplicationConnecting(
IApplication* pApp,
IUserCollection* pUsers){return S_OK;}
STDMETHODIMP CEventsDispatcher::ApplicationStreams(
IApplication* pApp,
IApplicationStreamCollection* pStreams){return S_OK;}
STDMETHODIMP CEventsDispatcher::ApplicationDatagram(
IApplication* pApp,
IApplicationStream* pStream,
BSTR Text){return S_OK;}
STDMETHODIMP CEventsDispatcher::ApplicationSending(
IApplication* pApp,
IApplicationStreamCollection* pStreams){return S_OK;}
STDMETHODIMP CEventsDispatcher::ApplicationReceiving(
IApplication* pApp,
IApplicationStreamCollection* pStreams){return S_OK;}
STDMETHODIMP CEventsDispatcher::ContactsFocused( BSTR UserHandle){return S_OK;}
STDMETHODIMP CEventsDispatcher::GroupVisible(
IGroup* pGroup,
VARIANT_BOOL Visible){return S_OK;}
STDMETHODIMP CEventsDispatcher::GroupExpanded(
IGroup* pGroup,
VARIANT_BOOL Expanded){return S_OK;}
STDMETHODIMP CEventsDispatcher::GroupUsers(
IGroup* pGroup,
IUserCollection* pUsers){return S_OK;}
STDMETHODIMP CEventsDispatcher::GroupDeleted( long GroupId){return S_OK;}
andreskaasik_
Here is one simple event handling example using ATL (tested from MSVC 6.0). Note, that not all events are handled by CSkypeEvents class. I hope this helps.

CODE


#include "stdafx.h"

using namespace SKYPE4COMLib;



static _ATL_FUNC_INFO AttachmentStatusInfo =  {CC_STDCALL,VT_EMPTY,1,{VT_I4}};

static _ATL_FUNC_INFO CommandInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};

static _ATL_FUNC_INFO ReplyInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};

static _ATL_FUNC_INFO ErrorInfo = {CC_STDCALL,VT_EMPTY,3,{VT_DISPATCH|VT_BYREF,VT_I4,VT_BSTR}};

static _ATL_FUNC_INFO ConnectionStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};

static _ATL_FUNC_INFO UserStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};

static _ATL_FUNC_INFO OnlineStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};

static _ATL_FUNC_INFO CallStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};

static _ATL_FUNC_INFO CallHistoryInfo = {CC_STDCALL,VT_EMPTY,0,{VT_EMPTY}};

static _ATL_FUNC_INFO MuteInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BOOL}};

static _ATL_FUNC_INFO MessageStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};

static _ATL_FUNC_INFO MessageHistoryInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BSTR}};



class CSkypeEvents : public IDispEventSimpleImpl<1,CSkypeEvents , &__uuidof(_ISkypeEvents)>

{

public:



BEGIN_SINK_MAP(CSkypeEvents)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 1, &Command,  &CommandInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 2, &Reply,  &ReplyInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 3, &Error,  &ErrorInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 4, &AttachmentStatus,  &AttachmentStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 5, &ConnectionStatus,  &ConnectionStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 6, &UserStatus,  &UserStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 7, &OnlineStatus,  &OnlineStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 8, &CallStatus,  &CallStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 10, &Mute,  &MuteInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 11, &MessageStatus,  &MessageStatusInfo)

  SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 12, &MessageHistory,  &MessageHistoryInfo)

END_SINK_MAP()



  void __stdcall Command(ICommand* pCommand) {

     _tprintf(_T("C(%d): %sn"), pCommand->GetId(), (LPCTSTR)pCommand->GetCommand());

  }

  void __stdcall Reply(ICommand* pCommand) {

     _tprintf(_T("R(%d): %sn"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());

  }

  void __stdcall Error(ICommand* pCommand, LONG Number, BSTR Description) {

     _tprintf(_T("E(%d): %sn"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());

  }

  void __stdcall AttachmentStatus(TAttachmentStatus Status) {

     _tprintf(_T("Attachment status %dn"), Status);

  }

  void __stdcall ConnectionStatus(TConnectionStatus Status) {

     _tprintf(_T("Connection status %dn"), Status);

  }

  void __stdcall UserStatus(TUserStatus Status) {

     _tprintf(_T("User status %dn"), Status);

  }

  void __stdcall OnlineStatus(IUser* pUser, TOnlineStatus Status) {

     _tprintf(_T("User %s status %dn"), (LPCTSTR)pUser->GetHandle(), Status);

  }

  void __stdcall CallStatus(ICall* pCall, TCallStatus Status) {

     _tprintf(_T("Call %d status %dn"), pCall->GetId(), Status);

  }

  void __stdcall CallHistory() {

     _tprintf(_T("Call history changedn"));

  }

  void __stdcall Mute(VARIANT_BOOL Status) {      

     if (Status == VARIANT_TRUE) {

        _tprintf(_T("Mute on"));

     } else {

        _tprintf(_T("Mute off"));

     }

  }

  void __stdcall MessageStatus(IChatMessage* pMessage, TChatMessageStatus Status) {

     _tprintf(_T("Message %d status %dn"), pMessage->GetId(), Status);

  }

  void __stdcall MessageHistory(BSTR Username) {

     _tprintf(_T("Message history changed %sn"), (LPCTSTR)_bstr_t(Username));

  }

};



int main(int argc, char* argv[])

{

  CoInitialize(NULL);

 

  // Create object

  ISkypePtr pSkype(__uuidof(Skype));



  // Create sink

  CSkypeEvents* pSink = new CSkypeEvents();



  // Connect events

  pSink->DispEventAdvise(pSkype);  



  // Attach to API

  pSkype->Attach(5, VARIANT_TRUE);



  // Test

  ISkypeUserPtr pSkypeUser(pSkype);



  CComBSTR bstrFullName;

  pSkypeUser->get_UserFullName(CComBSTR("echo123"), &bstrFullName);



  // Message loop

  MSG msg;

  while (GetMessage( &msg, NULL, 0, 0 )) {

     TranslateMessage(&msg);

     DispatchMessage(&msg);

  }



  // Disconnect events

  pSink->DispEventUnadvise(pSkype);



  // Cleanup

  pSkype = NULL;

  delete pSink;



  CoUninitialize();



return 0;

}

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.