summaryrefslogtreecommitdiff
path: root/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'extensions')
-rw-r--r--extensions/source/ole/unoobjw.cxx124
1 files changed, 124 insertions, 0 deletions
diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index 9b9a86a83c52..44ceeee791ef 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -24,6 +24,10 @@
#include <unordered_map>
#include <vector>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <comdef.h>
+
#include <osl/diagnose.h>
#include <salhelper/simplereferenceobject.hxx>
#include <rtl/ustring.hxx>
@@ -36,6 +40,8 @@
#include <com/sun/star/reflection/ParamInfo.hpp>
#include <com/sun/star/beans/XExactName.hpp>
#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/beans/XMaterialHolder.hpp>
#include <com/sun/star/script/XInvocation2.hpp>
@@ -1040,6 +1046,92 @@ HRESULT InterfaceOleWrapper::doSetProperty( DISPPARAMS * /*pdispparams*/, VARIAN
return ret;
}
+class CXEnumVariant : public IEnumVARIANT,
+ public CComObjectRoot
+{
+public:
+ CXEnumVariant()
+ {
+ }
+
+ ~CXEnumVariant()
+ {
+ }
+
+ BEGIN_COM_MAP(CXEnumVariant)
+ COM_INTERFACE_ENTRY(IEnumVARIANT)
+ END_COM_MAP()
+
+ DECLARE_NOT_AGGREGATABLE(CXEnumVariant)
+
+ // Creates and intializes the enumerator
+ void Init(InterfaceOleWrapper* pInterfaceOleWrapper,
+ const Reference< XEnumeration > xEnumeration)
+ {
+ mpInterfaceOleWrapper = pInterfaceOleWrapper;
+ mxEnumeration = xEnumeration;
+ }
+
+ // IEnumVARIANT
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT **ppEnum) override
+ {
+ (void) ppEnum;
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt,
+ VARIANT *rgVar,
+ ULONG *pCeltFetched) override
+ {
+ if (pCeltFetched)
+ *pCeltFetched = 0;
+
+ if (celt == 0)
+ return E_INVALIDARG;
+
+ if (rgVar == NULL || (celt != 1 && pCeltFetched == NULL))
+ return E_FAIL;
+
+ for (ULONG i = 0; i < celt; i++)
+ VariantInit(&rgVar[i]);
+
+ while (celt > 0)
+ {
+ if (!mxEnumeration->hasMoreElements())
+ return S_FALSE;
+ Any aElement = mxEnumeration->nextElement();
+ mpInterfaceOleWrapper->anyToVariant(rgVar, aElement);
+ // rgVar->pdispVal->AddRef(); ??
+ if (pCeltFetched)
+ (*pCeltFetched)++;
+ rgVar++;
+ celt--;
+ }
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Reset() override
+ {
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE STDMETHODCALLTYPE Skip(ULONG celt) override
+ {
+ while (celt > 0)
+ {
+ if (!mxEnumeration->hasMoreElements())
+ return S_FALSE;
+ mxEnumeration->nextElement();
+ celt--;
+ }
+ return S_OK;
+ }
+
+private:
+ InterfaceOleWrapper* mpInterfaceOleWrapper;
+ Reference<XEnumeration> mxEnumeration;
+};
+
HRESULT InterfaceOleWrapper::InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
unsigned int * /*puArgErr*/, bool& bHandled)
@@ -1136,6 +1228,38 @@ HRESULT InterfaceOleWrapper::InvokeGeneral( DISPID dispidMember, unsigned short
return DISP_E_EXCEPTION;
}
}
+ else if (dispidMember == DISPID_NEWENUM)
+ {
+ bHandled = true;
+ if( !pvarResult)
+ return E_POINTER;
+
+ Reference< XEnumerationAccess > xEnumerationAccess(m_xOrigin, UNO_QUERY_THROW);
+ if (!xEnumerationAccess.is())
+ return DISP_E_MEMBERNOTFOUND;
+
+ Reference< XEnumeration > xEnumeration = xEnumerationAccess->createEnumeration();
+
+ CComObject<CXEnumVariant>* pEnumVar;
+
+ ret = CComObject<CXEnumVariant>::CreateInstance(&pEnumVar);
+ if (FAILED(ret))
+ return ret;
+
+ pEnumVar->AddRef();
+
+ pEnumVar->Init(this, xEnumeration);
+
+ pvarResult->vt = VT_UNKNOWN;
+ pvarResult->punkVal = NULL;
+
+ ret = pEnumVar->QueryInterface(IID_IUnknown, (void**)&pvarResult->punkVal);
+ if (FAILED(ret))
+ {
+ pEnumVar->Release();
+ return ret;
+ }
+ }
}
catch(const BridgeRuntimeError & e)
{