QAxWidget und InvokeHelper

Alles rund um die Programmierung mit Qt
Antworten
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

QAxWidget und InvokeHelper

Beitrag von Pixtar »

Hallo Leute,

ich habe vor mir auf dem Tisch eine Kamera, welche sich über ActiveX ansteuern lässt. Laut der Kamera-SDK, die ich verwende, muss ich mit der Methode InvokeHelper der Klasse CWnd arbeiten, um z. B. die Belichtungszeit einzustellen.

Ich habe soweit verstanden, dass über die Methode dynamicCall die verschiedenen Funktionen aufgerufen werden. In der Hilfe von Qt über QAxBase steht, dass man mit folgender Syntax weiterkommt:

activeX->dynamicCall("Navigate(\"qt.nokia.com\")");
bzw.
activeX->dynamicCall("Navigate(const QString&)", "qt.nokia.com");

Wenn ich dieses Konstrukt für die Methode InvokeHelper übersetze sieht das bei mir folgendermaßen aus:
activeX->dynamicCall("InvokeHelper(DISPID&, WORD&, VARTYPE&, void*&, const BYTE*&)",0xce,DISPATCH_METHOD,VT_I4,0,0,VT_I4);

Kompilieren funktioniert, aber nicht das Ausführen, da springt mich folgendes an:
QAxBase::dynamicCallHelper: InvokeHelper(DISPID&,WORD&,VARTYPE&,void*&,BYTE*): No such property in {922FB007-DD9A-11D3-BD8D-DAAFCB8D9378}
Candidates are: IsCapturing

Was ist hier die Aussage? Falsche Parameter? Kennt QAxBase kein InvokeHelper? Soll eine andere Methode benutzt werden? Ist die Syntax falsch?

Ich komme an der Stelle einfach nicht weiter.

Grüße,
Pixtar
veeman
Beiträge: 280
Registriert: 3. Oktober 2012 01:43
Kontaktdaten:

Re: QAxWidget und InvokeHelper

Beitrag von veeman »

ActivX ist eine allgemeine Schnittstelle zu Softwarebibliotheken.

Verwende anstatt der Klasse QAxBase die Klasse QAxObject.
Weil du zunächst eine Instanz von deiner Softwarebibliothek erstellen musst.

Letztere verlangt beim Konstruktor die ID bzw. den Bibliotheksnamen unter dem es in Windows Registriert ist um
die Schnittstelle verwenden zu können.

Ist dies erfolgreich getan, können die verfügbaren Funktionen mit dynamicCall aufgerufen werden.

Ex:

Code: Alles auswählen

QAxObject excel = new QAxObject("Excel.Application", this);
QMessageBox::information(this, "DocInfo", excel->generateDocumentation());
excel->dynamicCall("Quit()");
excel->deleteLater();
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Re: QAxWidget und InvokeHelper

Beitrag von Pixtar »

Hallo veeman,

VIELEN Dank für deinen Denkanstoß. Ich habe die Initialisierung bereits über QAxWidget::setControl vorgenommen, daran lag es also nicht.
Der Konstruktor von QAxObject ist dem von QAxWidget gleichgestellt würde ich sagen, da die Hilfe von Qt an beiden Stellen auf setControl verweist.

Code: Alles auswählen

axWidget = new QAxWidget(this);
axWidget->setControl("{922FB007-DD9A-11D3-BD8D-DAAFCB8D9378}");
Mein Problem an dieser Stelle war ein eklatanter Denkfehler. Da ich mit dynamicCall nicht weiterkam habe ich mir über folgendes Konstrukt direkt den IDispatch von der MFC besorgt:

Code: Alles auswählen

IDispatch *iface = 0;
QUuid *uID = new QUuid(IID_IDispatch);
axWidget->queryInterface(*uID, (void**)&iface);
.. und dann alles händig! über IDispatch gemacht -.-

Code: Alles auswählen

if(iface){
        OLECHAR* name = L"GetLuma";
        DISPID dispid;
        iface->GetIDsOfNames(IID_NULL, &name, 1, GetUserDefaultLCID(), &dispid);
        qDebug() << "GetLuma_ID: " << dispid;

        VARIANTARG MyArg[1];
        VariantInit(&MyArg[0]);
        MyArg[0].vt = VT_I4;
        MyArg[0].lVal = 0;
        DISPPARAMS MyParam = { MyArg, NULL, 1, 0 };
        VARIANT Result;

        HRESULT hr = iface->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, &MyParam, &Result, NULL, NULL);
        qDebug() << Result.lVal;
}
Das ist aber ALLES überflüssig, da man mit folgendem Code alles erschlägt ^^:

Code: Alles auswählen

qDebug() << "GetLuma: " << axWidget->dynamicCall("GetLuma(const long&)",0).toUInt();
Also nochmals vielen Dank für den Denkanstoß veeman.

Grüße,
Pixtar
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Re: QAxWidget und InvokeHelper

Beitrag von Pixtar »

Hallo,

eine Frage habe ich dennoch: Wie werden [in/out] Parameter über dynamicCall abgehandelt?

Beispielfunktion: GetIndex(int state [in], int *result [in/out], int *step [in/out])

Code: Alles auswählen

    int *res= new int;
    int *st = new int;
    axObject->dynamicCall(GetIndex(int, int&, int&),0,res,st);
Fehler: 'QVariant::QVariant(void*)' is private

Code: Alles auswählen

    int *res= new int;
    int *st= new int;
    QVariant vstate(0);
    QVariant vres= qVariantFromValue((void *)res);
    QVariant vst= qVariantFromValue((void *)st);
    QList <QVariant> lList;
    lList << vstate << vres << vst;
    axObject->dynamicCall(GetIndex(int, int&, int&),lList);
Fehler: Kein Rückgabewert in res/st und keiner in vres/vst.

Kann man beim dynamicCall überhaupt Zeiger benutzen? Wenn ja, wie?

Laut Qt Hilfe sollte es gehen: "QVariant QAxBase::dynamicCall ( const char * function, QList<QVariant> & vars ) .... The QVariant objects in vars are updated when the method has out-parameters."

Grüße,
Pixtar
veeman
Beiträge: 280
Registriert: 3. Oktober 2012 01:43
Kontaktdaten:

Re: QAxWidget und InvokeHelper

Beitrag von veeman »

Darf ich fragen was für eine Camera du da hast und um welches ActiveX Interface es sich handelt?

Ansonsten solltest du beim Aufruf von dynamicCall wenn möglich nur mit QVariant arbeiten, vor allem wenn du Rückgabewerte erwartest.
Dein Parameter den du beim Funktionsaufruf von GetLuma übergibst, also die 0 wird implizit von QVariant aufgenommen.

Wenn du nun deine Funktion GetIndex(int, int&, int&) aufrufen möchtest kannst du das wie folgt tuen:

Code: Alles auswählen

QVariant vara(0);
QVariant retb, retc;

axObject->dynamicCall("GetIndex(int, int&, int&)", vara, retb, retc);
// oder einfach
axObject->dynamicCall("GetIndex(int, int&, int&)", 0, retb, retc);

...

int res = retb.toInt();
int st = retc.toInt();

// .. tue was mit res und st
Insofern du extrem viele Parameter hast kannst du mit QVariantList arbeiten und die Paremter da rein-pushen.
Antworten