Seite 1 von 1
QAxWidget und InvokeHelper
Verfasst: 28. Januar 2014 15:31
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
Re: QAxWidget und InvokeHelper
Verfasst: 28. Januar 2014 23:16
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();
Re: QAxWidget und InvokeHelper
Verfasst: 29. Januar 2014 07:45
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
Re: QAxWidget und InvokeHelper
Verfasst: 29. Januar 2014 13:01
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
Re: QAxWidget und InvokeHelper
Verfasst: 29. Januar 2014 19:23
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.