Linux x86 build fix
[LibreOffice.git] / extensions / source / activex / SOActiveX.cxx
blobfdb312e391055a89a864def417df04aae2d05b4a
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 #pragma warning (push,1)
23 #pragma warning (disable:4265)
25 #include "stdafx2.h"
26 #include "so_activex.h"
27 #include "SOActiveX.h"
28 #include "SOComWindowPeer.h"
29 #include "SODispatchInterceptor.h"
30 #include "SOActionsApproval.h"
32 #pragma warning (pop)
34 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
39 void OutputError_Impl( HWND hw, HRESULT ErrorCode )
41 void* sMessage;
42 FormatMessageA(
43 FORMAT_MESSAGE_ALLOCATE_BUFFER |
44 FORMAT_MESSAGE_FROM_SYSTEM,
45 NULL,
46 ErrorCode,
47 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
48 (LPTSTR) &sMessage,
50 NULL
52 ::MessageBoxA( hw, (LPCTSTR)sMessage, NULL, MB_OK | MB_ICONINFORMATION );
53 LocalFree( sMessage );
56 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
57 OLECHAR* sFuncName,
58 CComVariant* params,
59 unsigned int count,
60 CComVariant* pResult )
62 if( !idispUnoObject )
63 return E_FAIL;
65 DISPID id;
66 HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
67 if( !SUCCEEDED( hr ) ) return hr;
69 DISPPARAMS dispparams= { params, 0, count, 0};
71 // DEBUG
72 EXCEPINFO myInfo;
73 hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
74 &dispparams, pResult, &myInfo, 0);
76 // for debugging purposes
77 // USES_CONVERSION;
78 // if ( !SUCCEEDED( hr ) )
79 // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
81 return hr;
84 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
85 OLECHAR* sFuncName,
86 CComVariant* params,
87 unsigned int count,
88 CComPtr<IDispatch>& pdispResult )
90 if( !idispUnoObject )
91 return E_FAIL;
93 CComVariant result;
94 HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
95 if( !SUCCEEDED( hr ) ) return hr;
97 if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
98 return E_FAIL;
100 pdispResult = CComPtr<IDispatch>( result.pdispVal );
102 return S_OK;
105 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
106 OLECHAR** sMemberNames,
107 CComVariant* pVariant,
108 unsigned int count )
110 for( unsigned int ind = 0; ind < count; ind++ )
112 DISPID id;
113 HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
114 if( !SUCCEEDED( hr ) ) return hr;
116 hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
117 if( !SUCCEEDED( hr ) ) return hr;
120 return S_OK;
123 HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
124 OLECHAR** sMemberNames,
125 CComVariant* pVariant,
126 unsigned int count )
128 for( unsigned int ind = 0; ind < count; ind++ )
130 DISPID id;
131 HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
132 if( !SUCCEEDED( hr ) ) return hr;
134 hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
135 if( !SUCCEEDED( hr ) ) return hr;
138 return S_OK;
141 // CSOActiveX
143 CSOActiveX::CSOActiveX()
144 : mCookie(0)
145 , mCurFileUrl( L"private:factory/swriter" )
146 , mbLoad( FALSE )
147 , mParentWin( NULL )
148 , mOffWin( NULL )
149 , mbViewOnly( TRUE )
150 , mpDispatchInterceptor( NULL )
151 , mnVersion( SO_NOT_DETECTED )
152 , mbReadyForActivation( FALSE )
153 , mbDrawLocked( FALSE )
155 CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
156 HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
157 if( !SUCCEEDED( hr ) )
158 OutputError_Impl( NULL, hr );
160 mPWinClass.style = CS_HREDRAW|CS_VREDRAW;
161 mPWinClass.lpfnWndProc = ::DefWindowProc;
162 mPWinClass.cbClsExtra = 0;
163 mPWinClass.cbWndExtra = 0;
164 mPWinClass.hInstance = (HINSTANCE) GetModuleHandle(NULL); //myInstance;
165 mPWinClass.hIcon = NULL;
166 mPWinClass.hCursor = NULL;
167 mPWinClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
168 mPWinClass.lpszMenuName = NULL;
169 mPWinClass.lpszClassName = STAROFFICE_WINDOWCLASS;
171 RegisterClass(&mPWinClass);
174 CSOActiveX::~CSOActiveX()
176 Cleanup();
180 HRESULT CSOActiveX::Cleanup()
182 CComVariant dummyResult;
184 if( mpDispatchInterceptor )
186 if( mpDispFrame )
188 // remove dispatch interceptor
189 CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
190 CComVariant aVariant( pIDispDispInter );
191 ExecuteFunc( mpDispFrame,
192 L"releaseDispatchProviderInterceptor",
193 &aVariant,
195 &dummyResult );
198 mpDispatchInterceptor->ClearParent();
199 mpDispatchInterceptor->Release();
200 mpDispatchInterceptor = NULL;
203 mpDispTempFile = CComPtr< IDispatch >();
204 mbReadyForActivation = FALSE;
206 if( mpInstanceLocker )
208 ExecuteFunc( mpInstanceLocker, L"dispose", NULL, 0, &dummyResult );
209 mpInstanceLocker = CComPtr< IDispatch >();
212 if( mpDispFrame )
214 BOOL bCloserActivated = FALSE;
216 CComPtr<IDispatch> pDispDocumentCloser;
217 CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
218 HRESULT hr = GetIDispByFunc( mpDispFactory,
219 L"createInstance",
220 &aDocCloser,
222 pDispDocumentCloser );
223 if ( SUCCEEDED( hr ) && pDispDocumentCloser )
225 SAFEARRAY FAR* pInitFrame = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
226 long nInitInd = 0;
227 CComVariant pFrameVariant( mpDispFrame );
228 SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
229 CComVariant aVarInitFrame;
230 aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
231 hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
232 if( SUCCEEDED( hr ) )
234 // the following call will let the closing happen
235 hr = ExecuteFunc( pDispDocumentCloser, L"dispose", NULL, 0, &dummyResult );
236 bCloserActivated = SUCCEEDED( hr );
240 if ( !bCloserActivated )
242 CComVariant aPropVar;
243 aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
244 if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
245 ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
248 mpDispFrame = CComPtr< IDispatch >();
251 if( ::IsWindow( mOffWin ) )
252 ::DestroyWindow( mOffWin );
254 TerminateOffice();
256 return S_OK;
259 HRESULT CSOActiveX::TerminateOffice()
261 // create desktop
262 CComPtr<IDispatch> pdispDesktop;
263 CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
265 HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
266 if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
268 // create tree of frames
269 CComPtr<IDispatch> pdispChildren;
270 hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
271 if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
273 CComVariant aFrames;
274 CComVariant nFlag( 4 );
275 hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
276 if ( SUCCEEDED( hr ) )
278 if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
279 && ( !aFrames.parray || aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0 ) )
281 // there is no frames open
282 // TODO: check whether the frames are hidden if they are open?
283 CComVariant dummyResult;
284 hr = ExecuteFunc( pdispDesktop, L"terminate", NULL, 0, &dummyResult );
288 return hr;
291 STDMETHODIMP CSOActiveX::InitNew ()
293 mnVersion = GetVersionConnected();
294 mbLoad = TRUE;
295 return S_OK;
298 STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
300 mnVersion = GetVersionConnected();
301 mbLoad = TRUE;
303 // may be later?
304 // for now just ignore
306 return S_OK;
309 STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
311 mnVersion = GetVersionConnected();
313 IPropertyBag2* pPropBag2;
314 HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
315 //ATLASSERT( hr >= 0 );
317 if( !SUCCEEDED( hr ) )
318 return hr;
320 unsigned long aNum;
321 hr = pPropBag2->CountProperties( &aNum );
322 //ATLASSERT( hr >= 0 );
323 if( !SUCCEEDED( hr ) )
324 return hr;
326 PROPBAG2* aPropNames = new PROPBAG2[aNum];
327 unsigned long aReaded;
329 hr = pPropBag2->GetPropertyInfo( 0,
330 aNum,
331 aPropNames,
332 &aReaded );
333 //ATLASSERT( hr >= 0 );
334 if( !SUCCEEDED( hr ) )
336 delete[] aPropNames;
337 return hr;
340 CComVariant* aVal = new CComVariant[aNum];
341 HRESULT* hvs = new HRESULT[aNum];
342 hr = pPropBag2->Read( aNum,
343 aPropNames,
344 NULL,
345 aVal,
346 hvs );
347 //ATLASSERT( hr >= 0 );
348 if( !SUCCEEDED( hr ) )
350 delete[] hvs;
351 delete[] aVal;
352 delete[] aPropNames;
353 return hr;
356 USES_CONVERSION;
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 && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
362 mCurFileUrl = wcsdup( aVal[ind].bstrVal );
364 else if( aVal[ind].vt == VT_BSTR
365 && !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
367 if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
369 // the default value
370 mbViewOnly = TRUE;
372 else
374 mbViewOnly = FALSE;
379 delete[] hvs;
380 delete[] aVal;
381 delete[] aPropNames;
383 if( !mpDispFactory )
384 return hr;
386 mbReadyForActivation = FALSE;
387 hr = CBindStatusCallback<CSOActiveX>::Download( this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE );
388 if ( hr == MK_S_ASYNCHRONOUS )
389 hr = S_OK;
391 if ( !SUCCEEDED( hr ) )
393 // trigger initialization without stream
394 mbLoad = TRUE;
396 Invalidate();
397 UpdateWindow();
400 return hr;
403 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
405 CComVariant aComStruct( sStructName );
406 return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
409 HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
411 HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
412 if( !SUCCEEDED( hr ) ) return hr;
414 OLECHAR* sURLMemberName = L"Complete";
415 DISPID nURLID;
416 hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
417 if( !SUCCEEDED( hr ) ) return hr;
418 CComVariant aComUrl( sUrl );
419 hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
420 if( !SUCCEEDED( hr ) ) return hr;
422 CComPtr<IDispatch> pdispTransformer;
423 CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
424 hr = GetIDispByFunc( mpDispFactory,
425 L"createInstance",
426 &aServiceName,
428 pdispTransformer );
429 if( !SUCCEEDED( hr ) ) return hr;
431 CComVariant dummyResult;
432 CComVariant aParam[2];
433 aParam[1].ppdispVal = &pdispUrl;
434 aParam[1].vt = VT_DISPATCH | VT_BYREF;
435 aParam[0] = CComVariant( L"file:///" );
437 hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
438 if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
440 return S_OK;
443 HRESULT CSOActiveX::SetLayoutManagerProps()
445 if ( !mpDispFrame )
446 return E_FAIL;
448 CComVariant pVarLayoutMgr;
449 OLECHAR* sLMPropName = L"LayoutManager";
450 HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
451 if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == NULL )
452 return E_FAIL;
454 CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
457 if( !SUCCEEDED( hr ) || !pdispLM )
458 return E_FAIL;
460 OLECHAR* sATName = L"AutomaticToolbars";
461 CComVariant pATProp;
462 pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
463 hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
465 return hr;
468 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
470 if( !mpDispFactory )
471 return E_FAIL;
473 // create window handle holder
474 CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
475 pPeerToSend->SetHWNDInternally( hwnd );
476 CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
478 // create rectangle structure
479 CComPtr<IDispatch> pdispRectangle;
480 HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
481 if( !SUCCEEDED( hr ) ) return hr;
483 OLECHAR* sRectMemberNames[4] = { L"X",
484 L"Y",
485 L"Width",
486 L"Height" };
487 CComVariant pRectVariant[4];
488 pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
490 hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
491 if( !SUCCEEDED( hr ) ) return hr;
493 // create WindowDescriptor structure
494 CComPtr<IDispatch> pdispWinDescr;
495 hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
496 if( !SUCCEEDED( hr ) ) return hr;
498 // fill in descriptor with info
499 OLECHAR* sDescriptorMemberNames[6] = { L"Type",
500 L"WindowServiceName",
501 L"ParentIndex",
502 L"Parent",
503 L"Bounds",
504 L"WindowAttributes" };
505 CComVariant pDescriptorVar[6];
506 pDescriptorVar[0] = CComVariant( 0 );
507 pDescriptorVar[1] = CComVariant( L"workwindow" );
508 pDescriptorVar[2] = CComVariant( 1 );
509 pDescriptorVar[3] = CComVariant( pIDispToSend );
510 pDescriptorVar[4] = CComVariant( pdispRectangle );
511 pDescriptorVar[5] = CComVariant( 33 );
512 hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
513 if( !SUCCEEDED( hr ) ) return hr;
515 // create XToolkit instance
516 CComPtr<IDispatch> pdispToolkit;
517 CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
518 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
519 if( !SUCCEEDED( hr ) ) return hr;
521 // create window with toolkit
522 CComVariant aWinDescr( pdispWinDescr );
523 hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
524 if( !SUCCEEDED( hr ) ) return hr;
526 // create frame
527 aServiceName = CComVariant( L"com.sun.star.frame.Task" );
528 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
529 if( !SUCCEEDED( hr ) || !mpDispFrame )
531 // the interface com.sun.star.frame.Task is removed in 6.1
532 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
533 aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
534 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
535 if( !SUCCEEDED( hr ) ) return hr;
538 // initialize frame
539 CComVariant dummyResult;
540 CComVariant aDispWin( mpDispWin );
541 hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
542 if( !SUCCEEDED( hr ) ) return hr;
544 // set some properties to the layout manager, ignore errors for now
545 SetLayoutManagerProps();
547 // create desktop
548 CComPtr<IDispatch> pdispDesktop;
549 aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
550 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
551 if( !SUCCEEDED( hr ) ) return hr;
553 // create tree of frames
554 CComPtr<IDispatch> pdispChildren;
555 hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
556 if( !SUCCEEDED( hr ) ) return hr;
558 // insert new frame into desctop hierarchy
559 CComVariant aDispFrame( mpDispFrame );
560 hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
561 if( !SUCCEEDED( hr ) ) return hr;
563 // initialize window
564 CComVariant aTransparent( (long)0xFFFFFFFF );
565 hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
566 if( !SUCCEEDED( hr ) ) return hr;
568 CComVariant aTrue( TRUE );
569 hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
570 if( !SUCCEEDED( hr ) ) return hr;
572 CComVariant aPosArgs[5];
573 aPosArgs[4] = CComVariant( 0 );
574 aPosArgs[3] = CComVariant( 0 );
575 aPosArgs[2] = CComVariant( width );
576 aPosArgs[1] = CComVariant( height );
577 aPosArgs[0] = CComVariant( 12 );
578 hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
579 if( !SUCCEEDED( hr ) ) return hr;
581 // create frame locker if there is such service
582 aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
583 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
584 if( SUCCEEDED( hr ) && mpInstanceLocker )
586 SAFEARRAY FAR* pInitVals = SafeArrayCreateVector( VT_VARIANT, 0, 3 );
588 // the first sequence element
589 long nInitInd = 0;
590 CComVariant pFrameVariant( mpDispFrame );
591 SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
593 // the second sequence element
594 nInitInd = 1;
595 CComVariant pStrArr( 1L );
596 SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
598 // the third sequence element
599 nInitInd = 2;
600 CComPtr<IDispatch> pdispValueObj;
601 hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", NULL, 0, pdispValueObj );
602 if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
604 CComVariant aValueArgs[2];
605 aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
606 CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
607 aValueArgs[0] = CComVariant ( pApproval );
609 hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
610 if( !SUCCEEDED( hr ) ) return hr;
612 CComVariant aValueObj( pdispValueObj );
613 SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
615 // execute initialize()
616 CComVariant aVarInitVals;
617 aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
618 hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
619 if( !SUCCEEDED( hr ) ) return hr;
622 return S_OK;
625 HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
627 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
628 long ix = 0;
629 CComPtr<IDispatch> pdispPropVal;
630 HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
631 if( !SUCCEEDED( hr ) ) return hr;
633 OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
634 CComVariant pPropVar[2];
635 pPropVar[0] = CComVariant( sArgName );
636 pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
637 hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
638 if( !SUCCEEDED( hr ) ) return hr;
640 SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
642 CComVariant aDispArgs[4];
643 aDispArgs[3] = CComVariant( sUrl );
644 aDispArgs[2] = CComVariant( L"_self" );
645 aDispArgs[1] = CComVariant( 0 );
646 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
647 aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
649 CComVariant dummyResult;
650 hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
651 if( !SUCCEEDED( hr ) ) return hr;
653 return S_OK;
656 HRESULT CSOActiveX::CallDispatchMethod( OLECHAR* sUrl,
657 CComVariant* aArgNames,
658 CComVariant* aArgVals,
659 unsigned int count )
661 CComPtr<IDispatch> pdispURL;
662 HRESULT hr = GetUrlStruct( sUrl, pdispURL );
663 if( !SUCCEEDED( hr ) ) return hr;
665 CComPtr<IDispatch> pdispXDispatch;
666 CComVariant aArgs[3];
667 aArgs[2] = CComVariant( pdispURL );
668 aArgs[1] = CComVariant( L"" );
669 aArgs[0] = CComVariant( (int)0 );
670 hr = GetIDispByFunc( mpDispFrame,
671 L"queryDispatch",
672 aArgs,
674 pdispXDispatch );
675 if( !SUCCEEDED( hr ) ) return hr;
677 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, count );
678 for( long ix = 0; ix < (long)count; ix ++ )
680 CComPtr<IDispatch> pdispPropVal;
681 hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
682 if( !SUCCEEDED( hr ) ) return hr;
684 OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
685 CComVariant pPropVar[2];
686 pPropVar[0] = aArgNames[ix];
687 pPropVar[1] = aArgVals[ix];
688 hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
689 if( !SUCCEEDED( hr ) ) return hr;
691 SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
694 CComVariant aDispArgs[2];
695 aDispArgs[1] = CComVariant( pdispURL );
696 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
697 aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
699 CComVariant dummyResult;
700 hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
701 if( !SUCCEEDED( hr ) ) return hr;
703 return S_OK;
706 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
708 if ( mbReadyForActivation )
709 return;
711 BOOL bSuccess = FALSE;
712 BOOL bFinishDownload = FALSE;
713 if ( !pBytes )
715 // means the download is finished, dwSize contains hresult
716 bFinishDownload = TRUE;
717 if ( SUCCEEDED( dwSize ) )
718 bSuccess = TRUE;
720 else
722 HRESULT hr = S_OK;
724 if ( !mpDispTempFile )
726 CComVariant aServiceName( L"com.sun.star.io.TempFile" );
727 hr = GetIDispByFunc( mpDispFactory,
728 L"createInstance",
729 &aServiceName,
731 mpDispTempFile );
734 if( SUCCEEDED( hr ) && mpDispTempFile )
736 SAFEARRAY FAR* pDataArray = SafeArrayCreateVector( VT_I1, 0, dwSize );
738 if ( pDataArray )
740 hr = SafeArrayLock( pDataArray );
741 if ( SUCCEEDED( hr ) )
743 for( DWORD ix = 0; ix < dwSize; ix++ )
744 ((BYTE*)(pDataArray->pvData))[ix] = pBytes[ix];
745 hr = SafeArrayUnlock( pDataArray );
746 if ( SUCCEEDED( hr ) )
748 CComVariant aArgs[1];
749 aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
750 CComVariant dummyResult;
751 hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
752 if( SUCCEEDED( hr ) )
753 bSuccess = TRUE;
760 if ( !bSuccess )
762 // the download failed, let StarOffice download
763 bFinishDownload = TRUE;
764 mpDispTempFile = CComPtr< IDispatch >();
767 if ( bFinishDownload )
769 // trigger the loading now
770 mbLoad = TRUE;
771 mbReadyForActivation = TRUE;
773 Invalidate();
774 UpdateWindow();
778 HRESULT CSOActiveX::LoadURLToFrame( )
780 CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
781 CComVariant aArgVals[4];
782 unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
784 aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
785 aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
786 aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
788 if ( mpDispTempFile )
790 aArgVals[3] = CComVariant( mpDispTempFile );
791 nCount = 4;
794 HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
795 if( !SUCCEEDED( hr ) ) return hr;
797 CComVariant aBarName( L"MenuBarVisible" );
798 CComVariant aBarVis;
799 aBarVis.vt = VT_BOOL; aBarVis.boolVal = VARIANT_FALSE;
800 hr = CallDispatchMethod( L"slot:6661", &aBarName, &aBarVis, 1 );
801 // does not work for some documents, but it is no error
802 // if( !SUCCEEDED( hr ) ) return hr;
804 // try to get the model and set the presetation specific property, the setting will fail for other document formats
805 CComPtr<IDispatch> pdispController;
806 hr = GetIDispByFunc( mpDispFrame, L"getController", NULL, 0, pdispController );
807 if ( SUCCEEDED( hr ) && pdispController )
809 CComPtr<IDispatch> pdispModel;
810 hr = GetIDispByFunc( pdispController, L"getModel", NULL, 0, pdispModel );
811 if ( SUCCEEDED( hr ) && pdispModel )
813 CComPtr<IDispatch> pdispPres;
814 hr = GetIDispByFunc( pdispModel, L"getPresentation", NULL, 0, pdispPres );
815 if ( SUCCEEDED( hr ) && pdispPres )
817 // this is a presentation
818 // let the slide show be shown in the document window
819 OLECHAR* pPropName = L"IsFullScreen";
820 CComVariant pPresProp;
821 pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
822 hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
824 // start the slide show
825 if ( SUCCEEDED( hr ) )
827 CComVariant dummyResult;
828 ExecuteFunc( pdispPres, L"Start", NULL, 0, &dummyResult );
834 // create dispatch interceptor
835 mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
836 mpDispatchInterceptor->AddRef();
837 mpDispatchInterceptor->SetParent( this );
838 CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
840 // register dispatch interceptor in the frame
841 CComVariant aDispVariant( pIDispDispInter );
842 CComVariant dummyResult;
843 hr = ExecuteFunc( mpDispFrame,
844 L"registerDispatchProviderInterceptor",
845 &aDispVariant,
847 &dummyResult );
849 if( !SUCCEEDED( hr ) ) return hr;
851 return S_OK;
854 SOVersion CSOActiveX::GetVersionConnected()
856 SOVersion bResult = SO_NOT_DETECTED;
857 if( mpDispFactory )
859 // create ConfigurationProvider instance
860 CComPtr<IDispatch> pdispConfProv;
861 CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
862 HRESULT hr = GetIDispByFunc( mpDispFactory,
863 L"createInstance",
864 &aServiceName,
866 pdispConfProv );
868 if( SUCCEEDED( hr ) && pdispConfProv )
870 CComPtr<IDispatch> pdispConfAccess;
872 SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
874 if( pInitParams )
876 long ix = 0;
877 CComVariant aConfPath( L"org.openoffice.Setup" );
878 SafeArrayPutElement( pInitParams, &ix, &aConfPath );
880 CComVariant aArgs[2];
881 aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
882 aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
884 hr = GetIDispByFunc( pdispConfProv,
885 L"createInstanceWithArguments",
886 aArgs,
888 pdispConfAccess );
890 if( SUCCEEDED( hr ) && pdispConfAccess )
892 CComVariant aOfficeName;
894 CComVariant aProductName( L"Product/ooName" );
895 hr = ExecuteFunc( pdispConfAccess,
896 L"getByHierarchicalName",
897 &aProductName,
899 &aOfficeName );
901 if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
903 CComVariant aOfficeVersion;
905 CComVariant aProductVersion( L"Product/ooSetupVersion" );
906 hr = ExecuteFunc( pdispConfAccess,
907 L"getByHierarchicalName",
908 &aProductVersion,
910 &aOfficeVersion );
912 if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
914 USES_CONVERSION;
915 if( !strcmp( OLE2T( aOfficeName.bstrVal ), "StarOffice" ) )
917 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.1", 3 ) )
918 bResult = SO_61;
919 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.0", 3 ) )
920 bResult = SO_60;
921 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "5.2", 3 ) )
922 bResult = SO_52;
923 else
924 bResult = SO_UNKNOWN;
926 else // OpenOffice
928 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.1", 3 ) )
929 bResult = OO_11;
930 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.0", 3 ) )
931 bResult = OO_10;
932 else
933 bResult = OO_UNKNOWN;
942 return bResult;
945 class LockingGuard
947 BOOL& mbLocked;
948 public:
949 LockingGuard( BOOL& bLocked )
950 : mbLocked( bLocked )
952 mbLocked = TRUE;
955 ~LockingGuard()
957 mbLocked = FALSE;
961 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
963 // This method is called only in main thread, no need to lock it
965 // Get read of reentrance problems
966 if ( mbDrawLocked )
967 return S_OK;
968 LockingGuard aGuard( mbDrawLocked );
970 if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
972 HWND hwnd;
973 HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
974 if( !SUCCEEDED( hr ) ) return hr;
976 if( mParentWin != hwnd || !mOffWin )
978 if( mpDispFrame )
980 CComVariant dummyResult;
981 CComVariant aPropVar;
982 aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
983 HRESULT hr = ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
984 (void)hr;
985 mpDispFrame = CComPtr<IDispatch>();
988 mParentWin = hwnd;
989 mOffWin = CreateWindow(
990 STAROFFICE_WINDOWCLASS,
991 "OfficeContainer",
992 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
993 di.prcBounds->left,
994 di.prcBounds->top,
995 di.prcBounds->right - di.prcBounds->left,
996 di.prcBounds->bottom - di.prcBounds->top,
997 mParentWin,
998 NULL,
999 NULL,
1000 NULL );
1002 ::ShowWindow( mOffWin, SW_SHOW );
1004 else
1006 RECT aRect;
1007 ::GetWindowRect( mOffWin, &aRect );
1009 if( aRect.left != di.prcBounds->left || aRect.top != di.prcBounds->top
1010 || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
1012 // on this state the office window should exist already
1013 ::SetWindowPos( mOffWin,
1014 HWND_TOP,
1015 di.prcBounds->left,
1016 di.prcBounds->top,
1017 di.prcBounds->right - di.prcBounds->left,
1018 di.prcBounds->bottom - di.prcBounds->top,
1019 SWP_NOZORDER );
1021 CComVariant aPosArgs[5];
1022 aPosArgs[4] = CComVariant( 0 );
1023 aPosArgs[3] = CComVariant( 0 );
1024 aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
1025 aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
1026 aPosArgs[0] = CComVariant( 12 );
1027 CComVariant dummyResult;
1028 hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
1029 if( !SUCCEEDED( hr ) ) return hr;
1033 if( !mnVersion )
1035 OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
1036 return E_FAIL;
1039 if( ! mpDispFrame )
1041 hr = CreateFrameOldWay( mOffWin,
1042 di.prcBounds->right - di.prcBounds->left,
1043 di.prcBounds->bottom - di.prcBounds->top );
1045 if( !SUCCEEDED( hr ) )
1047 // if the frame can not be opened do not try any more
1048 mbReadyForActivation = FALSE;
1049 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1050 return hr;
1054 if( mbLoad )
1056 hr = LoadURLToFrame();
1057 mbLoad = FALSE;
1059 if( !SUCCEEDED( hr ) )
1061 // if the document can not be opened do not try any more
1062 mbReadyForActivation = FALSE;
1064 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1066 return hr;
1070 else
1072 // activate the fallback
1073 CComControl<CSOActiveX>::OnDrawAdvanced( di );
1076 return S_OK;
1079 HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
1081 // fallback that is activated by the parent class
1082 if ( di.hdcDraw )
1083 FillRect( di.hdcDraw, (RECT*)di.prcBounds, (HBRUSH)COLOR_BACKGROUND );
1085 return S_OK;
1088 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
1090 HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
1092 if( !aClientSite )
1094 //ATLASSERT( mWebBrowser2 );
1095 if( mWebBrowser2 )
1096 AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
1097 return hr;
1100 CComPtr<IOleContainer> aContainer;
1101 m_spClientSite->GetContainer( &aContainer );
1102 // ATLASSERT( aContainer );
1104 if( SUCCEEDED( hr ) && aContainer )
1106 CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
1107 //ATLASSERT( aServiceProvider );
1109 if( aServiceProvider )
1111 aServiceProvider->QueryService( SID_SInternetExplorer,
1112 IID_IWebBrowser,
1113 (void**)&mWebBrowser2 );
1114 // ATLASSERT( mWebBrowser2 );
1115 if( mWebBrowser2 )
1116 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
1120 return hr;
1123 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
1124 REFIID riid,
1125 LCID lcid,
1126 WORD wFlags,
1127 DISPPARAMS* pDispParams,
1128 VARIANT* pvarResult,
1129 EXCEPINFO* pExcepInfo,
1130 UINT* puArgErr)
1132 if (riid != IID_NULL)
1133 return DISP_E_UNKNOWNINTERFACE;
1135 if (!pDispParams)
1136 return DISP_E_PARAMNOTOPTIONAL;
1138 if ( dispidMember == DISPID_ONQUIT )
1139 Cleanup();
1141 IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
1142 &LIBID_SO_ACTIVEXLib>::Invoke(
1143 dispidMember, riid, lcid, wFlags, pDispParams,
1144 pvarResult, pExcepInfo, puArgErr);
1146 return S_OK;
1149 HRESULT CSOActiveX::GetURL( const OLECHAR* url,
1150 const OLECHAR* target )
1152 CComVariant aEmpty1, aEmpty2, aEmpty3;
1153 CComVariant aUrl( url );
1154 CComVariant aTarget;
1155 if ( target )
1156 aTarget = CComVariant( target );
1158 return mWebBrowser2->Navigate2( &aUrl,
1159 &aEmpty1,
1160 &aTarget,
1161 &aEmpty2,
1162 &aEmpty3 );
1168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */