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 // SOActiveX.cpp : Implementation of CSOActiveX
23 #include <so_activex.h>
24 #include "SOActiveX.h"
25 #include "SOComWindowPeer.h"
26 #include "SODispatchInterceptor.h"
27 #include "SOActionsApproval.h"
28 #include "com_uno_helper.h"
30 #define STAROFFICE_WINDOWCLASS L"SOParentWindow"
33 static void OutputError_Impl( HWND hw
, HRESULT ErrorCode
)
35 LPWSTR sMessage
= nullptr;
37 FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
,
40 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
41 reinterpret_cast<LPWSTR
>(&sMessage
),
45 MessageBoxW( hw
, sMessage
, nullptr, MB_OK
| MB_ICONINFORMATION
);
46 HeapFree( GetProcessHeap(), 0, sMessage
);
49 HRESULT
ExecuteFunc( IDispatch
* idispUnoObject
,
50 OLECHAR
const * sFuncName
,
53 CComVariant
* pResult
)
59 HRESULT hr
= idispUnoObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sFuncName
), 1, LOCALE_USER_DEFAULT
, &id
);
60 if( !SUCCEEDED( hr
) ) return hr
;
62 DISPPARAMS dispparams
= { params
, nullptr, count
, 0};
66 hr
= idispUnoObject
->Invoke( id
, IID_NULL
,LOCALE_USER_DEFAULT
, DISPATCH_METHOD
,
67 &dispparams
, pResult
, &myInfo
, nullptr);
69 // for debugging purposes
71 // if ( !SUCCEEDED( hr ) )
72 // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
77 static HRESULT
GetIDispByFunc( IDispatch
* idispUnoObject
,
78 OLECHAR
const * sFuncName
,
81 CComPtr
<IDispatch
>& pdispResult
)
87 HRESULT hr
= ExecuteFunc( idispUnoObject
, sFuncName
, params
, count
, &result
);
88 if( !SUCCEEDED( hr
) ) return hr
;
90 if( result
.vt
!= VT_DISPATCH
|| result
.pdispVal
== nullptr )
93 pdispResult
= CComPtr
<IDispatch
>( result
.pdispVal
);
98 static HRESULT
PutPropertiesToIDisp( IDispatch
* pdispObject
,
99 OLECHAR
const ** sMemberNames
,
100 CComVariant
* pVariant
,
103 for( unsigned int ind
= 0; ind
< count
; ind
++ )
106 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sMemberNames
[ind
]), 1, LOCALE_USER_DEFAULT
, &id
);
107 if( !SUCCEEDED( hr
) ) return hr
;
109 hr
= CComDispatchDriver::PutProperty( pdispObject
, id
, &pVariant
[ind
] );
110 if( !SUCCEEDED( hr
) ) return hr
;
116 HRESULT
GetPropertiesFromIDisp( IDispatch
* pdispObject
,
117 OLECHAR
const ** sMemberNames
,
118 CComVariant
* pVariant
,
121 for( unsigned int ind
= 0; ind
< count
; ind
++ )
124 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sMemberNames
[ind
]), 1, LOCALE_USER_DEFAULT
, &id
);
125 if( !SUCCEEDED( hr
) ) return hr
;
127 hr
= CComDispatchDriver::GetProperty( pdispObject
, id
, &pVariant
[ind
] );
128 if( !SUCCEEDED( hr
) ) return hr
;
136 CSOActiveX::CSOActiveX()
138 , mCurFileUrl( L
"private:factory/swriter" )
141 , mParentWin( nullptr )
143 , mpDispatchInterceptor( nullptr )
144 , mnVersion( SO_NOT_DETECTED
)
145 , mbReadyForActivation( FALSE
)
146 , mbDrawLocked( false )
148 CLSID
const clsFactory
= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
149 HRESULT hr
= CoCreateInstance( clsFactory
, nullptr, CLSCTX_ALL
, __uuidof(IDispatch
), reinterpret_cast<void**>(&mpDispFactory
));
150 if( !SUCCEEDED( hr
) )
151 OutputError_Impl( nullptr, hr
);
153 mPWinClass
.style
= CS_HREDRAW
|CS_VREDRAW
;
154 mPWinClass
.lpfnWndProc
= DefWindowProcW
;
155 mPWinClass
.cbClsExtra
= 0;
156 mPWinClass
.cbWndExtra
= 0;
157 mPWinClass
.hInstance
= GetModuleHandleW(nullptr); //myInstance;
158 mPWinClass
.hIcon
= nullptr;
159 mPWinClass
.hCursor
= nullptr;
160 mPWinClass
.hbrBackground
= reinterpret_cast<HBRUSH
>(COLOR_BACKGROUND
);
161 mPWinClass
.lpszMenuName
= nullptr;
162 mPWinClass
.lpszClassName
= STAROFFICE_WINDOWCLASS
;
164 RegisterClassW(&mPWinClass
);
167 CSOActiveX::~CSOActiveX()
173 HRESULT
CSOActiveX::Cleanup()
175 CComVariant dummyResult
;
177 if( mpDispatchInterceptor
)
181 // remove dispatch interceptor
182 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispDispInter( mpDispatchInterceptor
);
183 CComVariant
aVariant( pIDispDispInter
);
184 ExecuteFunc( mpDispFrame
,
185 L
"releaseDispatchProviderInterceptor",
191 mpDispatchInterceptor
->ClearParent();
192 mpDispatchInterceptor
->Release();
193 mpDispatchInterceptor
= nullptr;
196 mpDispTempFile
= CComPtr
< IDispatch
>();
197 mbReadyForActivation
= FALSE
;
199 if( mpInstanceLocker
)
201 ExecuteFunc( mpInstanceLocker
, L
"dispose", nullptr, 0, &dummyResult
);
202 mpInstanceLocker
= CComPtr
< IDispatch
>();
207 bool bCloserActivated
= false;
209 CComPtr
<IDispatch
> pDispDocumentCloser
;
210 CComVariant
aDocCloser( L
"com.sun.star.embed.DocumentCloser" );
211 HRESULT hr
= GetIDispByFunc( mpDispFactory
,
215 pDispDocumentCloser
);
216 if ( SUCCEEDED( hr
) && pDispDocumentCloser
)
218 SAFEARRAY
* pInitFrame
= SafeArrayCreateVector(VT_VARIANT
, 0, 1);
220 CComVariant
pFrameVariant( mpDispFrame
);
221 SafeArrayPutElement( pInitFrame
, &nInitInd
, &pFrameVariant
);
222 CComVariant aVarInitFrame
;
223 aVarInitFrame
.vt
= VT_ARRAY
| VT_VARIANT
; aVarInitFrame
.parray
= pInitFrame
;
224 hr
= ExecuteFunc( pDispDocumentCloser
, L
"initialize", &aVarInitFrame
, 1, &dummyResult
);
225 if( SUCCEEDED( hr
) )
227 // the following call will let the closing happen
228 hr
= ExecuteFunc( pDispDocumentCloser
, L
"dispose", nullptr, 0, &dummyResult
);
229 bCloserActivated
= SUCCEEDED( hr
);
233 if ( !bCloserActivated
)
235 CComVariant aPropVar
;
236 aPropVar
.vt
= VT_BOOL
; aPropVar
.boolVal
= VARIANT_TRUE
;
237 if ( !SUCCEEDED( ExecuteFunc( mpDispFrame
, L
"close", &aPropVar
, 1, &dummyResult
) ) )
238 ExecuteFunc( mpDispFrame
, L
"dispose", nullptr, 0, &dummyResult
);
241 mpDispFrame
= CComPtr
< IDispatch
>();
244 if( ::IsWindow( mOffWin
) )
245 ::DestroyWindow( mOffWin
);
252 HRESULT
CSOActiveX::TerminateOffice()
255 CComPtr
<IDispatch
> pdispDesktop
;
256 CComVariant
aDesktopServiceName( L
"com.sun.star.frame.Desktop" );
258 HRESULT hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aDesktopServiceName
, 1, pdispDesktop
);
259 if( !pdispDesktop
|| !SUCCEEDED( hr
) ) return hr
;
261 // create tree of frames
262 CComPtr
<IDispatch
> pdispChildren
;
263 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", nullptr, 0, pdispChildren
);
264 if( !pdispChildren
|| !SUCCEEDED( hr
) ) return hr
;
267 CComVariant
nFlag( 4 );
268 hr
= ExecuteFunc( pdispChildren
, L
"queryFrames", &nFlag
, 1, &aFrames
);
269 if ( SUCCEEDED( hr
) )
271 if ( ( aFrames
.vt
== ( VT_ARRAY
| VT_DISPATCH
) || aFrames
.vt
== ( VT_ARRAY
| VT_VARIANT
) )
272 && ( !aFrames
.parray
|| (aFrames
.parray
->cDims
== 1 && aFrames
.parray
->rgsabound
[0].cElements
== 0) ) )
274 // there is no frames open
275 // TODO: check whether the frames are hidden if they are open?
276 CComVariant dummyResult
;
277 hr
= ExecuteFunc( pdispDesktop
, L
"terminate", nullptr, 0, &dummyResult
);
284 COM_DECLSPEC_NOTHROW STDMETHODIMP
CSOActiveX::InitNew ()
286 mnVersion
= GetVersionConnected();
291 COM_DECLSPEC_NOTHROW STDMETHODIMP
CSOActiveX::Load ( LPSTREAM
/*pStm*/ )
293 mnVersion
= GetVersionConnected();
297 // for now just ignore
302 COM_DECLSPEC_NOTHROW STDMETHODIMP
CSOActiveX::Load( LPPROPERTYBAG pPropBag
, LPERRORLOG
/*pErrorLog*/ )
304 mnVersion
= GetVersionConnected();
306 IPropertyBag2
* pPropBag2
;
307 HRESULT hr
= pPropBag
->QueryInterface( IID_IPropertyBag2
, reinterpret_cast<void**>(&pPropBag2
) );
308 //ATLASSERT( hr >= 0 );
310 if( !SUCCEEDED( hr
) )
314 hr
= pPropBag2
->CountProperties( &aNum
);
315 //ATLASSERT( hr >= 0 );
316 if( !SUCCEEDED( hr
) )
319 PROPBAG2
* aPropNames
= new PROPBAG2
[aNum
];
320 unsigned long aReaded
;
322 hr
= pPropBag2
->GetPropertyInfo( 0,
326 //ATLASSERT( hr >= 0 );
327 if( !SUCCEEDED( hr
) )
333 CComVariant
* aVal
= new CComVariant
[aNum
];
334 HRESULT
* hvs
= new HRESULT
[aNum
];
335 hr
= pPropBag2
->Read( aNum
,
340 //ATLASSERT( hr >= 0 );
341 if( !SUCCEEDED( hr
) )
349 for( unsigned long ind
= 0; ind
< aNum
; ind
++ )
351 // all information from the 'object' tag is in strings
352 if (aVal
[ind
].vt
== VT_BSTR
&& !wcscmp(aPropNames
[ind
].pstrName
, L
"src"))
354 mCurFileUrl
.AssignBSTR(aVal
[ind
].bstrVal
);
356 else if( aVal
[ind
].vt
== VT_BSTR
357 && !wcscmp(aPropNames
[ind
].pstrName
, L
"readonly"))
359 if (!wcscmp(aVal
[ind
].bstrVal
, L
"true"))
378 mbReadyForActivation
= FALSE
;
379 hr
= CBindStatusCallback
<CSOActiveX
>::Download(
380 this, &CSOActiveX::CallbackCreateXInputStream
, mCurFileUrl
, m_spClientSite
, FALSE
);
381 if (hr
== MK_S_ASYNCHRONOUS
)
384 if ( !SUCCEEDED( hr
) )
386 // trigger initialization without stream
396 HRESULT
CSOActiveX::GetUnoStruct( OLECHAR
const * sStructName
, CComPtr
<IDispatch
>& pdispResult
)
398 CComVariant
aComStruct( sStructName
);
399 return GetIDispByFunc( mpDispFactory
, L
"Bridge_GetStruct", &aComStruct
, 1, pdispResult
);
402 HRESULT
CSOActiveX::GetUrlStruct( OLECHAR
const * sUrl
, CComPtr
<IDispatch
>& pdispUrl
)
404 HRESULT hr
= GetUnoStruct( L
"com.sun.star.util.URL", pdispUrl
);
405 if( !SUCCEEDED( hr
) ) return hr
;
407 OLECHAR
const * sURLMemberName
= L
"Complete";
409 hr
= pdispUrl
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sURLMemberName
), 1, LOCALE_USER_DEFAULT
, &nURLID
);
410 if( !SUCCEEDED( hr
) ) return hr
;
411 CComVariant
aComUrl( sUrl
);
412 hr
= CComDispatchDriver::PutProperty( pdispUrl
, nURLID
, &aComUrl
);
413 if( !SUCCEEDED( hr
) ) return hr
;
415 CComPtr
<IDispatch
> pdispTransformer
;
416 CComVariant
aServiceName( L
"com.sun.star.util.URLTransformer" );
417 hr
= GetIDispByFunc( mpDispFactory
,
422 if( !SUCCEEDED( hr
) ) return hr
;
424 CComVariant dummyResult
;
425 CComVariant aParam
[2];
426 aParam
[1].ppdispVal
= &pdispUrl
;
427 aParam
[1].vt
= VT_DISPATCH
| VT_BYREF
;
428 aParam
[0] = CComVariant( L
"file:///" );
430 hr
= ExecuteFunc( pdispTransformer
, L
"parseSmart", aParam
, 2, &dummyResult
);
431 if( !SUCCEEDED( hr
) || dummyResult
.vt
!= VT_BOOL
|| !dummyResult
.boolVal
) return hr
;
436 HRESULT
CSOActiveX::SetLayoutManagerProps()
441 CComVariant pVarLayoutMgr
;
442 OLECHAR
const * sLMPropName
= L
"LayoutManager";
443 HRESULT hr
= GetPropertiesFromIDisp( mpDispFrame
, &sLMPropName
, &pVarLayoutMgr
, 1 );
444 if( pVarLayoutMgr
.vt
!= VT_DISPATCH
|| pVarLayoutMgr
.pdispVal
== nullptr )
447 CComPtr
<IDispatch
> pdispLM( pVarLayoutMgr
.pdispVal
);
450 if( !SUCCEEDED( hr
) || !pdispLM
)
453 OLECHAR
const * sATName
= L
"AutomaticToolbars";
455 pATProp
.vt
= VT_BOOL
; pATProp
.boolVal
= VARIANT_FALSE
;
456 hr
= PutPropertiesToIDisp( pdispLM
, &sATName
, &pATProp
, 1 );
461 HRESULT
CSOActiveX::CreateFrameOldWay( HWND hwnd
, int width
, int height
)
466 // create window handle holder
467 CComPtr
< CComObject
< SOComWindowPeer
> > pPeerToSend
= new CComObject
<SOComWindowPeer
>();
468 pPeerToSend
->SetHWNDInternally( hwnd
);
469 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispToSend( pPeerToSend
);
471 // create rectangle structure
472 CComPtr
<IDispatch
> pdispRectangle
;
473 HRESULT hr
= GetUnoStruct( L
"com.sun.star.awt.Rectangle", pdispRectangle
);
474 if( !SUCCEEDED( hr
) ) return hr
;
476 OLECHAR
const * sRectMemberNames
[4] = { L
"X",
480 CComVariant pRectVariant
[4];
481 pRectVariant
[0] = pRectVariant
[1] = pRectVariant
[2] = pRectVariant
[3] = CComVariant( 0 );
483 hr
= PutPropertiesToIDisp( pdispRectangle
, sRectMemberNames
, pRectVariant
, 4 );
484 if( !SUCCEEDED( hr
) ) return hr
;
486 // create WindowDescriptor structure
487 CComPtr
<IDispatch
> pdispWinDescr
;
488 hr
= GetUnoStruct( L
"com.sun.star.awt.WindowDescriptor", pdispWinDescr
);
489 if( !SUCCEEDED( hr
) ) return hr
;
491 // fill in descriptor with info
492 OLECHAR
const * sDescriptorMemberNames
[6] = { L
"Type",
493 L
"WindowServiceName",
497 L
"WindowAttributes" };
498 CComVariant pDescriptorVar
[6];
499 pDescriptorVar
[0] = CComVariant( 0 );
500 pDescriptorVar
[1] = CComVariant( L
"workwindow" );
501 pDescriptorVar
[2] = CComVariant( 1 );
502 pDescriptorVar
[3] = CComVariant( pIDispToSend
);
503 pDescriptorVar
[4] = CComVariant( pdispRectangle
);
504 pDescriptorVar
[5] = CComVariant( 33 );
505 hr
= PutPropertiesToIDisp( pdispWinDescr
, sDescriptorMemberNames
, pDescriptorVar
, 6 );
506 if( !SUCCEEDED( hr
) ) return hr
;
508 // create XToolkit instance
509 CComPtr
<IDispatch
> pdispToolkit
;
510 CComVariant
aServiceName( L
"com.sun.star.awt.Toolkit" );
511 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, pdispToolkit
);
512 if( !SUCCEEDED( hr
) ) return hr
;
514 // create window with toolkit
515 CComVariant
aWinDescr( pdispWinDescr
);
516 hr
= GetIDispByFunc( pdispToolkit
, L
"createWindow", &aWinDescr
, 1, mpDispWin
);
517 if( !SUCCEEDED( hr
) ) return hr
;
520 aServiceName
= CComVariant( L
"com.sun.star.frame.Task" );
521 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpDispFrame
);
522 if( !SUCCEEDED( hr
) || !mpDispFrame
)
524 // the interface com.sun.star.frame.Task is removed in 6.1
525 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
526 aServiceName
= CComVariant( L
"com.sun.star.frame.Frame" );
527 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpDispFrame
);
528 if( !SUCCEEDED( hr
) ) return hr
;
532 CComVariant dummyResult
;
533 CComVariant
aDispWin( mpDispWin
);
534 hr
= ExecuteFunc( mpDispFrame
, L
"initialize", &aDispWin
, 1, &dummyResult
);
535 if( !SUCCEEDED( hr
) ) return hr
;
537 // set some properties to the layout manager, ignore errors for now
538 SetLayoutManagerProps();
541 CComPtr
<IDispatch
> pdispDesktop
;
542 aServiceName
= CComVariant( L
"com.sun.star.frame.Desktop" );
543 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, pdispDesktop
);
544 if( !SUCCEEDED( hr
) ) return hr
;
546 // create tree of frames
547 CComPtr
<IDispatch
> pdispChildren
;
548 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", nullptr, 0, pdispChildren
);
549 if( !SUCCEEDED( hr
) ) return hr
;
551 // insert new frame into desktop hierarchy
552 CComVariant
aDispFrame( mpDispFrame
);
553 hr
= ExecuteFunc( pdispChildren
, L
"append", &aDispFrame
, 1, &dummyResult
);
554 if( !SUCCEEDED( hr
) ) return hr
;
557 CComVariant
aTransparent( long(0xFFFFFFFF) );
558 hr
= ExecuteFunc( mpDispWin
, L
"setBackground", &aTransparent
, 1, &dummyResult
);
559 if( !SUCCEEDED( hr
) ) return hr
;
561 CComVariant
aTrue( TRUE
);
562 hr
= ExecuteFunc( mpDispWin
, L
"setVisible", &aTrue
, 1, &dummyResult
);
563 if( !SUCCEEDED( hr
) ) return hr
;
565 CComVariant aPosArgs
[5];
566 aPosArgs
[4] = CComVariant( 0 );
567 aPosArgs
[3] = CComVariant( 0 );
568 aPosArgs
[2] = CComVariant( width
);
569 aPosArgs
[1] = CComVariant( height
);
570 aPosArgs
[0] = CComVariant( 12 );
571 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
572 if( !SUCCEEDED( hr
) ) return hr
;
574 // create frame locker if there is such service
575 aServiceName
= CComVariant( L
"com.sun.star.embed.InstanceLocker" );
576 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpInstanceLocker
);
577 if( SUCCEEDED( hr
) && mpInstanceLocker
)
579 SAFEARRAY
* pInitVals
= SafeArrayCreateVector(VT_VARIANT
, 0, 3);
581 // the first sequence element
583 CComVariant
pFrameVariant( mpDispFrame
);
584 SafeArrayPutElement( pInitVals
, &nInitInd
, &pFrameVariant
);
586 // the second sequence element
588 CComVariant
pStrArr( 1 );
589 SafeArrayPutElement( pInitVals
, &nInitInd
, &pStrArr
);
591 // the third sequence element
593 CComPtr
<IDispatch
> pdispValueObj
;
594 hr
= GetIDispByFunc( mpDispFactory
, L
"Bridge_GetValueObject", nullptr, 0, pdispValueObj
);
595 if( !SUCCEEDED( hr
) || !pdispValueObj
) return hr
;
597 CComVariant aValueArgs
[2];
598 aValueArgs
[1] = CComVariant( L
"com.sun.star.embed.XActionsApproval" );
599 CComPtr
< CComObject
< SOActionsApproval
> > pApproval( new CComObject
<SOActionsApproval
>() );
600 aValueArgs
[0] = CComVariant ( pApproval
);
602 hr
= ExecuteFunc( pdispValueObj
, L
"Set", aValueArgs
, 2, &dummyResult
);
603 if( !SUCCEEDED( hr
) ) return hr
;
605 CComVariant
aValueObj( pdispValueObj
);
606 SafeArrayPutElement( pInitVals
, &nInitInd
, &aValueObj
);
608 // execute initialize()
609 CComVariant aVarInitVals
;
610 aVarInitVals
.vt
= VT_ARRAY
| VT_VARIANT
; aVarInitVals
.parray
= pInitVals
;
611 hr
= ExecuteFunc( mpInstanceLocker
, L
"initialize", &aVarInitVals
, 1, &dummyResult
);
612 if( !SUCCEEDED( hr
) ) return hr
;
618 HRESULT
CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR
const * sUrl
, OLECHAR
const * sArgName
, BOOL sArgVal
)
620 SAFEARRAY
* pPropVals
= SafeArrayCreateVector(VT_DISPATCH
, 0, 1);
622 CComPtr
<IDispatch
> pdispPropVal
;
623 HRESULT hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
624 if( !SUCCEEDED( hr
) ) return hr
;
626 OLECHAR
const * sPropMemberNames
[2] = { L
"Name", L
"Value" };
627 CComVariant pPropVar
[2];
628 pPropVar
[0] = CComVariant( sArgName
);
629 pPropVar
[1].vt
= VT_BOOL
; pPropVar
[1].boolVal
= sArgVal
? VARIANT_TRUE
: VARIANT_FALSE
;
630 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
631 if( !SUCCEEDED( hr
) ) return hr
;
633 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
635 CComVariant aDispArgs
[4];
636 aDispArgs
[3] = CComVariant( sUrl
);
637 aDispArgs
[2] = CComVariant( L
"_self" );
638 aDispArgs
[1] = CComVariant( 0 );
639 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
640 aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
642 CComVariant dummyResult
;
643 hr
= ExecuteFunc( mpDispFrame
, L
"loadComponentFromURL", aDispArgs
, 4, &dummyResult
);
644 if( !SUCCEEDED( hr
) ) return hr
;
649 HRESULT
CSOActiveX::CallDispatchMethod( OLECHAR
const * sUrl
,
650 CComVariant
* aArgNames
,
651 CComVariant
* aArgVals
,
654 CComPtr
<IDispatch
> pdispURL
;
655 HRESULT hr
= GetUrlStruct( sUrl
, pdispURL
);
656 if( !SUCCEEDED( hr
) ) return hr
;
658 CComPtr
<IDispatch
> pdispXDispatch
;
659 CComVariant aArgs
[3];
660 aArgs
[2] = CComVariant( pdispURL
);
661 aArgs
[1] = CComVariant( L
"" );
662 aArgs
[0] = CComVariant( int(0) );
663 hr
= GetIDispByFunc( mpDispFrame
,
668 if( !SUCCEEDED( hr
) ) return hr
;
670 SAFEARRAY
* pPropVals
= SafeArrayCreateVector(VT_DISPATCH
, 0, count
);
671 for( LONG ix
= 0; ix
< static_cast<LONG
>(count
); ix
++ )
673 CComPtr
<IDispatch
> pdispPropVal
;
674 hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
675 if( !SUCCEEDED( hr
) ) return hr
;
677 OLECHAR
const * sPropMemberNames
[2] = { L
"Name", L
"Value" };
678 CComVariant pPropVar
[2];
679 pPropVar
[0] = aArgNames
[ix
];
680 pPropVar
[1] = aArgVals
[ix
];
681 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
682 if( !SUCCEEDED( hr
) ) return hr
;
684 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
687 CComVariant aDispArgs
[2];
688 aDispArgs
[1] = CComVariant( pdispURL
);
689 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
690 aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
692 CComVariant dummyResult
;
693 hr
= ExecuteFunc( pdispXDispatch
, L
"dispatch", aDispArgs
, 2, &dummyResult
);
694 if( !SUCCEEDED( hr
) ) return hr
;
699 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback
<CSOActiveX
>* /*pbsc*/, BYTE
* pBytes
, DWORD dwSize
)
701 if ( mbReadyForActivation
)
704 bool bSuccess
= false;
705 bool bFinishDownload
= false;
708 // means the download is finished, dwSize contains hresult
709 bFinishDownload
= true;
710 if ( SUCCEEDED( dwSize
) )
717 if ( !mpDispTempFile
)
719 CComVariant
aServiceName( L
"com.sun.star.io.TempFile" );
720 hr
= GetIDispByFunc( mpDispFactory
,
727 if( SUCCEEDED( hr
) && mpDispTempFile
)
729 SAFEARRAY
* pDataArray
= SafeArrayCreateVector(VT_I1
, 0, dwSize
);
733 hr
= SafeArrayLock( pDataArray
);
734 if ( SUCCEEDED( hr
) )
736 for( DWORD ix
= 0; ix
< dwSize
; ix
++ )
737 static_cast<BYTE
*>(pDataArray
->pvData
)[ix
] = pBytes
[ix
];
738 hr
= SafeArrayUnlock( pDataArray
);
739 if ( SUCCEEDED( hr
) )
741 CComVariant aArgs
[1];
742 aArgs
[0].vt
= VT_ARRAY
| VT_I1
; aArgs
[0].parray
= pDataArray
;
743 CComVariant dummyResult
;
744 hr
= ExecuteFunc( mpDispTempFile
, L
"writeBytes", aArgs
, 1, &dummyResult
);
745 if( SUCCEEDED( hr
) )
755 // the download failed, let StarOffice download
756 bFinishDownload
= true;
757 mpDispTempFile
= CComPtr
< IDispatch
>();
760 if ( bFinishDownload
)
762 // trigger the loading now
764 mbReadyForActivation
= TRUE
;
771 HRESULT
CSOActiveX::LoadURLToFrame( )
773 CComVariant aArgNames
[4] = { L
"ReadOnly", L
"ViewOnly", L
"AsTemplate", L
"InputStream" };
774 CComVariant aArgVals
[4];
775 unsigned int nCount
= 3; // the 4-th argument is used only if the stream can be retrieved
777 aArgVals
[0].vt
= VT_BOOL
; aArgVals
[0].boolVal
= mbViewOnly
? VARIANT_TRUE
: VARIANT_FALSE
;
778 aArgVals
[1].vt
= VT_BOOL
; aArgVals
[1].boolVal
= mbViewOnly
? VARIANT_TRUE
: VARIANT_FALSE
;
779 aArgVals
[2].vt
= VT_BOOL
; aArgVals
[2].boolVal
= VARIANT_FALSE
;
781 if ( mpDispTempFile
)
783 aArgVals
[3] = CComVariant( mpDispTempFile
);
787 HRESULT hr
= CallDispatchMethod( mCurFileUrl
, aArgNames
, aArgVals
, nCount
);
788 if( !SUCCEEDED( hr
) ) return hr
;
790 // try to get the model and set the presentation specific property, the setting will fail for other document formats
791 CComPtr
<IDispatch
> pdispController
;
792 hr
= GetIDispByFunc( mpDispFrame
, L
"getController", nullptr, 0, pdispController
);
793 if ( SUCCEEDED( hr
) && pdispController
)
795 CComPtr
<IDispatch
> pdispModel
;
796 hr
= GetIDispByFunc( pdispController
, L
"getModel", nullptr, 0, pdispModel
);
797 if ( SUCCEEDED( hr
) && pdispModel
)
799 CComPtr
<IDispatch
> pdispPres
;
800 hr
= GetIDispByFunc( pdispModel
, L
"getPresentation", nullptr, 0, pdispPres
);
801 if ( SUCCEEDED( hr
) && pdispPres
)
803 // this is a presentation
804 // let the slide show be shown in the document window
805 OLECHAR
const * pPropName
= L
"IsFullScreen";
806 CComVariant pPresProp
;
807 pPresProp
.vt
= VT_BOOL
; pPresProp
.boolVal
= VARIANT_FALSE
;
808 hr
= PutPropertiesToIDisp( pdispPres
, &pPropName
, &pPresProp
, 1 );
810 // start the slide show
811 if ( SUCCEEDED( hr
) )
813 CComVariant dummyResult
;
814 ExecuteFunc( pdispPres
, L
"Start", nullptr, 0, &dummyResult
);
820 // create dispatch interceptor
821 mpDispatchInterceptor
= new CComObject
< SODispatchInterceptor
>();
822 mpDispatchInterceptor
->AddRef();
823 mpDispatchInterceptor
->SetParent( this );
824 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispDispInter( mpDispatchInterceptor
);
826 // register dispatch interceptor in the frame
827 CComVariant
aDispVariant( pIDispDispInter
);
828 CComVariant dummyResult
;
829 hr
= ExecuteFunc( mpDispFrame
,
830 L
"registerDispatchProviderInterceptor",
835 if( !SUCCEEDED( hr
) ) return hr
;
840 SOVersion
CSOActiveX::GetVersionConnected()
842 SOVersion bResult
= SO_NOT_DETECTED
;
845 // create ConfigurationProvider instance
846 CComPtr
<IDispatch
> pdispConfProv
;
847 CComVariant
aServiceName( L
"com.sun.star.configuration.ConfigurationProvider" );
848 HRESULT hr
= GetIDispByFunc( mpDispFactory
,
854 if( SUCCEEDED( hr
) && pdispConfProv
)
856 CComPtr
<IDispatch
> pdispConfAccess
;
858 SAFEARRAY
* pInitParams
= SafeArrayCreateVector( VT_VARIANT
, 0, 1 );
863 CComVariant
aConfPath( L
"org.openoffice.Setup" );
864 SafeArrayPutElement( pInitParams
, &ix
, &aConfPath
);
866 CComVariant aArgs
[2];
867 aArgs
[1] = CComVariant( L
"com.sun.star.configuration.ConfigurationAccess" );
868 aArgs
[0].vt
= VT_ARRAY
| VT_VARIANT
; aArgs
[0].parray
= pInitParams
;
870 hr
= GetIDispByFunc( pdispConfProv
,
871 L
"createInstanceWithArguments",
876 if( SUCCEEDED( hr
) && pdispConfAccess
)
878 CComVariant aOfficeName
;
880 CComVariant
aProductName( L
"Product/ooName" );
881 hr
= ExecuteFunc( pdispConfAccess
,
882 L
"getByHierarchicalName",
887 if( SUCCEEDED( hr
) && aOfficeName
.vt
== VT_BSTR
)
889 CComVariant aOfficeVersion
;
891 CComVariant
aProductVersion( L
"Product/ooSetupVersion" );
892 hr
= ExecuteFunc( pdispConfAccess
,
893 L
"getByHierarchicalName",
898 if( SUCCEEDED( hr
) && aOfficeVersion
.vt
== VT_BSTR
)
900 if (!wcscmp(aOfficeName
.bstrVal
, L
"StarOffice"))
902 if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"6.1", 3))
904 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"6.0", 3))
906 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"5.2", 3))
909 bResult
= SO_UNKNOWN
;
913 if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"1.1", 3))
915 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"1.0", 3))
918 bResult
= OO_UNKNOWN
;
936 explicit LockingGuard( bool& bLocked
)
937 : mbLocked( bLocked
)
950 HRESULT
CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO
& di
)
952 // This method is called only in main thread, no need to lock it
954 // Get read of reentrance problems
957 LockingGuard
aGuard( mbDrawLocked
);
959 if( m_spInPlaceSite
&& mCurFileUrl
&& mbReadyForActivation
)
962 HRESULT hr
= m_spInPlaceSite
->GetWindow( &hwnd
);
963 if( !SUCCEEDED( hr
) ) return hr
;
965 if( mParentWin
!= hwnd
|| !mOffWin
)
969 CComVariant dummyResult
;
970 CComVariant aPropVar
;
971 aPropVar
.vt
= VT_BOOL
; aPropVar
.boolVal
= VARIANT_FALSE
;
972 (void) ExecuteFunc( mpDispFrame
, L
"close", &aPropVar
, 1, &dummyResult
);
973 mpDispFrame
= CComPtr
<IDispatch
>();
977 mOffWin
= CreateWindowW(
978 STAROFFICE_WINDOWCLASS
,
980 WS_CHILD
| WS_CLIPCHILDREN
| WS_BORDER
,
983 di
.prcBounds
->right
- di
.prcBounds
->left
,
984 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
990 ::ShowWindow( mOffWin
, SW_SHOW
);
995 ::GetWindowRect( mOffWin
, &aRect
);
997 if( aRect
.left
!= di
.prcBounds
->left
|| aRect
.top
!= di
.prcBounds
->top
998 || aRect
.right
!= di
.prcBounds
->right
|| aRect
.bottom
!= di
.prcBounds
->bottom
)
1000 // on this state the office window should exist already
1001 ::SetWindowPos( mOffWin
,
1005 di
.prcBounds
->right
- di
.prcBounds
->left
,
1006 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
1009 CComVariant aPosArgs
[5];
1010 aPosArgs
[4] = CComVariant( 0 );
1011 aPosArgs
[3] = CComVariant( 0 );
1012 aPosArgs
[2] = CComVariant( int(di
.prcBounds
->right
- di
.prcBounds
->left
) );
1013 aPosArgs
[1] = CComVariant( int(di
.prcBounds
->bottom
- di
.prcBounds
->top
) );
1014 aPosArgs
[0] = CComVariant( 12 );
1015 CComVariant dummyResult
;
1016 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
1017 if( !SUCCEEDED( hr
) ) return hr
;
1021 if (mnVersion
== SO_NOT_DETECTED
)
1023 OutputError_Impl( mOffWin
, CS_E_INVALID_VERSION
);
1029 hr
= CreateFrameOldWay( mOffWin
,
1030 di
.prcBounds
->right
- di
.prcBounds
->left
,
1031 di
.prcBounds
->bottom
- di
.prcBounds
->top
);
1033 if( !SUCCEEDED( hr
) )
1035 // if the frame can not be opened do not try any more
1036 mbReadyForActivation
= FALSE
;
1037 OutputError_Impl( mOffWin
, STG_E_ABNORMALAPIEXIT
);
1044 hr
= LoadURLToFrame();
1047 if( !SUCCEEDED( hr
) )
1049 // if the document can not be opened do not try any more
1050 mbReadyForActivation
= FALSE
;
1052 OutputError_Impl( mOffWin
, STG_E_ABNORMALAPIEXIT
);
1060 // activate the fallback
1061 CComControl
<CSOActiveX
>::OnDrawAdvanced( di
);
1067 HRESULT
CSOActiveX::OnDraw( ATL_DRAWINFO
& di
)
1069 // fallback that is activated by the parent class
1071 FillRect( di
.hdcDraw
, reinterpret_cast<RECT
const *>(di
.prcBounds
), reinterpret_cast<HBRUSH
>(COLOR_BACKGROUND
) );
1076 COM_DECLSPEC_NOTHROW STDMETHODIMP
CSOActiveX::SetClientSite( IOleClientSite
* aClientSite
)
1078 HRESULT hr
= IOleObjectImpl
<CSOActiveX
>::SetClientSite( aClientSite
);
1082 //ATLASSERT( mWebBrowser2 );
1084 AtlUnadvise( mWebBrowser2
, DIID_DWebBrowserEvents2
, mCookie
);
1088 CComPtr
<IOleContainer
> aContainer
;
1089 m_spClientSite
->GetContainer( &aContainer
);
1090 // ATLASSERT( aContainer );
1092 if( SUCCEEDED( hr
) && aContainer
)
1094 CComQIPtr
<IServiceProvider
, &IID_IServiceProvider
> aServiceProvider( aContainer
);
1095 //ATLASSERT( aServiceProvider );
1097 if( aServiceProvider
)
1099 aServiceProvider
->QueryService( SID_SInternetExplorer
,
1101 reinterpret_cast<void**>(&mWebBrowser2
) );
1102 // ATLASSERT( mWebBrowser2 );
1104 AtlAdvise( mWebBrowser2
, GetUnknown(), DIID_DWebBrowserEvents2
, &mCookie
);
1111 COM_DECLSPEC_NOTHROW STDMETHODIMP
CSOActiveX::Invoke(DISPID dispidMember
,
1115 DISPPARAMS
* pDispParams
,
1116 VARIANT
* pvarResult
,
1117 EXCEPINFO
* pExcepInfo
,
1120 if (riid
!= IID_NULL
)
1121 return DISP_E_UNKNOWNINTERFACE
;
1124 return DISP_E_PARAMNOTOPTIONAL
;
1126 if ( dispidMember
== DISPID_ONQUIT
)
1129 IDispatchImpl
<ISOActiveX
, &IID_ISOActiveX
,
1130 &LIBID_SO_ACTIVEXLib
>::Invoke(
1131 dispidMember
, riid
, lcid
, wFlags
, pDispParams
,
1132 pvarResult
, pExcepInfo
, puArgErr
);
1137 HRESULT
CSOActiveX::GetURL( const OLECHAR
* url
,
1138 const OLECHAR
* target
)
1140 CComVariant aEmpty1
, aEmpty2
, aEmpty3
;
1141 CComVariant
aUrl( url
);
1142 CComVariant aTarget
;
1144 aTarget
= CComVariant( target
);
1146 return mWebBrowser2
->Navigate2( &aUrl
,
1154 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */