[Libreoffice-commits] core.git: extensions/source stoc/source

Tor Lillqvist tml at collabora.com
Wed May 30 08:13:26 UTC 2018


 extensions/source/ole/unoobjw.cxx     |  291 +++++++++++++++++++++++++++++++++-
 extensions/source/ole/unoobjw.hxx     |    6 
 stoc/source/invocation/invocation.cxx |   20 +-
 3 files changed, 309 insertions(+), 8 deletions(-)

New commits:
commit 2b6a84c8f699c9da115ce297ad19b8f480ab608f
Author: Tor Lillqvist <tml at collabora.com>
Date:   Thu Feb 22 00:47:30 2018 +0200

    We might need to handle form controls as properties for OLE clients after all
    
    Start a bit of work on that.
    
    Change-Id: I7775f9598a81d64e9716996027b01f7f8e29745b
    Reviewed-on: https://gerrit.libreoffice.org/55043
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tor Lillqvist <tml at collabora.com>

diff --git a/extensions/source/ole/unoobjw.cxx b/extensions/source/ole/unoobjw.cxx
index 376496e005c8..1e2525791ee9 100644
--- a/extensions/source/ole/unoobjw.cxx
+++ b/extensions/source/ole/unoobjw.cxx
@@ -47,10 +47,12 @@
 #include <com/sun/star/script/XInvocation2.hpp>
 #include <com/sun/star/script/MemberType.hpp>
 #include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <ooo/vba/msforms/XCheckBox.hpp>
 #include <osl/interlck.h>
 #include <com/sun/star/uno/genfunc.h>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/profilezone.hxx>
+#include <comphelper/windowsdebugoutput.hxx>
 #include <o3tl/char16_t2wchar_t.hxx>
 
 #include "comifaces.hxx"
@@ -107,6 +109,8 @@ InterfaceOleWrapper::~InterfaceOleWrapper()
 
 STDMETHODIMP InterfaceOleWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppv)
 {
+    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::QueryInterface " << riid);
+
     HRESULT ret= S_OK;
 
     if( !ppv)
@@ -179,12 +183,263 @@ STDMETHODIMP  InterfaceOleWrapper::getOriginalUnoStruct( Any * pStruct)
 
 STDMETHODIMP InterfaceOleWrapper::GetTypeInfoCount( unsigned int * /*pctinfo*/ )
 {
-    return E_NOTIMPL ;
+    SAL_WARN("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetTypeInfoCount: NOTIMPL");
+    return E_NOTIMPL;
 }
 
-STDMETHODIMP InterfaceOleWrapper::GetTypeInfo(unsigned int /*itinfo*/, LCID /*lcid*/, ITypeInfo ** /*pptinfo*/)
+class CXTypeInfo : public ITypeInfo,
+                   public CComObjectRoot
 {
-    return E_NOTIMPL;
+public:
+    BEGIN_COM_MAP(CXTypeInfo)
+        COM_INTERFACE_ENTRY(ITypeInfo)
+    END_COM_MAP()
+
+    DECLARE_NOT_AGGREGATABLE(CXTypeInfo)
+
+    void Init(InterfaceOleWrapper* pInterfaceOleWrapper)
+    {
+        SAL_INFO("extensions.olebridge", "CXTypeInfo::Init() this=" << this << " for " << pInterfaceOleWrapper->getImplementationName());
+        mpInterfaceOleWrapper = pInterfaceOleWrapper;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetTypeAttr(TYPEATTR **ppTypeAttr) override
+    {
+        (void) ppTypeAttr;
+        SAL_WARN("extensions.olebridge", "CXTypeInfo::GetTypeAttr: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetTypeComp(ITypeComp **ppTComp) override
+    {
+        (void) ppTComp;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetTypeComp: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetFuncDesc(UINT index,
+                                                  FUNCDESC **ppFuncDesc) override
+    {
+        (void) index;
+        (void) ppFuncDesc;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetFuncDesc: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetVarDesc(UINT index,
+                                                 VARDESC **ppVarDesc) override
+    {
+        (void) index;
+        (void) ppVarDesc;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetVarDesc: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetNames(MEMBERID memid,
+                                               BSTR *rgBstrNames,
+                                               UINT cMaxNames,
+                                               UINT *pcNames) override
+    {
+        (void) memid;
+        (void) rgBstrNames;
+        (void) cMaxNames;
+        (void) pcNames;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetNames: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType(UINT index,
+                                                           HREFTYPE *pRefType) override
+    {
+        (void) index;
+        (void) pRefType;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetRefTypeOfImplType: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetImplTypeFlags(UINT index,
+                                                       INT *pImplTypeFlags) override
+    {
+        (void) index;
+        (void) pImplTypeFlags;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetImplTypeFlags: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(LPOLESTR *rgszNames,
+                                                    UINT cNames,
+                                                    MEMBERID *pMemId) override
+    {
+        (void) rgszNames;
+        (void) cNames;
+        (void) pMemId;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetIDsOfNames: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Invoke(PVOID pvInstance,
+                                             MEMBERID memid,
+                                             WORD wFlags,
+                                             DISPPARAMS *pDispParams,
+                                             VARIANT *pVarResult,
+                                             EXCEPINFO *pExcepInfo,
+                                             UINT *puArgErr) override
+    {
+        (void) pvInstance;
+        (void) memid;
+        (void) wFlags;
+        (void) pDispParams;
+        (void) pVarResult;
+        (void) pExcepInfo;
+        (void) puArgErr;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::Invoke: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetDocumentation(MEMBERID memid,
+                                                       BSTR *pBstrName,
+                                                       BSTR *pBstrDocString,
+                                                       DWORD *pdwHelpContext,
+                                                       BSTR *pBstrHelpFile) override
+    {
+        SAL_INFO("extensions.olebridge", "CxTypeInfo::GetDocumentation(" << memid << ")");
+        if (pBstrName)
+        {
+            if (memid == MEMBERID_NIL)
+            {
+                *pBstrName = SysAllocString(o3tl::toW(mpInterfaceOleWrapper->getImplementationName().getStr()));
+            }
+            else if (memid == DISPID_VALUE)
+            {
+                // MEMBERIDs are the same as DISPIDs, apparently?
+                *pBstrName = SysAllocString(L"Value");
+            }
+            else
+            {
+                *pBstrName = SysAllocString(L"Unknown");
+            }
+        }
+        if (pBstrDocString)
+            *pBstrDocString = SysAllocString(L"");;
+        if (pdwHelpContext)
+            *pdwHelpContext = 0;
+        if (pBstrHelpFile)
+            *pBstrHelpFile = NULL;
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetDllEntry(MEMBERID memid,
+                                                  INVOKEKIND invKind,
+                                                  BSTR *pBstrDllName,
+                                                  BSTR *pBstrName,
+                                                  WORD *pwOrdinal) override
+    {
+        (void) memid;
+        (void) invKind;
+        (void) pBstrDllName;
+        (void) pBstrName;
+        (void) pwOrdinal;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetDllEntry: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetRefTypeInfo(HREFTYPE hRefType,
+                                                     ITypeInfo **ppTInfo) override
+    {
+        (void) hRefType;
+        (void) ppTInfo;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetRefTypeInfo: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE AddressOfMember(MEMBERID memid,
+                                                      INVOKEKIND invKind,
+                                                      PVOID *ppv) override
+    {
+        (void) memid;
+        (void) invKind;
+        (void) ppv;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::AddressOfMember: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter,
+                                                     REFIID riid,
+                                                     PVOID *ppvObj) override
+    {
+        (void) pUnkOuter;
+        (void) riid;
+        (void) ppvObj;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::CreateInstance: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetMops(MEMBERID memid,
+                                              BSTR *pBstrMops) override
+    {
+        (void) memid;
+        (void) pBstrMops;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetMops: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE GetContainingTypeLib(ITypeLib **ppTLib,
+                                                           UINT *pIndex) override
+    {
+        (void) ppTLib;
+        (void) pIndex;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::GetContainingTypeLib: NOTIMPL");
+        return E_NOTIMPL;
+    }
+
+    virtual void STDMETHODCALLTYPE ReleaseTypeAttr(TYPEATTR *pTypeAttr) override
+    {
+        (void) pTypeAttr;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::ReleaseTypeAttr: NOTIMPL");
+    }
+
+    virtual void STDMETHODCALLTYPE ReleaseFuncDesc(FUNCDESC *pFuncDesc) override
+    {
+        (void) pFuncDesc;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::ReleaseFuncDesc: NOTIMPL");
+    }
+
+    virtual void STDMETHODCALLTYPE ReleaseVarDesc(VARDESC *pVarDesc) override
+    {
+        (void) pVarDesc;
+        SAL_WARN("extensions.olebridge", "CxTypeInfo::ReleaseVarDesc: NOTIMPL");
+    }
+
+private:
+    InterfaceOleWrapper* mpInterfaceOleWrapper;
+};
+
+STDMETHODIMP InterfaceOleWrapper::GetTypeInfo(unsigned int iTInfo, LCID, ITypeInfo ** ppTInfo)
+{
+    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetTypeInfo(" << iTInfo << ")");
+
+    if (!ppTInfo)
+        return E_POINTER;
+
+    if (iTInfo != 0)
+        return E_NOTIMPL;
+
+    HRESULT ret = S_OK;
+
+    CComObject<CXTypeInfo>* pTypeInfo;
+
+    ret = CComObject<CXTypeInfo>::CreateInstance(&pTypeInfo);
+    if (FAILED(ret))
+        return ret;
+
+    pTypeInfo->AddRef();
+
+    pTypeInfo->Init(this);
+
+    *ppTInfo = pTypeInfo;
+
+    return S_OK;
 }
 
 STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
@@ -193,6 +448,10 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
                                                 LCID /*lcid*/,
                                                 DISPID * rgdispid )
 {
+    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::GetIDsOfNames("
+             << OUString(o3tl::toU(rgszNames[0]))
+             << (cNames > 1 ? "...!" : "") << "," << cNames << ")");
+
     HRESULT ret = DISP_E_UNKNOWNNAME;
     try
     {
@@ -200,6 +459,8 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
         if( ! rgdispid)
             return E_POINTER;
 
+        // FIXME: Handle the cNames > 1 case
+
         if( ! _wcsicmp( *rgszNames, JSCRIPT_VALUE_FUNC) ||
             ! _wcsicmp( *rgszNames, BRIDGE_VALUE_FUNC))
         {
@@ -230,6 +491,8 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
                 if (m_xExactName.is())
                 {
                     exactName = m_xExactName->getExactName(name);
+                    if (exactName.isEmpty())
+                        exactName = name;
                 }
                 else
                 {
@@ -269,6 +532,7 @@ STDMETHODIMP InterfaceOleWrapper::GetIDsOfNames(REFIID /*riid*/,
             else
             {
                 *rgdispid = (*iter).second;
+                SAL_INFO("extensions.olebridge", "  " << name << ": " << *rgdispid);
                 ret = S_OK;
             }
         }
@@ -513,6 +777,13 @@ void SAL_CALL InterfaceOleWrapper::initialize( const Sequence< Any >& aArguments
         aArguments[0] >>= m_xInvocation;
         aArguments[1] >>= m_xOrigin;
         aArguments[2] >>= m_defaultValueType;
+
+        Reference<XServiceInfo> xServiceInfo(m_xOrigin, UNO_QUERY);
+        if (xServiceInfo.is())
+            m_sImplementationName = xServiceInfo->getImplementationName();
+
+        SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::initialize for "
+                 << (m_sImplementationName.isEmpty()?"an unknown implementation":m_sImplementationName));
         break;
     }
 
@@ -787,6 +1058,8 @@ STDMETHODIMP InterfaceOleWrapper::Invoke(DISPID dispidMember,
                                          EXCEPINFO * pexcepinfo,
                                          unsigned int * puArgErr )
 {
+    SAL_INFO("extensions.olebridge", "InterfaceOleWrapper@" << this << "::Invoke(" << dispidMember << ")");
+
     comphelper::ProfileZone aZone("COM Bridge");
     HRESULT ret = S_OK;
 
@@ -1142,9 +1415,19 @@ HRESULT InterfaceOleWrapper::InvokeGeneral( DISPID dispidMember, unsigned short
 // DISPID_VALUE | The DEFAULT Value is required in JScript when the situation
 // is that we put an object into an Array object ( out parameter). We have to return
 // IDispatch otherwise the object cannot be accessed from the Script.
-        if( dispidMember == DISPID_VALUE && wFlags == DISPATCH_PROPERTYGET
+        if( dispidMember == DISPID_VALUE && (wFlags & DISPATCH_PROPERTYGET) != 0
             && m_defaultValueType != VT_EMPTY && pvarResult != nullptr)
         {
+            // Special case hack: If it is a ScVbaCheckBox, return the boolean value
+            Reference<ooo::vba::msforms::XCheckBox> xCheckBox(m_xOrigin, UNO_QUERY);
+            if (xCheckBox.is())
+            {
+                bHandled = true;
+                Any aValue = xCheckBox->getValue();
+                anyToVariant(pvarResult, aValue);
+                return S_OK;
+            }
+
             bHandled= true;
             if( m_defaultValueType == VT_DISPATCH)
             {
diff --git a/extensions/source/ole/unoobjw.hxx b/extensions/source/ole/unoobjw.hxx
index 528d6a342a04..f77d2aba10d5 100644
--- a/extensions/source/ole/unoobjw.hxx
+++ b/extensions/source/ole/unoobjw.hxx
@@ -159,6 +159,10 @@ public:
     virtual Reference< XInterface > createUnoWrapperInstance() override;
     virtual Reference< XInterface > createComWrapperInstance() override;
 
+    const OUString& getImplementationName() const
+    {
+        return m_sImplementationName;
+    }
 
 protected:
     virtual HRESULT doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
@@ -194,6 +198,8 @@ protected:
     // see InterfaceOleWrapper::Invoke
     VARTYPE                         m_defaultValueType;
 
+    // The name of the implementation. Can be empty if unknown.
+    OUString                        m_sImplementationName;
 };
 
 /*****************************************************************************
diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx
index 830ad61e33a6..68ea0ce3ccc3 100644
--- a/stoc/source/invocation/invocation.cxx
+++ b/stoc/source/invocation/invocation.cxx
@@ -458,8 +458,12 @@ sal_Bool Invocation_Impl::hasMethod( const OUString& Name )
 
 sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
 {
-    if (!mbFromOLE && _xDirect.is())
-        return _xDirect->hasProperty( Name );
+    if (_xDirect.is())
+    {
+        bool bRet = _xDirect->hasProperty( Name );
+        if (bRet || !mbFromOLE)
+            return bRet;
+    }
     // PropertySet
     if( _xIntrospectionAccess.is()
         && _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
@@ -473,8 +477,16 @@ sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
 
 Any Invocation_Impl::getValue( const OUString& PropertyName )
 {
-    if (!mbFromOLE && _xDirect.is())
-        return _xDirect->getValue( PropertyName );
+    try
+    {
+        if (_xDirect.is())
+            return _xDirect->getValue( PropertyName );
+    }
+    catch (RuntimeException &)
+    {
+        if (!mbFromOLE)
+            throw;
+    }
     try
     {
         // PropertySet


More information about the Libreoffice-commits mailing list