Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / extensions / source / activex / SOActiveX.cxx
blobb72ab0d66ca0eecbc2b48f575da895027c53b70b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
22 #include "StdAfx2.h"
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;
36 FormatMessageW(
37 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
38 nullptr,
39 ErrorCode,
40 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
41 reinterpret_cast<LPWSTR>(&sMessage),
43 nullptr
45 MessageBoxW( hw, sMessage, nullptr, MB_OK | MB_ICONINFORMATION );
46 HeapFree( GetProcessHeap(), 0, sMessage );
49 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
50 OLECHAR const * sFuncName,
51 CComVariant* params,
52 unsigned int count,
53 CComVariant* pResult )
55 if( !idispUnoObject )
56 return E_FAIL;
58 DISPID id;
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};
64 // DEBUG
65 EXCEPINFO myInfo;
66 hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
67 &dispparams, pResult, &myInfo, nullptr);
69 // for debugging purposes
70 // USES_CONVERSION;
71 // if ( !SUCCEEDED( hr ) )
72 // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
74 return hr;
77 static HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
78 OLECHAR const * sFuncName,
79 CComVariant* params,
80 unsigned int count,
81 CComPtr<IDispatch>& pdispResult )
83 if( !idispUnoObject )
84 return E_FAIL;
86 CComVariant result;
87 HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
88 if( !SUCCEEDED( hr ) ) return hr;
90 if( result.vt != VT_DISPATCH || result.pdispVal == nullptr )
91 return E_FAIL;
93 pdispResult = CComPtr<IDispatch>( result.pdispVal );
95 return S_OK;
98 static HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
99 OLECHAR const ** sMemberNames,
100 CComVariant* pVariant,
101 unsigned int count )
103 for( unsigned int ind = 0; ind < count; ind++ )
105 DISPID id;
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;
113 return S_OK;
116 HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
117 OLECHAR const ** sMemberNames,
118 CComVariant* pVariant,
119 unsigned int count )
121 for( unsigned int ind = 0; ind < count; ind++ )
123 DISPID id;
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;
131 return S_OK;
134 // CSOActiveX
136 CSOActiveX::CSOActiveX()
137 : mCookie(0)
138 , mCurFileUrl( L"private:factory/swriter" )
139 , mbLoad( FALSE )
140 , mbViewOnly( TRUE )
141 , mParentWin( nullptr )
142 , mOffWin( 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()
169 Cleanup();
173 HRESULT CSOActiveX::Cleanup()
175 CComVariant dummyResult;
177 if( mpDispatchInterceptor )
179 if( mpDispFrame )
181 // remove dispatch interceptor
182 CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
183 CComVariant aVariant( pIDispDispInter );
184 ExecuteFunc( mpDispFrame,
185 L"releaseDispatchProviderInterceptor",
186 &aVariant,
188 &dummyResult );
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 >();
205 if( mpDispFrame )
207 bool bCloserActivated = false;
209 CComPtr<IDispatch> pDispDocumentCloser;
210 CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
211 HRESULT hr = GetIDispByFunc( mpDispFactory,
212 L"createInstance",
213 &aDocCloser,
215 pDispDocumentCloser );
216 if ( SUCCEEDED( hr ) && pDispDocumentCloser )
218 SAFEARRAY* pInitFrame = SafeArrayCreateVector(VT_VARIANT, 0, 1);
219 LONG nInitInd = 0;
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 );
247 TerminateOffice();
249 return S_OK;
252 HRESULT CSOActiveX::TerminateOffice()
254 // create desktop
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;
266 CComVariant aFrames;
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 );
281 return hr;
284 COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::InitNew ()
286 mnVersion = GetVersionConnected();
287 mbLoad = TRUE;
288 return S_OK;
291 COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
293 mnVersion = GetVersionConnected();
294 mbLoad = TRUE;
296 // may be later?
297 // for now just ignore
299 return S_OK;
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 ) )
311 return hr;
313 unsigned long aNum;
314 hr = pPropBag2->CountProperties( &aNum );
315 //ATLASSERT( hr >= 0 );
316 if( !SUCCEEDED( hr ) )
317 return hr;
319 PROPBAG2* aPropNames = new PROPBAG2[aNum];
320 unsigned long aReaded;
322 hr = pPropBag2->GetPropertyInfo( 0,
323 aNum,
324 aPropNames,
325 &aReaded );
326 //ATLASSERT( hr >= 0 );
327 if( !SUCCEEDED( hr ) )
329 delete[] aPropNames;
330 return hr;
333 CComVariant* aVal = new CComVariant[aNum];
334 HRESULT* hvs = new HRESULT[aNum];
335 hr = pPropBag2->Read( aNum,
336 aPropNames,
337 nullptr,
338 aVal,
339 hvs );
340 //ATLASSERT( hr >= 0 );
341 if( !SUCCEEDED( hr ) )
343 delete[] hvs;
344 delete[] aVal;
345 delete[] aPropNames;
346 return 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"))
361 // the default value
362 mbViewOnly = TRUE;
364 else
366 mbViewOnly = FALSE;
371 delete[] hvs;
372 delete[] aVal;
373 delete[] aPropNames;
375 if( !mpDispFactory )
376 return hr;
378 mbReadyForActivation = FALSE;
379 hr = CBindStatusCallback<CSOActiveX>::Download(
380 this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE);
381 if (hr == MK_S_ASYNCHRONOUS)
382 hr = S_OK;
384 if ( !SUCCEEDED( hr ) )
386 // trigger initialization without stream
387 mbLoad = TRUE;
389 Invalidate();
390 UpdateWindow();
393 return hr;
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";
408 DISPID nURLID;
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,
418 L"createInstance",
419 &aServiceName,
421 pdispTransformer );
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;
433 return S_OK;
436 HRESULT CSOActiveX::SetLayoutManagerProps()
438 if ( !mpDispFrame )
439 return E_FAIL;
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 )
445 return E_FAIL;
447 CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
450 if( !SUCCEEDED( hr ) || !pdispLM )
451 return E_FAIL;
453 OLECHAR const * sATName = L"AutomaticToolbars";
454 CComVariant pATProp;
455 pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
456 hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
458 return hr;
461 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
463 if( !mpDispFactory )
464 return E_FAIL;
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",
477 L"Y",
478 L"Width",
479 L"Height" };
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",
494 L"ParentIndex",
495 L"Parent",
496 L"Bounds",
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;
519 // create frame
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;
531 // initialize frame
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();
540 // create desktop
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;
556 // initialize window
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
582 LONG nInitInd = 0;
583 CComVariant pFrameVariant( mpDispFrame );
584 SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
586 // the second sequence element
587 nInitInd = 1;
588 CComVariant pStrArr( 1 );
589 SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
591 // the third sequence element
592 nInitInd = 2;
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;
615 return S_OK;
618 HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR const * sUrl, OLECHAR const * sArgName, BOOL sArgVal )
620 SAFEARRAY* pPropVals = SafeArrayCreateVector(VT_DISPATCH, 0, 1);
621 LONG ix = 0;
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;
646 return S_OK;
649 HRESULT CSOActiveX::CallDispatchMethod( OLECHAR const * sUrl,
650 CComVariant* aArgNames,
651 CComVariant* aArgVals,
652 unsigned int count )
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,
664 L"queryDispatch",
665 aArgs,
667 pdispXDispatch );
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;
696 return S_OK;
699 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
701 if ( mbReadyForActivation )
702 return;
704 bool bSuccess = false;
705 bool bFinishDownload = false;
706 if ( !pBytes )
708 // means the download is finished, dwSize contains hresult
709 bFinishDownload = true;
710 if ( SUCCEEDED( dwSize ) )
711 bSuccess = true;
713 else
715 HRESULT hr = S_OK;
717 if ( !mpDispTempFile )
719 CComVariant aServiceName( L"com.sun.star.io.TempFile" );
720 hr = GetIDispByFunc( mpDispFactory,
721 L"createInstance",
722 &aServiceName,
724 mpDispTempFile );
727 if( SUCCEEDED( hr ) && mpDispTempFile )
729 SAFEARRAY* pDataArray = SafeArrayCreateVector(VT_I1, 0, dwSize);
731 if ( pDataArray )
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 ) )
746 bSuccess = true;
753 if ( !bSuccess )
755 // the download failed, let StarOffice download
756 bFinishDownload = true;
757 mpDispTempFile = CComPtr< IDispatch >();
760 if ( bFinishDownload )
762 // trigger the loading now
763 mbLoad = TRUE;
764 mbReadyForActivation = TRUE;
766 Invalidate();
767 UpdateWindow();
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 );
784 nCount = 4;
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",
831 &aDispVariant,
833 &dummyResult );
835 if( !SUCCEEDED( hr ) ) return hr;
837 return S_OK;
840 SOVersion CSOActiveX::GetVersionConnected()
842 SOVersion bResult = SO_NOT_DETECTED;
843 if( mpDispFactory )
845 // create ConfigurationProvider instance
846 CComPtr<IDispatch> pdispConfProv;
847 CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
848 HRESULT hr = GetIDispByFunc( mpDispFactory,
849 L"createInstance",
850 &aServiceName,
852 pdispConfProv );
854 if( SUCCEEDED( hr ) && pdispConfProv )
856 CComPtr<IDispatch> pdispConfAccess;
858 SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
860 if( pInitParams )
862 LONG ix = 0;
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",
872 aArgs,
874 pdispConfAccess );
876 if( SUCCEEDED( hr ) && pdispConfAccess )
878 CComVariant aOfficeName;
880 CComVariant aProductName( L"Product/ooName" );
881 hr = ExecuteFunc( pdispConfAccess,
882 L"getByHierarchicalName",
883 &aProductName,
885 &aOfficeName );
887 if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
889 CComVariant aOfficeVersion;
891 CComVariant aProductVersion( L"Product/ooSetupVersion" );
892 hr = ExecuteFunc( pdispConfAccess,
893 L"getByHierarchicalName",
894 &aProductVersion,
896 &aOfficeVersion );
898 if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
900 if (!wcscmp(aOfficeName.bstrVal, L"StarOffice"))
902 if (!wcsncmp(aOfficeVersion.bstrVal, L"6.1", 3))
903 bResult = SO_61;
904 else if (!wcsncmp(aOfficeVersion.bstrVal, L"6.0", 3))
905 bResult = SO_60;
906 else if (!wcsncmp(aOfficeVersion.bstrVal, L"5.2", 3))
907 bResult = SO_52;
908 else
909 bResult = SO_UNKNOWN;
911 else // OpenOffice
913 if (!wcsncmp(aOfficeVersion.bstrVal, L"1.1", 3))
914 bResult = OO_11;
915 else if (!wcsncmp(aOfficeVersion.bstrVal, L"1.0", 3))
916 bResult = OO_10;
917 else
918 bResult = OO_UNKNOWN;
927 return bResult;
930 namespace {
932 class LockingGuard
934 bool& mbLocked;
935 public:
936 explicit LockingGuard( bool& bLocked )
937 : mbLocked( bLocked )
939 mbLocked = true;
942 ~LockingGuard()
944 mbLocked = false;
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
955 if ( mbDrawLocked )
956 return S_OK;
957 LockingGuard aGuard( mbDrawLocked );
959 if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
961 HWND hwnd;
962 HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
963 if( !SUCCEEDED( hr ) ) return hr;
965 if( mParentWin != hwnd || !mOffWin )
967 if( mpDispFrame )
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>();
976 mParentWin = hwnd;
977 mOffWin = CreateWindowW(
978 STAROFFICE_WINDOWCLASS,
979 L"OfficeContainer",
980 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
981 di.prcBounds->left,
982 di.prcBounds->top,
983 di.prcBounds->right - di.prcBounds->left,
984 di.prcBounds->bottom - di.prcBounds->top,
985 mParentWin,
986 nullptr,
987 nullptr,
988 nullptr );
990 ::ShowWindow( mOffWin, SW_SHOW );
992 else
994 RECT aRect;
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,
1002 HWND_TOP,
1003 di.prcBounds->left,
1004 di.prcBounds->top,
1005 di.prcBounds->right - di.prcBounds->left,
1006 di.prcBounds->bottom - di.prcBounds->top,
1007 SWP_NOZORDER );
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 );
1024 return E_FAIL;
1027 if( ! mpDispFrame )
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 );
1038 return hr;
1042 if( mbLoad )
1044 hr = LoadURLToFrame();
1045 mbLoad = FALSE;
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 );
1054 return hr;
1058 else
1060 // activate the fallback
1061 CComControl<CSOActiveX>::OnDrawAdvanced( di );
1064 return S_OK;
1067 HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
1069 // fallback that is activated by the parent class
1070 if ( di.hdcDraw )
1071 FillRect( di.hdcDraw, reinterpret_cast<RECT const *>(di.prcBounds), reinterpret_cast<HBRUSH>(COLOR_BACKGROUND) );
1073 return S_OK;
1076 COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
1078 HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
1080 if( !aClientSite )
1082 //ATLASSERT( mWebBrowser2 );
1083 if( mWebBrowser2 )
1084 AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
1085 return hr;
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,
1100 IID_IWebBrowser,
1101 reinterpret_cast<void**>(&mWebBrowser2) );
1102 // ATLASSERT( mWebBrowser2 );
1103 if( mWebBrowser2 )
1104 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
1108 return hr;
1111 COM_DECLSPEC_NOTHROW STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
1112 REFIID riid,
1113 LCID lcid,
1114 WORD wFlags,
1115 DISPPARAMS* pDispParams,
1116 VARIANT* pvarResult,
1117 EXCEPINFO* pExcepInfo,
1118 UINT* puArgErr)
1120 if (riid != IID_NULL)
1121 return DISP_E_UNKNOWNINTERFACE;
1123 if (!pDispParams)
1124 return DISP_E_PARAMNOTOPTIONAL;
1126 if ( dispidMember == DISPID_ONQUIT )
1127 Cleanup();
1129 IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
1130 &LIBID_SO_ACTIVEXLib>::Invoke(
1131 dispidMember, riid, lcid, wFlags, pDispParams,
1132 pvarResult, pExcepInfo, puArgErr);
1134 return S_OK;
1137 HRESULT CSOActiveX::GetURL( const OLECHAR* url,
1138 const OLECHAR* target )
1140 CComVariant aEmpty1, aEmpty2, aEmpty3;
1141 CComVariant aUrl( url );
1142 CComVariant aTarget;
1143 if ( target )
1144 aTarget = CComVariant( target );
1146 return mWebBrowser2->Navigate2( &aUrl,
1147 &aEmpty1,
1148 &aTarget,
1149 &aEmpty2,
1150 &aEmpty3 );
1154 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */