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 "SOActiveX.h"
24 #include "SOComWindowPeer.h"
25 #include "SODispatchInterceptor.h"
26 #include "SOActionsApproval.h"
27 #include "com_uno_helper.h"
30 #pragma clang diagnostic push
31 #pragma clang diagnostic ignored "-Wnon-virtual-dtor"
33 #include <so_activex.h>
35 #pragma clang diagnostic pop
38 #define STAROFFICE_WINDOWCLASS L"SOParentWindow"
41 static void OutputError_Impl( HWND hw
, HRESULT ErrorCode
)
43 LPWSTR sMessage
= nullptr;
45 FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
,
48 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), // Default language
49 reinterpret_cast<LPWSTR
>(&sMessage
),
53 MessageBoxW( hw
, sMessage
, nullptr, MB_OK
| MB_ICONINFORMATION
);
54 HeapFree( GetProcessHeap(), 0, sMessage
);
57 HRESULT
ExecuteFunc( IDispatch
* idispUnoObject
,
58 OLECHAR
const * sFuncName
,
61 CComVariant
* pResult
)
67 HRESULT hr
= idispUnoObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sFuncName
), 1, LOCALE_USER_DEFAULT
, &id
);
68 if( !SUCCEEDED( hr
) ) return hr
;
70 DISPPARAMS dispparams
= { params
, nullptr, count
, 0};
74 hr
= idispUnoObject
->Invoke( id
, IID_NULL
,LOCALE_USER_DEFAULT
, DISPATCH_METHOD
,
75 &dispparams
, pResult
, &myInfo
, nullptr);
77 // for debugging purposes
79 // if ( !SUCCEEDED( hr ) )
80 // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
85 static HRESULT
GetIDispByFunc( IDispatch
* idispUnoObject
,
86 OLECHAR
const * sFuncName
,
89 CComPtr
<IDispatch
>& pdispResult
)
95 HRESULT hr
= ExecuteFunc( idispUnoObject
, sFuncName
, params
, count
, &result
);
96 if( !SUCCEEDED( hr
) ) return hr
;
98 if( result
.vt
!= VT_DISPATCH
|| result
.pdispVal
== nullptr )
101 pdispResult
= CComPtr
<IDispatch
>( result
.pdispVal
);
106 static HRESULT
PutPropertiesToIDisp( IDispatch
* pdispObject
,
107 OLECHAR
const ** sMemberNames
,
108 CComVariant
* pVariant
,
111 for( unsigned int ind
= 0; ind
< count
; ind
++ )
114 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sMemberNames
[ind
]), 1, LOCALE_USER_DEFAULT
, &id
);
115 if( !SUCCEEDED( hr
) ) return hr
;
117 hr
= CComDispatchDriver::PutProperty( pdispObject
, id
, &pVariant
[ind
] );
118 if( !SUCCEEDED( hr
) ) return hr
;
124 HRESULT
GetPropertiesFromIDisp( IDispatch
* pdispObject
,
125 OLECHAR
const ** sMemberNames
,
126 CComVariant
* pVariant
,
129 for( unsigned int ind
= 0; ind
< count
; ind
++ )
132 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sMemberNames
[ind
]), 1, LOCALE_USER_DEFAULT
, &id
);
133 if( !SUCCEEDED( hr
) ) return hr
;
135 hr
= CComDispatchDriver::GetProperty( pdispObject
, id
, &pVariant
[ind
] );
136 if( !SUCCEEDED( hr
) ) return hr
;
144 CSOActiveX::CSOActiveX()
146 , mCurFileUrl( L
"private:factory/swriter" )
149 , mParentWin( nullptr )
151 , mpDispatchInterceptor( nullptr )
152 , mnVersion( SO_NOT_DETECTED
)
153 , mbReadyForActivation( FALSE
)
154 , mbDrawLocked( FALSE
)
156 CLSID
const clsFactory
= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
157 HRESULT hr
= CoCreateInstance( clsFactory
, nullptr, CLSCTX_ALL
, __uuidof(IDispatch
), reinterpret_cast<void**>(&mpDispFactory
));
158 if( !SUCCEEDED( hr
) )
159 OutputError_Impl( nullptr, hr
);
161 mPWinClass
.style
= CS_HREDRAW
|CS_VREDRAW
;
162 mPWinClass
.lpfnWndProc
= DefWindowProcW
;
163 mPWinClass
.cbClsExtra
= 0;
164 mPWinClass
.cbWndExtra
= 0;
165 mPWinClass
.hInstance
= GetModuleHandleW(nullptr); //myInstance;
166 mPWinClass
.hIcon
= nullptr;
167 mPWinClass
.hCursor
= nullptr;
168 mPWinClass
.hbrBackground
= reinterpret_cast<HBRUSH
>(COLOR_BACKGROUND
);
169 mPWinClass
.lpszMenuName
= nullptr;
170 mPWinClass
.lpszClassName
= STAROFFICE_WINDOWCLASS
;
172 RegisterClassW(&mPWinClass
);
175 CSOActiveX::~CSOActiveX()
181 HRESULT
CSOActiveX::Cleanup()
183 CComVariant dummyResult
;
185 if( mpDispatchInterceptor
)
189 // remove dispatch interceptor
190 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispDispInter( mpDispatchInterceptor
);
191 CComVariant
aVariant( pIDispDispInter
);
192 ExecuteFunc( mpDispFrame
,
193 L
"releaseDispatchProviderInterceptor",
199 mpDispatchInterceptor
->ClearParent();
200 mpDispatchInterceptor
->Release();
201 mpDispatchInterceptor
= nullptr;
204 mpDispTempFile
= CComPtr
< IDispatch
>();
205 mbReadyForActivation
= FALSE
;
207 if( mpInstanceLocker
)
209 ExecuteFunc( mpInstanceLocker
, L
"dispose", nullptr, 0, &dummyResult
);
210 mpInstanceLocker
= CComPtr
< IDispatch
>();
215 BOOL bCloserActivated
= FALSE
;
217 CComPtr
<IDispatch
> pDispDocumentCloser
;
218 CComVariant
aDocCloser( L
"com.sun.star.embed.DocumentCloser" );
219 HRESULT hr
= GetIDispByFunc( mpDispFactory
,
223 pDispDocumentCloser
);
224 if ( SUCCEEDED( hr
) && pDispDocumentCloser
)
226 SAFEARRAY FAR
* pInitFrame
= SafeArrayCreateVector( VT_VARIANT
, 0, 1 );
228 CComVariant
pFrameVariant( mpDispFrame
);
229 SafeArrayPutElement( pInitFrame
, &nInitInd
, &pFrameVariant
);
230 CComVariant aVarInitFrame
;
231 aVarInitFrame
.vt
= VT_ARRAY
| VT_VARIANT
; aVarInitFrame
.parray
= pInitFrame
;
232 hr
= ExecuteFunc( pDispDocumentCloser
, L
"initialize", &aVarInitFrame
, 1, &dummyResult
);
233 if( SUCCEEDED( hr
) )
235 // the following call will let the closing happen
236 hr
= ExecuteFunc( pDispDocumentCloser
, L
"dispose", nullptr, 0, &dummyResult
);
237 bCloserActivated
= SUCCEEDED( hr
);
241 if ( !bCloserActivated
)
243 CComVariant aPropVar
;
244 aPropVar
.vt
= VT_BOOL
; aPropVar
.boolVal
= VARIANT_TRUE
;
245 if ( !SUCCEEDED( ExecuteFunc( mpDispFrame
, L
"close", &aPropVar
, 1, &dummyResult
) ) )
246 ExecuteFunc( mpDispFrame
, L
"dispose", nullptr, 0, &dummyResult
);
249 mpDispFrame
= CComPtr
< IDispatch
>();
252 if( ::IsWindow( mOffWin
) )
253 ::DestroyWindow( mOffWin
);
260 HRESULT
CSOActiveX::TerminateOffice()
263 CComPtr
<IDispatch
> pdispDesktop
;
264 CComVariant
aDesktopServiceName( L
"com.sun.star.frame.Desktop" );
266 HRESULT hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aDesktopServiceName
, 1, pdispDesktop
);
267 if( !pdispDesktop
|| !SUCCEEDED( hr
) ) return hr
;
269 // create tree of frames
270 CComPtr
<IDispatch
> pdispChildren
;
271 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", nullptr, 0, pdispChildren
);
272 if( !pdispChildren
|| !SUCCEEDED( hr
) ) return hr
;
275 CComVariant
nFlag( 4 );
276 hr
= ExecuteFunc( pdispChildren
, L
"queryFrames", &nFlag
, 1, &aFrames
);
277 if ( SUCCEEDED( hr
) )
279 if ( ( aFrames
.vt
== ( VT_ARRAY
| VT_DISPATCH
) || aFrames
.vt
== ( VT_ARRAY
| VT_VARIANT
) )
280 && ( !aFrames
.parray
|| (aFrames
.parray
->cDims
== 1 && aFrames
.parray
->rgsabound
[0].cElements
== 0) ) )
282 // there is no frames open
283 // TODO: check whether the frames are hidden if they are open?
284 CComVariant dummyResult
;
285 hr
= ExecuteFunc( pdispDesktop
, L
"terminate", nullptr, 0, &dummyResult
);
292 STDMETHODIMP
CSOActiveX::InitNew ()
294 mnVersion
= GetVersionConnected();
299 STDMETHODIMP
CSOActiveX::Load ( LPSTREAM
/*pStm*/ )
301 mnVersion
= GetVersionConnected();
305 // for now just ignore
310 STDMETHODIMP
CSOActiveX::Load( LPPROPERTYBAG pPropBag
, LPERRORLOG
/*pErrorLog*/ )
312 mnVersion
= GetVersionConnected();
314 IPropertyBag2
* pPropBag2
;
315 HRESULT hr
= pPropBag
->QueryInterface( IID_IPropertyBag2
, reinterpret_cast<void**>(&pPropBag2
) );
316 //ATLASSERT( hr >= 0 );
318 if( !SUCCEEDED( hr
) )
322 hr
= pPropBag2
->CountProperties( &aNum
);
323 //ATLASSERT( hr >= 0 );
324 if( !SUCCEEDED( hr
) )
327 PROPBAG2
* aPropNames
= new PROPBAG2
[aNum
];
328 unsigned long aReaded
;
330 hr
= pPropBag2
->GetPropertyInfo( 0,
334 //ATLASSERT( hr >= 0 );
335 if( !SUCCEEDED( hr
) )
341 CComVariant
* aVal
= new CComVariant
[aNum
];
342 HRESULT
* hvs
= new HRESULT
[aNum
];
343 hr
= pPropBag2
->Read( aNum
,
348 //ATLASSERT( hr >= 0 );
349 if( !SUCCEEDED( hr
) )
357 for( unsigned long ind
= 0; ind
< aNum
; ind
++ )
359 // all information from the 'object' tag is in strings
360 if (aVal
[ind
].vt
== VT_BSTR
&& !wcscmp(aPropNames
[ind
].pstrName
, L
"src"))
362 mCurFileUrl
= wcsdup( aVal
[ind
].bstrVal
);
364 else if( aVal
[ind
].vt
== VT_BSTR
365 && !wcscmp(aPropNames
[ind
].pstrName
, L
"readonly"))
367 if (!wcscmp(aVal
[ind
].bstrVal
, L
"true"))
386 mbReadyForActivation
= FALSE
;
387 if (BSTR bStrUrl
= SysAllocString(mCurFileUrl
))
389 hr
= CBindStatusCallback
<CSOActiveX
>::Download(
390 this, &CSOActiveX::CallbackCreateXInputStream
, bStrUrl
, m_spClientSite
, FALSE
);
391 SysFreeString(bStrUrl
);
392 if (hr
== MK_S_ASYNCHRONOUS
)
398 if ( !SUCCEEDED( hr
) )
400 // trigger initialization without stream
410 HRESULT
CSOActiveX::GetUnoStruct( OLECHAR
const * sStructName
, CComPtr
<IDispatch
>& pdispResult
)
412 CComVariant
aComStruct( sStructName
);
413 return GetIDispByFunc( mpDispFactory
, L
"Bridge_GetStruct", &aComStruct
, 1, pdispResult
);
416 HRESULT
CSOActiveX::GetUrlStruct( OLECHAR
const * sUrl
, CComPtr
<IDispatch
>& pdispUrl
)
418 HRESULT hr
= GetUnoStruct( L
"com.sun.star.util.URL", pdispUrl
);
419 if( !SUCCEEDED( hr
) ) return hr
;
421 OLECHAR
const * sURLMemberName
= L
"Complete";
423 hr
= pdispUrl
->GetIDsOfNames( IID_NULL
, const_cast<OLECHAR
**>(&sURLMemberName
), 1, LOCALE_USER_DEFAULT
, &nURLID
);
424 if( !SUCCEEDED( hr
) ) return hr
;
425 CComVariant
aComUrl( sUrl
);
426 hr
= CComDispatchDriver::PutProperty( pdispUrl
, nURLID
, &aComUrl
);
427 if( !SUCCEEDED( hr
) ) return hr
;
429 CComPtr
<IDispatch
> pdispTransformer
;
430 CComVariant
aServiceName( L
"com.sun.star.util.URLTransformer" );
431 hr
= GetIDispByFunc( mpDispFactory
,
436 if( !SUCCEEDED( hr
) ) return hr
;
438 CComVariant dummyResult
;
439 CComVariant aParam
[2];
440 aParam
[1].ppdispVal
= &pdispUrl
;
441 aParam
[1].vt
= VT_DISPATCH
| VT_BYREF
;
442 aParam
[0] = CComVariant( L
"file:///" );
444 hr
= ExecuteFunc( pdispTransformer
, L
"parseSmart", aParam
, 2, &dummyResult
);
445 if( !SUCCEEDED( hr
) || dummyResult
.vt
!= VT_BOOL
|| !dummyResult
.boolVal
) return hr
;
450 HRESULT
CSOActiveX::SetLayoutManagerProps()
455 CComVariant pVarLayoutMgr
;
456 OLECHAR
const * sLMPropName
= L
"LayoutManager";
457 HRESULT hr
= GetPropertiesFromIDisp( mpDispFrame
, &sLMPropName
, &pVarLayoutMgr
, 1 );
458 if( pVarLayoutMgr
.vt
!= VT_DISPATCH
|| pVarLayoutMgr
.pdispVal
== nullptr )
461 CComPtr
<IDispatch
> pdispLM( pVarLayoutMgr
.pdispVal
);
464 if( !SUCCEEDED( hr
) || !pdispLM
)
467 OLECHAR
const * sATName
= L
"AutomaticToolbars";
469 pATProp
.vt
= VT_BOOL
; pATProp
.boolVal
= VARIANT_FALSE
;
470 hr
= PutPropertiesToIDisp( pdispLM
, &sATName
, &pATProp
, 1 );
475 HRESULT
CSOActiveX::CreateFrameOldWay( HWND hwnd
, int width
, int height
)
480 // create window handle holder
481 CComPtr
< CComObject
< SOComWindowPeer
> > pPeerToSend
= new CComObject
<SOComWindowPeer
>();
482 pPeerToSend
->SetHWNDInternally( hwnd
);
483 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispToSend( pPeerToSend
);
485 // create rectangle structure
486 CComPtr
<IDispatch
> pdispRectangle
;
487 HRESULT hr
= GetUnoStruct( L
"com.sun.star.awt.Rectangle", pdispRectangle
);
488 if( !SUCCEEDED( hr
) ) return hr
;
490 OLECHAR
const * sRectMemberNames
[4] = { L
"X",
494 CComVariant pRectVariant
[4];
495 pRectVariant
[0] = pRectVariant
[1] = pRectVariant
[2] = pRectVariant
[3] = CComVariant( 0 );
497 hr
= PutPropertiesToIDisp( pdispRectangle
, sRectMemberNames
, pRectVariant
, 4 );
498 if( !SUCCEEDED( hr
) ) return hr
;
500 // create WindowDescriptor structure
501 CComPtr
<IDispatch
> pdispWinDescr
;
502 hr
= GetUnoStruct( L
"com.sun.star.awt.WindowDescriptor", pdispWinDescr
);
503 if( !SUCCEEDED( hr
) ) return hr
;
505 // fill in descriptor with info
506 OLECHAR
const * sDescriptorMemberNames
[6] = { L
"Type",
507 L
"WindowServiceName",
511 L
"WindowAttributes" };
512 CComVariant pDescriptorVar
[6];
513 pDescriptorVar
[0] = CComVariant( 0 );
514 pDescriptorVar
[1] = CComVariant( L
"workwindow" );
515 pDescriptorVar
[2] = CComVariant( 1 );
516 pDescriptorVar
[3] = CComVariant( pIDispToSend
);
517 pDescriptorVar
[4] = CComVariant( pdispRectangle
);
518 pDescriptorVar
[5] = CComVariant( 33 );
519 hr
= PutPropertiesToIDisp( pdispWinDescr
, sDescriptorMemberNames
, pDescriptorVar
, 6 );
520 if( !SUCCEEDED( hr
) ) return hr
;
522 // create XToolkit instance
523 CComPtr
<IDispatch
> pdispToolkit
;
524 CComVariant
aServiceName( L
"com.sun.star.awt.Toolkit" );
525 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, pdispToolkit
);
526 if( !SUCCEEDED( hr
) ) return hr
;
528 // create window with toolkit
529 CComVariant
aWinDescr( pdispWinDescr
);
530 hr
= GetIDispByFunc( pdispToolkit
, L
"createWindow", &aWinDescr
, 1, mpDispWin
);
531 if( !SUCCEEDED( hr
) ) return hr
;
534 aServiceName
= CComVariant( L
"com.sun.star.frame.Task" );
535 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpDispFrame
);
536 if( !SUCCEEDED( hr
) || !mpDispFrame
)
538 // the interface com.sun.star.frame.Task is removed in 6.1
539 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
540 aServiceName
= CComVariant( L
"com.sun.star.frame.Frame" );
541 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpDispFrame
);
542 if( !SUCCEEDED( hr
) ) return hr
;
546 CComVariant dummyResult
;
547 CComVariant
aDispWin( mpDispWin
);
548 hr
= ExecuteFunc( mpDispFrame
, L
"initialize", &aDispWin
, 1, &dummyResult
);
549 if( !SUCCEEDED( hr
) ) return hr
;
551 // set some properties to the layout manager, ignore errors for now
552 SetLayoutManagerProps();
555 CComPtr
<IDispatch
> pdispDesktop
;
556 aServiceName
= CComVariant( L
"com.sun.star.frame.Desktop" );
557 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, pdispDesktop
);
558 if( !SUCCEEDED( hr
) ) return hr
;
560 // create tree of frames
561 CComPtr
<IDispatch
> pdispChildren
;
562 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", nullptr, 0, pdispChildren
);
563 if( !SUCCEEDED( hr
) ) return hr
;
565 // insert new frame into desktop hierarchy
566 CComVariant
aDispFrame( mpDispFrame
);
567 hr
= ExecuteFunc( pdispChildren
, L
"append", &aDispFrame
, 1, &dummyResult
);
568 if( !SUCCEEDED( hr
) ) return hr
;
571 CComVariant
aTransparent( long(0xFFFFFFFF) );
572 hr
= ExecuteFunc( mpDispWin
, L
"setBackground", &aTransparent
, 1, &dummyResult
);
573 if( !SUCCEEDED( hr
) ) return hr
;
575 CComVariant
aTrue( TRUE
);
576 hr
= ExecuteFunc( mpDispWin
, L
"setVisible", &aTrue
, 1, &dummyResult
);
577 if( !SUCCEEDED( hr
) ) return hr
;
579 CComVariant aPosArgs
[5];
580 aPosArgs
[4] = CComVariant( 0 );
581 aPosArgs
[3] = CComVariant( 0 );
582 aPosArgs
[2] = CComVariant( width
);
583 aPosArgs
[1] = CComVariant( height
);
584 aPosArgs
[0] = CComVariant( 12 );
585 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
586 if( !SUCCEEDED( hr
) ) return hr
;
588 // create frame locker if there is such service
589 aServiceName
= CComVariant( L
"com.sun.star.embed.InstanceLocker" );
590 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &aServiceName
, 1, mpInstanceLocker
);
591 if( SUCCEEDED( hr
) && mpInstanceLocker
)
593 SAFEARRAY FAR
* pInitVals
= SafeArrayCreateVector( VT_VARIANT
, 0, 3 );
595 // the first sequence element
597 CComVariant
pFrameVariant( mpDispFrame
);
598 SafeArrayPutElement( pInitVals
, &nInitInd
, &pFrameVariant
);
600 // the second sequence element
602 CComVariant
pStrArr( 1 );
603 SafeArrayPutElement( pInitVals
, &nInitInd
, &pStrArr
);
605 // the third sequence element
607 CComPtr
<IDispatch
> pdispValueObj
;
608 hr
= GetIDispByFunc( mpDispFactory
, L
"Bridge_GetValueObject", nullptr, 0, pdispValueObj
);
609 if( !SUCCEEDED( hr
) || !pdispValueObj
) return hr
;
611 CComVariant aValueArgs
[2];
612 aValueArgs
[1] = CComVariant( L
"com.sun.star.embed.XActionsApproval" );
613 CComPtr
< CComObject
< SOActionsApproval
> > pApproval( new CComObject
<SOActionsApproval
>() );
614 aValueArgs
[0] = CComVariant ( pApproval
);
616 hr
= ExecuteFunc( pdispValueObj
, L
"Set", aValueArgs
, 2, &dummyResult
);
617 if( !SUCCEEDED( hr
) ) return hr
;
619 CComVariant
aValueObj( pdispValueObj
);
620 SafeArrayPutElement( pInitVals
, &nInitInd
, &aValueObj
);
622 // execute initialize()
623 CComVariant aVarInitVals
;
624 aVarInitVals
.vt
= VT_ARRAY
| VT_VARIANT
; aVarInitVals
.parray
= pInitVals
;
625 hr
= ExecuteFunc( mpInstanceLocker
, L
"initialize", &aVarInitVals
, 1, &dummyResult
);
626 if( !SUCCEEDED( hr
) ) return hr
;
632 HRESULT
CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR
const * sUrl
, OLECHAR
const * sArgName
, BOOL sArgVal
)
634 SAFEARRAY FAR
* pPropVals
= SafeArrayCreateVector( VT_DISPATCH
, 0, 1 );
636 CComPtr
<IDispatch
> pdispPropVal
;
637 HRESULT hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
638 if( !SUCCEEDED( hr
) ) return hr
;
640 OLECHAR
const * sPropMemberNames
[2] = { L
"Name", L
"Value" };
641 CComVariant pPropVar
[2];
642 pPropVar
[0] = CComVariant( sArgName
);
643 pPropVar
[1].vt
= VT_BOOL
; pPropVar
[1].boolVal
= sArgVal
? VARIANT_TRUE
: VARIANT_FALSE
;
644 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
645 if( !SUCCEEDED( hr
) ) return hr
;
647 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
649 CComVariant aDispArgs
[4];
650 aDispArgs
[3] = CComVariant( sUrl
);
651 aDispArgs
[2] = CComVariant( L
"_self" );
652 aDispArgs
[1] = CComVariant( 0 );
653 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
654 aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
656 CComVariant dummyResult
;
657 hr
= ExecuteFunc( mpDispFrame
, L
"loadComponentFromURL", aDispArgs
, 4, &dummyResult
);
658 if( !SUCCEEDED( hr
) ) return hr
;
663 HRESULT
CSOActiveX::CallDispatchMethod( OLECHAR
const * sUrl
,
664 CComVariant
* aArgNames
,
665 CComVariant
* aArgVals
,
668 CComPtr
<IDispatch
> pdispURL
;
669 HRESULT hr
= GetUrlStruct( sUrl
, pdispURL
);
670 if( !SUCCEEDED( hr
) ) return hr
;
672 CComPtr
<IDispatch
> pdispXDispatch
;
673 CComVariant aArgs
[3];
674 aArgs
[2] = CComVariant( pdispURL
);
675 aArgs
[1] = CComVariant( L
"" );
676 aArgs
[0] = CComVariant( int(0) );
677 hr
= GetIDispByFunc( mpDispFrame
,
682 if( !SUCCEEDED( hr
) ) return hr
;
684 SAFEARRAY FAR
* pPropVals
= SafeArrayCreateVector( VT_DISPATCH
, 0, count
);
685 for( long ix
= 0; ix
< static_cast<long>(count
); ix
++ )
687 CComPtr
<IDispatch
> pdispPropVal
;
688 hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
689 if( !SUCCEEDED( hr
) ) return hr
;
691 OLECHAR
const * sPropMemberNames
[2] = { L
"Name", L
"Value" };
692 CComVariant pPropVar
[2];
693 pPropVar
[0] = aArgNames
[ix
];
694 pPropVar
[1] = aArgVals
[ix
];
695 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
696 if( !SUCCEEDED( hr
) ) return hr
;
698 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
701 CComVariant aDispArgs
[2];
702 aDispArgs
[1] = CComVariant( pdispURL
);
703 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
704 aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
706 CComVariant dummyResult
;
707 hr
= ExecuteFunc( pdispXDispatch
, L
"dispatch", aDispArgs
, 2, &dummyResult
);
708 if( !SUCCEEDED( hr
) ) return hr
;
713 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback
<CSOActiveX
>* /*pbsc*/, BYTE
* pBytes
, DWORD dwSize
)
715 if ( mbReadyForActivation
)
718 BOOL bSuccess
= FALSE
;
719 BOOL bFinishDownload
= FALSE
;
722 // means the download is finished, dwSize contains hresult
723 bFinishDownload
= TRUE
;
724 if ( SUCCEEDED( dwSize
) )
731 if ( !mpDispTempFile
)
733 CComVariant
aServiceName( L
"com.sun.star.io.TempFile" );
734 hr
= GetIDispByFunc( mpDispFactory
,
741 if( SUCCEEDED( hr
) && mpDispTempFile
)
743 SAFEARRAY FAR
* pDataArray
= SafeArrayCreateVector( VT_I1
, 0, dwSize
);
747 hr
= SafeArrayLock( pDataArray
);
748 if ( SUCCEEDED( hr
) )
750 for( DWORD ix
= 0; ix
< dwSize
; ix
++ )
751 static_cast<BYTE
*>(pDataArray
->pvData
)[ix
] = pBytes
[ix
];
752 hr
= SafeArrayUnlock( pDataArray
);
753 if ( SUCCEEDED( hr
) )
755 CComVariant aArgs
[1];
756 aArgs
[0].vt
= VT_ARRAY
| VT_I1
; aArgs
[0].parray
= pDataArray
;
757 CComVariant dummyResult
;
758 hr
= ExecuteFunc( mpDispTempFile
, L
"writeBytes", aArgs
, 1, &dummyResult
);
759 if( SUCCEEDED( hr
) )
769 // the download failed, let StarOffice download
770 bFinishDownload
= TRUE
;
771 mpDispTempFile
= CComPtr
< IDispatch
>();
774 if ( bFinishDownload
)
776 // trigger the loading now
778 mbReadyForActivation
= TRUE
;
785 HRESULT
CSOActiveX::LoadURLToFrame( )
787 CComVariant aArgNames
[4] = { L
"ReadOnly", L
"ViewOnly", L
"AsTemplate", L
"InputStream" };
788 CComVariant aArgVals
[4];
789 unsigned int nCount
= 3; // the 4-th argument is used only if the stream can be retrieved
791 aArgVals
[0].vt
= VT_BOOL
; aArgVals
[0].boolVal
= mbViewOnly
? VARIANT_TRUE
: VARIANT_FALSE
;
792 aArgVals
[1].vt
= VT_BOOL
; aArgVals
[1].boolVal
= mbViewOnly
? VARIANT_TRUE
: VARIANT_FALSE
;
793 aArgVals
[2].vt
= VT_BOOL
; aArgVals
[2].boolVal
= VARIANT_FALSE
;
795 if ( mpDispTempFile
)
797 aArgVals
[3] = CComVariant( mpDispTempFile
);
801 HRESULT hr
= CallDispatchMethod( mCurFileUrl
, aArgNames
, aArgVals
, nCount
);
802 if( !SUCCEEDED( hr
) ) return hr
;
804 CComVariant
aBarName( L
"MenuBarVisible" );
806 aBarVis
.vt
= VT_BOOL
; aBarVis
.boolVal
= VARIANT_FALSE
;
807 hr
= CallDispatchMethod( L
"slot:6661", &aBarName
, &aBarVis
, 1 );
808 // does not work for some documents, but it is no error
809 // if( !SUCCEEDED( hr ) ) return hr;
811 // try to get the model and set the presentation specific property, the setting will fail for other document formats
812 CComPtr
<IDispatch
> pdispController
;
813 hr
= GetIDispByFunc( mpDispFrame
, L
"getController", nullptr, 0, pdispController
);
814 if ( SUCCEEDED( hr
) && pdispController
)
816 CComPtr
<IDispatch
> pdispModel
;
817 hr
= GetIDispByFunc( pdispController
, L
"getModel", nullptr, 0, pdispModel
);
818 if ( SUCCEEDED( hr
) && pdispModel
)
820 CComPtr
<IDispatch
> pdispPres
;
821 hr
= GetIDispByFunc( pdispModel
, L
"getPresentation", nullptr, 0, pdispPres
);
822 if ( SUCCEEDED( hr
) && pdispPres
)
824 // this is a presentation
825 // let the slide show be shown in the document window
826 OLECHAR
const * pPropName
= L
"IsFullScreen";
827 CComVariant pPresProp
;
828 pPresProp
.vt
= VT_BOOL
; pPresProp
.boolVal
= VARIANT_FALSE
;
829 hr
= PutPropertiesToIDisp( pdispPres
, &pPropName
, &pPresProp
, 1 );
831 // start the slide show
832 if ( SUCCEEDED( hr
) )
834 CComVariant dummyResult
;
835 ExecuteFunc( pdispPres
, L
"Start", nullptr, 0, &dummyResult
);
841 // create dispatch interceptor
842 mpDispatchInterceptor
= new CComObject
< SODispatchInterceptor
>();
843 mpDispatchInterceptor
->AddRef();
844 mpDispatchInterceptor
->SetParent( this );
845 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispDispInter( mpDispatchInterceptor
);
847 // register dispatch interceptor in the frame
848 CComVariant
aDispVariant( pIDispDispInter
);
849 CComVariant dummyResult
;
850 hr
= ExecuteFunc( mpDispFrame
,
851 L
"registerDispatchProviderInterceptor",
856 if( !SUCCEEDED( hr
) ) return hr
;
861 SOVersion
CSOActiveX::GetVersionConnected()
863 SOVersion bResult
= SO_NOT_DETECTED
;
866 // create ConfigurationProvider instance
867 CComPtr
<IDispatch
> pdispConfProv
;
868 CComVariant
aServiceName( L
"com.sun.star.configuration.ConfigurationProvider" );
869 HRESULT hr
= GetIDispByFunc( mpDispFactory
,
875 if( SUCCEEDED( hr
) && pdispConfProv
)
877 CComPtr
<IDispatch
> pdispConfAccess
;
879 SAFEARRAY
* pInitParams
= SafeArrayCreateVector( VT_VARIANT
, 0, 1 );
884 CComVariant
aConfPath( L
"org.openoffice.Setup" );
885 SafeArrayPutElement( pInitParams
, &ix
, &aConfPath
);
887 CComVariant aArgs
[2];
888 aArgs
[1] = CComVariant( L
"com.sun.star.configuration.ConfigurationAccess" );
889 aArgs
[0].vt
= VT_ARRAY
| VT_VARIANT
; aArgs
[0].parray
= pInitParams
;
891 hr
= GetIDispByFunc( pdispConfProv
,
892 L
"createInstanceWithArguments",
897 if( SUCCEEDED( hr
) && pdispConfAccess
)
899 CComVariant aOfficeName
;
901 CComVariant
aProductName( L
"Product/ooName" );
902 hr
= ExecuteFunc( pdispConfAccess
,
903 L
"getByHierarchicalName",
908 if( SUCCEEDED( hr
) && aOfficeName
.vt
== VT_BSTR
)
910 CComVariant aOfficeVersion
;
912 CComVariant
aProductVersion( L
"Product/ooSetupVersion" );
913 hr
= ExecuteFunc( pdispConfAccess
,
914 L
"getByHierarchicalName",
919 if( SUCCEEDED( hr
) && aOfficeVersion
.vt
== VT_BSTR
)
921 if (!wcscmp(aOfficeName
.bstrVal
, L
"StarOffice"))
923 if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"6.1", 3))
925 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"6.0", 3))
927 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"5.2", 3))
930 bResult
= SO_UNKNOWN
;
934 if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"1.1", 3))
936 else if (!wcsncmp(aOfficeVersion
.bstrVal
, L
"1.0", 3))
939 bResult
= OO_UNKNOWN
;
955 explicit LockingGuard( BOOL
& bLocked
)
956 : mbLocked( bLocked
)
967 HRESULT
CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO
& di
)
969 // This method is called only in main thread, no need to lock it
971 // Get read of reentrance problems
974 LockingGuard
aGuard( mbDrawLocked
);
976 if( m_spInPlaceSite
&& mCurFileUrl
&& mbReadyForActivation
)
979 HRESULT hr
= m_spInPlaceSite
->GetWindow( &hwnd
);
980 if( !SUCCEEDED( hr
) ) return hr
;
982 if( mParentWin
!= hwnd
|| !mOffWin
)
986 CComVariant dummyResult
;
987 CComVariant aPropVar
;
988 aPropVar
.vt
= VT_BOOL
; aPropVar
.boolVal
= VARIANT_FALSE
;
989 (void) ExecuteFunc( mpDispFrame
, L
"close", &aPropVar
, 1, &dummyResult
);
990 mpDispFrame
= CComPtr
<IDispatch
>();
994 mOffWin
= CreateWindowW(
995 STAROFFICE_WINDOWCLASS
,
997 WS_CHILD
| WS_CLIPCHILDREN
| WS_BORDER
,
1000 di
.prcBounds
->right
- di
.prcBounds
->left
,
1001 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
1007 ::ShowWindow( mOffWin
, SW_SHOW
);
1012 ::GetWindowRect( mOffWin
, &aRect
);
1014 if( aRect
.left
!= di
.prcBounds
->left
|| aRect
.top
!= di
.prcBounds
->top
1015 || aRect
.right
!= di
.prcBounds
->right
|| aRect
.bottom
!= di
.prcBounds
->bottom
)
1017 // on this state the office window should exist already
1018 ::SetWindowPos( mOffWin
,
1022 di
.prcBounds
->right
- di
.prcBounds
->left
,
1023 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
1026 CComVariant aPosArgs
[5];
1027 aPosArgs
[4] = CComVariant( 0 );
1028 aPosArgs
[3] = CComVariant( 0 );
1029 aPosArgs
[2] = CComVariant( int(di
.prcBounds
->right
- di
.prcBounds
->left
) );
1030 aPosArgs
[1] = CComVariant( int(di
.prcBounds
->bottom
- di
.prcBounds
->top
) );
1031 aPosArgs
[0] = CComVariant( 12 );
1032 CComVariant dummyResult
;
1033 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
1034 if( !SUCCEEDED( hr
) ) return hr
;
1038 if (mnVersion
== SO_NOT_DETECTED
)
1040 OutputError_Impl( mOffWin
, CS_E_INVALID_VERSION
);
1046 hr
= CreateFrameOldWay( mOffWin
,
1047 di
.prcBounds
->right
- di
.prcBounds
->left
,
1048 di
.prcBounds
->bottom
- di
.prcBounds
->top
);
1050 if( !SUCCEEDED( hr
) )
1052 // if the frame can not be opened do not try any more
1053 mbReadyForActivation
= FALSE
;
1054 OutputError_Impl( mOffWin
, STG_E_ABNORMALAPIEXIT
);
1061 hr
= LoadURLToFrame();
1064 if( !SUCCEEDED( hr
) )
1066 // if the document can not be opened do not try any more
1067 mbReadyForActivation
= FALSE
;
1069 OutputError_Impl( mOffWin
, STG_E_ABNORMALAPIEXIT
);
1077 // activate the fallback
1078 CComControl
<CSOActiveX
>::OnDrawAdvanced( di
);
1084 HRESULT
CSOActiveX::OnDraw( ATL_DRAWINFO
& di
)
1086 // fallback that is activated by the parent class
1088 FillRect( di
.hdcDraw
, reinterpret_cast<RECT
const *>(di
.prcBounds
), reinterpret_cast<HBRUSH
>(COLOR_BACKGROUND
) );
1093 STDMETHODIMP
CSOActiveX::SetClientSite( IOleClientSite
* aClientSite
)
1095 HRESULT hr
= IOleObjectImpl
<CSOActiveX
>::SetClientSite( aClientSite
);
1099 //ATLASSERT( mWebBrowser2 );
1101 AtlUnadvise( mWebBrowser2
, DIID_DWebBrowserEvents2
, mCookie
);
1105 CComPtr
<IOleContainer
> aContainer
;
1106 m_spClientSite
->GetContainer( &aContainer
);
1107 // ATLASSERT( aContainer );
1109 if( SUCCEEDED( hr
) && aContainer
)
1111 CComQIPtr
<IServiceProvider
, &IID_IServiceProvider
> aServiceProvider( aContainer
);
1112 //ATLASSERT( aServiceProvider );
1114 if( aServiceProvider
)
1116 aServiceProvider
->QueryService( SID_SInternetExplorer
,
1118 reinterpret_cast<void**>(&mWebBrowser2
) );
1119 // ATLASSERT( mWebBrowser2 );
1121 AtlAdvise( mWebBrowser2
, GetUnknown(), DIID_DWebBrowserEvents2
, &mCookie
);
1128 STDMETHODIMP
CSOActiveX::Invoke(DISPID dispidMember
,
1132 DISPPARAMS
* pDispParams
,
1133 VARIANT
* pvarResult
,
1134 EXCEPINFO
* pExcepInfo
,
1137 if (riid
!= IID_NULL
)
1138 return DISP_E_UNKNOWNINTERFACE
;
1141 return DISP_E_PARAMNOTOPTIONAL
;
1143 if ( dispidMember
== DISPID_ONQUIT
)
1146 IDispatchImpl
<ISOActiveX
, &IID_ISOActiveX
,
1147 &LIBID_SO_ACTIVEXLib
>::Invoke(
1148 dispidMember
, riid
, lcid
, wFlags
, pDispParams
,
1149 pvarResult
, pExcepInfo
, puArgErr
);
1154 HRESULT
CSOActiveX::GetURL( const OLECHAR
* url
,
1155 const OLECHAR
* target
)
1157 CComVariant aEmpty1
, aEmpty2
, aEmpty3
;
1158 CComVariant
aUrl( url
);
1159 CComVariant aTarget
;
1161 aTarget
= CComVariant( target
);
1163 return mWebBrowser2
->Navigate2( &aUrl
,
1171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */