diff options
-rw-r--r-- | qtactiveqt.pro | 7 | ||||
-rw-r--r-- | src/activeqt/container/qaxbase.cpp | 54 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/qaxobject/qaxobject.pro | 3 | ||||
-rw-r--r-- | tests/auto/qaxobject/tst_qaxobject.cpp | 77 | ||||
-rw-r--r-- | tests/tests.pro | 2 |
6 files changed, 137 insertions, 9 deletions
diff --git a/qtactiveqt.pro b/qtactiveqt.pro index 91317de..8fd1d20 100644 --- a/qtactiveqt.pro +++ b/qtactiveqt.pro @@ -3,6 +3,12 @@ TEMPLATE = subdirs activeqt_src.subdir = $$IN_PWD/src activeqt_src.target = sub-src +activeqt_tests.subdir = $$IN_PWD/tests +activeqt_tests.target = sub-tests +activeqt_tests.depends = activeqt_src +activeqt_tests.CONFIG = no_default_install +!contains(QT_BUILD_PARTS,tests):activeqt_tests.CONFIG += no_default_target + activeqt_tools.subdir = $$IN_PWD/tools activeqt_tools.target = sub-tools activeqt_tools.depends = activeqt_src @@ -13,6 +19,7 @@ activeqt_examples.depends = activeqt_src win32 { SUBDIRS = activeqt_src \ + activeqt_tests \ activeqt_tools \ activeqt_examples } diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index f4ae696..9034ad6 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -68,6 +68,36 @@ QT_BEGIN_NAMESPACE +static inline HRESULT Invoke(IDispatch *disp, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + DWORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + unsigned int *puArgErr) +{ + if ((wFlags & DISPATCH_PROPERTYPUT) && + pDispParams && + pDispParams->cArgs == 1 && + pDispParams->cNamedArgs == 1 && + pDispParams->rgdispidNamedArgs && + *pDispParams->rgdispidNamedArgs == DISPID_PROPERTYPUT && + pDispParams->rgvarg) { + VARTYPE vt = pDispParams->rgvarg->vt; + + if (vt == VT_UNKNOWN || vt == VT_DISPATCH || (vt & VT_ARRAY) || (vt & VT_BYREF)) { + HRESULT hr = disp->Invoke(dispIdMember, riid, lcid, (wFlags & ~DISPATCH_PROPERTYPUT) | DISPATCH_PROPERTYPUTREF, + pDispParams, pVarResult, pExcepInfo, puArgErr); + if (SUCCEEDED(hr)) + return hr; + } + } + + return disp->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + /* \internal \class QAxMetaObject @@ -2371,7 +2401,9 @@ QByteArray MetaObjectGenerator::createPrototype(FUNCDESC *funcdesc, ITypeInfo *t const QByteArray hresult("HRESULT"); // get function prototype type = guessTypes(funcdesc->elemdescFunc.tdesc, typeinfo, function); - if ((type.isEmpty() || type == hresult) && funcdesc->invkind == INVOKE_PROPERTYPUT && funcdesc->lprgelemdescParam) { + if ((type.isEmpty() || type == hresult) && + (funcdesc->invkind == INVOKE_PROPERTYPUT || funcdesc->invkind == INVOKE_PROPERTYPUTREF) && + funcdesc->lprgelemdescParam) { type = guessTypes(funcdesc->lprgelemdescParam->tdesc, typeinfo, function); } @@ -2413,7 +2445,8 @@ QByteArray MetaObjectGenerator::createPrototype(FUNCDESC *funcdesc, ITypeInfo *t if (!prototype.isEmpty()) { if (prototype.endsWith(',')) { - if (funcdesc->invkind == INVOKE_PROPERTYPUT && p == funcdesc->cParams) { + if ((funcdesc->invkind == INVOKE_PROPERTYPUT || funcdesc->invkind == INVOKE_PROPERTYPUTREF) && + p == funcdesc->cParams) { TYPEDESC tdesc = funcdesc->lprgelemdescParam[p-1].tdesc; QByteArray ptype = guessTypes(tdesc, typeinfo, function); prototype += ptype; @@ -2484,6 +2517,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) switch(funcdesc->invkind) { case INVOKE_PROPERTYGET: // property case INVOKE_PROPERTYPUT: + case INVOKE_PROPERTYPUTREF: if (funcdesc->cParams - funcdesc->cParamsOpt <= 1) { bool dontBreak = false; // getter with non-default-parameters -> fall through to function handling @@ -2526,11 +2560,13 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) break; // generate setter slot - if (funcdesc->invkind == INVOKE_PROPERTYPUT && hasProperty(function)) { + if ((funcdesc->invkind == INVOKE_PROPERTYPUT || funcdesc->invkind == INVOKE_PROPERTYPUTREF) && + hasProperty(function)) { addSetterSlot(function); break; } - } else if (funcdesc->invkind == INVOKE_PROPERTYPUT && hasProperty(function)) { + } else if ((funcdesc->invkind == INVOKE_PROPERTYPUT || funcdesc->invkind == INVOKE_PROPERTYPUTREF) && + hasProperty(function)) { addSetterSlot(function); // more parameters -> function handling if (funcdesc->cParams > 1) @@ -2539,7 +2575,7 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) if (!dontBreak) break; } - if (funcdesc->invkind == INVOKE_PROPERTYPUT) { + if (funcdesc->invkind == INVOKE_PROPERTYPUT || funcdesc->invkind == INVOKE_PROPERTYPUTREF) { // remove the typename guessed for property setters // its done only for setter's with more than one parameter. if (funcdesc->cParams - funcdesc->cParamsOpt > 1) { @@ -3503,7 +3539,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) params.rgdispidNamedArgs = 0; params.rgvarg = 0; - hres = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &arg, &excepinfo, 0); + hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &arg, &excepinfo, 0); // map result VARIANTARG to void* uint type = QVariant::Int; @@ -3549,7 +3585,7 @@ int QAxBase::internalProperty(QMetaObject::Call call, int index, void **v) break; } } - hres = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, 0, &excepinfo, &argerr); + hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, 0, &excepinfo, &argerr); clearVARIANT(&arg); break; @@ -3647,7 +3683,7 @@ int QAxBase::internalInvoke(QMetaObject::Call call, int index, void **v) memset(&excepinfo, 0, sizeof(excepinfo)); WORD wFlags = isProperty ? DISPATCH_PROPERTYPUT : DISPATCH_METHOD | DISPATCH_PROPERTYGET; - hres = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, wFlags, ¶ms, &ret, &excepinfo, &argerr); + hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, wFlags, ¶ms, &ret, &excepinfo, &argerr); // get return value if (hres == S_OK && ret.vt != VT_EMPTY) @@ -3947,7 +3983,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList<QVariant> & memset(&excepinfo, 0, sizeof(excepinfo)); UINT argerr = 0; - HRESULT hres = disp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, disptype, ¶ms, res, &excepinfo, &argerr); + HRESULT hres = Invoke(disp, dispid, IID_NULL, LOCALE_USER_DEFAULT, disptype, ¶ms, res, &excepinfo, &argerr); if (disptype == (DISPATCH_METHOD|DISPATCH_PROPERTYGET) && hres == S_OK && varc) { for (int i = 0; i < varc; ++i) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro new file mode 100644 index 0000000..8e3a63f --- /dev/null +++ b/tests/auto/auto.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS += \ + qaxobject diff --git a/tests/auto/qaxobject/qaxobject.pro b/tests/auto/qaxobject/qaxobject.pro new file mode 100644 index 0000000..7e0fd69 --- /dev/null +++ b/tests/auto/qaxobject/qaxobject.pro @@ -0,0 +1,3 @@ +CONFIG += testcase qaxcontainer +QT += testlib +SOURCES += tst_qaxobject.cpp diff --git a/tests/auto/qaxobject/tst_qaxobject.cpp b/tests/auto/qaxobject/tst_qaxobject.cpp new file mode 100644 index 0000000..d0ad298 --- /dev/null +++ b/tests/auto/qaxobject/tst_qaxobject.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QAxObject> +#include <QByteArray> + +class tst_QAxObject : public QObject +{ + Q_OBJECT + +private slots: + void propertyByRefWritable(); + void setPropertyByRef(); +}; + +void tst_QAxObject::propertyByRefWritable() +{ + const QAxObject speak("SAPI.SPVoice"); + const QMetaObject *metaObject = speak.metaObject(); + + for (int i = 0; i < metaObject->propertyCount(); ++i) { + if (qstrcmp(metaObject->property(i).name(), "Voice") == 0) { + QVERIFY(metaObject->property(i).isWritable()); + break; + } + } +} + +void tst_QAxObject::setPropertyByRef() +{ + QAxObject speak("SAPI.SPVoice"); + + QVERIFY(speak.setProperty("Voice", speak.property("Voice"))); +} + +QTEST_MAIN(tst_QAxObject) +#include "tst_qaxobject.moc" diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 0000000..157ef34 --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += auto |