PDA

View Full Version : ActiveX events and Qt



rvdk
20th April 2011, 14:49
I'm trying to use the Skype4COM library in a Qt application. Now with dumpcpp I've created the h and cpp file.
I can collect User in my friends list and make a call but I don't know how I could receive events from Skype itself.
Watching the generated header file I found this:

// skipping event interface _ISkypeEvents and is probably not a good sign. Does anyone know how I could get the (Skype) events working? If I do it in C# it is fairly easiliy but I want it in Qt.

Further more when using my (basic) application I get a segmentation fault when exiting my app. Am I missing something do destroy the ActiveX component?
delete m_Skype; doesn't get rid of the segmentation fault.

Some code:
header:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QAxObject>
#include "skype4comlib.h"

using namespace SKYPE4COMLib;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private:
Ui::MainWindow* m_UI;
Skype* m_Skype;

};

#endif // MAINWINDOW_H

the cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_UI(new Ui::MainWindow)
{
m_UI->setupUi(this);

m_Skype = new Skype();
m_Skype->Attach(6, true);
//m_Skype->SetSilentMode(true);

IUserCollection* friends = m_Skype->Friends();

for (int i = 1; i <= friends->Count(); i++)
{
IUser* user = friends->Item(i);
qDebug() << i << ":" << user->FullName();
}
}

MainWindow::~MainWindow()
{
delete m_UI;
}

rvdk
26th April 2011, 12:19
Would using a QAxWidget and/or loading the dll directly instead of using dumpcpp help?

rvdk
26th April 2011, 15:41
I found out that qAxBase has already an event sink:


connect(m_Skype, SIGNAL(signal(QString,int,void*)), SLOT(Sink(QString,int,void*)));

Now I receive the events but the signatures differ from the Skype Documentation
By calling I get a
"CallStatus(IDispatch*,TCallStatus)" as name. But in documentation it should be
HRESULT CallStatus([in] ICall* pCall, [in] TCallStatus Status);

If I connect to the IDispatch, the connect will fail. If I connect to the ICall interface I don't get a msg in output(==succesfull) but events will not be send to that slot...

rvdk
27th April 2011, 11:07
I can receive the CallStatus using the sink but the parameters are incorrect. Casting the first parameter (IDispatch) is not working either.
Connecting to "CallStatus(IDispatch*,TCallStatus)" will fail because the signal could not be found.


m_Skype = new Skype();
m_Skype->Attach(5, true);
connect(m_Skype, SIGNAL(signal(QString,int,void*)), SLOT(Sink(QString,int,void*)));
connect(m_Skype, SIGNAL(ContactsFocused(QString)), SLOT(ContactsFocused(QString)));
connect(m_Skype, SIGNAL(CallStatus(ICall*,TCallStatus)), SLOT(CallStatus(ICall*,TCallStatus)));

void SkypeWrapper::ContactsFocused(QString name)
{
qDebug() << "ContactsFocused:" << name; // <- Called!
}

void SkypeWrapper::CallStatus(ICall* pCall, TCallStatus Status)
{
qDebug() << "CallStatus(ICall):"; // <- Never called
}

void SkypeWrapper::Sink(const QString& name, int argc, void * argv)
{
qDebug() << "sink: name(" << name << ") argc(" << argc<< ")";

VARIANTARG* params = (VARIANTARG*)argv;

if (name.startsWith("CallStatus"))
{
//According to Qt the arguments are in reverse order
IDispatch* dis = params[argc-1].pdispVal;
ICall* call = (ICall*)dis;
dis.Answer(); // <- Segmentation fault
}
}

It works for ContactsFocussed:

sink: name( "Reply(IDispatch*)" ) argc( 1 )
Object::receivers: No such signal SKYPE4COMLib::skype::Reply(IDispatch*)
sink: name( "ContactsFocused(QString)" ) argc( 1 )
ContactsFocused: "echo123" // <- Works!

But not for CallStatus:

sink: name( "Reply(IDispatch*)" ) argc( 1 )
Object::receivers: No such signal SKYPE4COMLib::skype::Reply(IDispatch*)
sink: name( "CallStatus(IDispatch*,TCallStatus)" ) argc( 2 ) //<- This should be CallStatus(ICall*,TCallStatus)
Object::receivers: No such signal SKYPE4COMLib::skype::CallStatus(IDispatch*,TCallSt atus)
sink: name( "Reply(IDispatch*)" ) argc( 1 )
Object::receivers: No such signal SKYPE4COMLib::skype::Reply(IDispatch*)
sink: name( "CallStatus(IDispatch*,TCallStatus)" ) argc( 2 )
Object::receivers: No such signal SKYPE4COMLib::skype::CallStatus(IDispatch*,TCallSt atus)

If I use the dumpinfo function I get:

OBJECT SKYPE4COMLib::skype::unnamed
SIGNALS OUT
//Snip
signal: CallStatus(ICall*,TCallStatus)
--> SkypeWrapper::SkypeWrapperCallStatus(ICall*,TCallS tatus)
//Snip
signal: ContactsFocused(QString)
--> SkypeWrapper::SkypeWrapperContactsFocused(QString)
//Snip
signal: signal(QString,int,void*)
--> SkypeWrapper::SkypeWrapperSink(QString,int,void*)
SIGNALS IN
<None>

Any ideas how to get the ICall* object?

slg1013
8th August 2011, 20:41
I was just wondering if you were ever able to solve this problem. I'm using a different library, but am getting similar error messages...

Thanks