1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // SODispatchInterceptor.cpp : Implementation of CHelpApp and DLL registration.
22 #include <sal/config.h>
28 #include "SOActiveX.h"
29 #include "SODispatchInterceptor.h"
30 #include "com_uno_helper.h"
31 #include <sal/macros.h>
34 #pragma clang diagnostic push
35 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
37 #include <so_activex.h>
39 #pragma clang diagnostic pop
42 COM_DECLSPEC_NOTHROW STDMETHODIMP
SODispatchInterceptor::InterfaceSupportsErrorInfo(REFIID riid
)
44 static const IID
* arr
[] =
46 &IID_ISODispatchInterceptor
,
49 for (std::size_t i
=0;i
<SAL_N_ELEMENTS(arr
);i
++)
52 if (InlineIsEqualGUID(*arr
[i
],riid
))
54 if (::ATL::InlineIsEqualGUID(*arr
[i
],riid
))
61 STDMETHODIMP
SODispatchInterceptor::queryDispatch( IDispatch FAR
* aURL
,
62 BSTR aTargetFrameName
,
64 IDispatch FAR
* FAR
* retVal
)
66 if ( !aURL
|| !retVal
) return E_FAIL
;
68 CComVariant aTargetUrl
;
69 OLECHAR
const * sURLMemberName
= L
"Complete";
71 HRESULT hr
= aURL
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sURLMemberName
), 1, LOCALE_USER_DEFAULT
, &nURLID
);
72 if( !SUCCEEDED( hr
) ) return hr
;
74 hr
= CComDispatchDriver::GetProperty( aURL
, nURLID
, &aTargetUrl
);
75 if( !SUCCEEDED( hr
) ) return hr
;
77 if( aTargetUrl
.vt
!= VT_BSTR
) return E_FAIL
;
79 if (!wcsncmp(aTargetUrl
.bstrVal
, L
".uno:OpenHyperlink", 18))
81 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDisp( this );
98 aArgs
[0] = CComVariant( nSearchFlags
);
99 aArgs
[1] = CComVariant( aTargetFrameName
);
100 aArgs
[2] = CComVariant( aURL
);
102 hr
= ExecuteFunc( m_xSlave
, L
"queryDispatch", aArgs
, 3, &aResult
);
103 if( !SUCCEEDED( hr
) || aResult
.vt
!= VT_DISPATCH
|| aResult
.pdispVal
== nullptr )
109 *retVal
= aResult
.pdispVal
;
111 CComQIPtr
< IUnknown
, &IID_IUnknown
> pIUnk( *retVal
);
119 STDMETHODIMP
SODispatchInterceptor::queryDispatches( SAFEARRAY FAR
* aDescripts
, SAFEARRAY FAR
* FAR
* retVal
)
121 if ( !aDescripts
|| !retVal
|| SafeArrayGetDim( aDescripts
) != 1 )
126 HRESULT hr
= SafeArrayGetLBound( aDescripts
, 1, &nLB
);
127 if( !SUCCEEDED( hr
) ) return hr
;
129 hr
= SafeArrayGetUBound( aDescripts
, 1, &nUB
);
130 if( !SUCCEEDED( hr
) ) return hr
;
131 if( nUB
< nLB
) return E_FAIL
;
133 *retVal
= SafeArrayCreateVector( VT_DISPATCH
, 0, nUB
- nLB
);
135 for ( long ind
= nLB
; ind
<= nUB
; ind
++ )
137 CComPtr
<IDispatch
> pElem
;
138 SafeArrayGetElement( aDescripts
, &ind
, pElem
);
141 OLECHAR
const * pMemberNames
[3] = { L
"FeatureURL", L
"FrameName", L
"SearchFlags" };
142 CComVariant pValues
[3];
143 hr
= GetPropertiesFromIDisp( pElem
, pMemberNames
, pValues
, 3 );
144 if( !SUCCEEDED( hr
) ) return hr
;
145 if( pValues
[0].vt
!= VT_DISPATCH
|| pValues
[0].pdispVal
== nullptr
146 || pValues
[1].vt
!= VT_BSTR
|| pValues
[2].vt
!= VT_I4
)
149 CComPtr
<IDispatch
> aRes
;
150 hr
= queryDispatch( pValues
[0].pdispVal
, pValues
[1].bstrVal
, pValues
[2].lVal
, &aRes
);
151 SafeArrayPutElement( *retVal
, &ind
, aRes
);
159 STDMETHODIMP
SODispatchInterceptor::dispatch( IDispatch FAR
* aURL
, SAFEARRAY FAR
* aArgs
)
162 OLECHAR
const * pUrlName
= L
"Complete";
164 HRESULT hr
= GetPropertiesFromIDisp( aURL
, &pUrlName
, &pValue
, 1 );
165 if( !SUCCEEDED( hr
) ) return hr
;
166 if( pValue
.vt
!= VT_BSTR
|| pValue
.bstrVal
== nullptr )
169 if (!wcsncmp(pValue
.bstrVal
, L
".uno:OpenHyperlink", 18))
171 long nLB
= 0, nUB
= 0;
172 // long nDim = SafeArrayGetDim( aArgs );
174 hr
= SafeArrayGetLBound( aArgs
, 1, &nLB
);
175 if( !SUCCEEDED( hr
) ) return hr
;
177 hr
= SafeArrayGetUBound( aArgs
, 1, &nUB
);
178 if( !SUCCEEDED( hr
) ) return hr
;
179 if( nUB
< nLB
) return E_FAIL
;
181 for ( long ind
= nLB
; ind
<= nUB
; ind
++ )
183 CComVariant pVarElem
;
184 SafeArrayGetElement( aArgs
, &ind
, &pVarElem
);
185 if( pVarElem
.vt
== VT_DISPATCH
&& pVarElem
.pdispVal
!= nullptr )
187 OLECHAR
const * pMemberNames
[2] = { L
"Name", L
"Value" };
188 CComVariant pValues
[2];
189 hr
= GetPropertiesFromIDisp( pVarElem
.pdispVal
, pMemberNames
, pValues
, 2 );
190 if( !SUCCEEDED( hr
) ) return hr
;
192 if( pValues
[0].vt
== VT_BSTR
&& pValues
[1].vt
== VT_BSTR
)
194 if (!wcsncmp(pValues
[0].bstrVal
, L
"URL", 3))
196 EnterCriticalSection( &mMutex
);
197 if( m_xParentControl
)
199 // call GetUrl to the browser instance
200 m_xParentControl
->GetURL( pValues
[1].bstrVal
, L
"_self" );
202 LeaveCriticalSection( &mMutex
);
214 STDMETHODIMP
SODispatchInterceptor::addStatusListener( IDispatch FAR
* /*xControl*/, IDispatch FAR
* /*aURL*/)
220 STDMETHODIMP
SODispatchInterceptor::removeStatusListener( IDispatch FAR
* /*xControl*/, IDispatch FAR
* /*aURL*/)
226 STDMETHODIMP
SODispatchInterceptor::getInterceptedURLs( SAFEARRAY FAR
* FAR
* pVal
)
228 *pVal
= SafeArrayCreateVector( VT_BSTR
, 0, 3 );
234 CComBSTR
aPattern( OLESTR( "ftp://*" ) );
235 SafeArrayPutElement( *pVal
, &ix
, aPattern
);
238 aPattern
= CComBSTR( OLESTR( "http://*" ) );
239 SafeArrayPutElement( *pVal
, &ix
, aPattern
);
242 aPattern
= CComBSTR( OLESTR( "file://*" ) );
243 SafeArrayPutElement( *pVal
, &ix
, aPattern
);
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */