merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / activex / main / SOActiveX.cpp
blob52833ae17587d15a90407984991ddafdcedb6a17
1 // SOActiveX.cpp : Implementation of CSOActiveX
3 #pragma warning (disable:4505)
4 // permanently suppress "unreferenced local function has been removed" warning
6 #pragma warning (push,1)
7 #pragma warning (disable:4265)
9 #include "stdafx2.h"
10 #include "so_activex.h"
11 #include "SOActiveX.h"
12 #include "SOComWindowPeer.h"
13 #include "SODispatchInterceptor.h"
14 #include "SOActionsApproval.h"
16 #pragma warning (pop)
18 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
21 /////////////////////////////////////////////////////////////////////////////
23 void OutputError_Impl( HWND hw, HRESULT ErrorCode )
25 void* sMessage;
26 FormatMessageA(
27 FORMAT_MESSAGE_ALLOCATE_BUFFER |
28 FORMAT_MESSAGE_FROM_SYSTEM,
29 NULL,
30 ErrorCode,
31 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
32 (LPTSTR) &sMessage,
34 NULL
36 ::MessageBoxA( hw, (LPCTSTR)sMessage, NULL, MB_OK | MB_ICONINFORMATION );
37 LocalFree( sMessage );
40 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
41 OLECHAR* sFuncName,
42 CComVariant* params,
43 unsigned int count,
44 CComVariant* pResult )
46 if( !idispUnoObject )
47 return E_FAIL;
49 DISPID id;
50 HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
51 if( !SUCCEEDED( hr ) ) return hr;
53 DISPPARAMS dispparams= { params, 0, count, 0};
55 // DEBUG
56 EXCEPINFO myInfo;
57 hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
58 &dispparams, pResult, &myInfo, 0);
60 // for debugging purposes
61 // USES_CONVERSION;
62 // if ( !SUCCEEDED( hr ) )
63 // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
65 return hr;
68 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
69 OLECHAR* sFuncName,
70 CComVariant* params,
71 unsigned int count,
72 CComPtr<IDispatch>& pdispResult )
74 if( !idispUnoObject )
75 return E_FAIL;
77 CComVariant result;
78 HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
79 if( !SUCCEEDED( hr ) ) return hr;
81 if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
82 return E_FAIL;
84 pdispResult = CComPtr<IDispatch>( result.pdispVal );
86 return S_OK;
89 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
90 OLECHAR** sMemberNames,
91 CComVariant* pVariant,
92 unsigned int count )
94 for( unsigned int ind = 0; ind < count; ind++ )
96 DISPID id;
97 HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
98 if( !SUCCEEDED( hr ) ) return hr;
100 hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
101 if( !SUCCEEDED( hr ) ) return hr;
104 return S_OK;
107 HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
108 OLECHAR** sMemberNames,
109 CComVariant* pVariant,
110 unsigned int count )
112 for( unsigned int ind = 0; ind < count; ind++ )
114 DISPID id;
115 HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
116 if( !SUCCEEDED( hr ) ) return hr;
118 hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
119 if( !SUCCEEDED( hr ) ) return hr;
122 return S_OK;
124 /////////////////////////////////////////////////////////////////////////////
125 // CSOActiveX
127 CSOActiveX::CSOActiveX()
128 : mCookie(0)
129 , mCurFileUrl( L"private:factory/swriter" )
130 , mbLoad( FALSE )
131 , mParentWin( NULL )
132 , mOffWin( NULL )
133 , mbViewOnly( TRUE )
134 , mpDispatchInterceptor( NULL )
135 , mnVersion( SO_NOT_DETECTED )
136 , mbReadyForActivation( FALSE )
137 , mbDrawLocked( FALSE )
139 CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
140 HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
141 if( !SUCCEEDED( hr ) )
142 OutputError_Impl( NULL, hr );
144 mPWinClass.style = CS_HREDRAW|CS_VREDRAW;
145 mPWinClass.lpfnWndProc = ::DefWindowProc;
146 mPWinClass.cbClsExtra = 0;
147 mPWinClass.cbWndExtra = 0;
148 mPWinClass.hInstance = (HINSTANCE) GetModuleHandle(NULL); //myInstance;
149 mPWinClass.hIcon = NULL;
150 mPWinClass.hCursor = NULL;
151 mPWinClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
152 mPWinClass.lpszMenuName = NULL;
153 mPWinClass.lpszClassName = STAROFFICE_WINDOWCLASS;
155 RegisterClass(&mPWinClass);
158 CSOActiveX::~CSOActiveX()
160 Cleanup();
164 HRESULT CSOActiveX::Cleanup()
166 CComVariant dummyResult;
168 if( mpDispatchInterceptor )
170 if( mpDispFrame )
172 // remove dispatch interceptor
173 CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
174 CComVariant aVariant( pIDispDispInter );
175 ExecuteFunc( mpDispFrame,
176 L"releaseDispatchProviderInterceptor",
177 &aVariant,
179 &dummyResult );
182 mpDispatchInterceptor->ClearParent();
183 mpDispatchInterceptor->Release();
184 mpDispatchInterceptor = NULL;
187 mpDispTempFile = CComPtr< IDispatch >();
188 mbReadyForActivation = FALSE;
190 if( mpInstanceLocker )
192 ExecuteFunc( mpInstanceLocker, L"dispose", NULL, 0, &dummyResult );
193 mpInstanceLocker = CComPtr< IDispatch >();
196 if( mpDispFrame )
198 BOOL bCloserActivated = FALSE;
200 CComPtr<IDispatch> pDispDocumentCloser;
201 CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
202 HRESULT hr = GetIDispByFunc( mpDispFactory,
203 L"createInstance",
204 &aDocCloser,
206 pDispDocumentCloser );
207 if ( SUCCEEDED( hr ) && pDispDocumentCloser )
209 SAFEARRAY FAR* pInitFrame = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
210 long nInitInd = 0;
211 CComVariant pFrameVariant( mpDispFrame );
212 SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
213 CComVariant aVarInitFrame;
214 aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
215 hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
216 if( SUCCEEDED( hr ) )
218 // the following call will let the closing happen
219 hr = ExecuteFunc( pDispDocumentCloser, L"dispose", NULL, 0, &dummyResult );
220 bCloserActivated = SUCCEEDED( hr );
224 if ( !bCloserActivated )
226 CComVariant aPropVar;
227 aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
228 if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
229 ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
232 mpDispFrame = CComPtr< IDispatch >();
235 if( ::IsWindow( mOffWin ) )
236 ::DestroyWindow( mOffWin );
238 TerminateOffice();
240 return S_OK;
243 HRESULT CSOActiveX::TerminateOffice()
245 // create desktop
246 CComPtr<IDispatch> pdispDesktop;
247 CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
249 HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
250 if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
252 // create tree of frames
253 CComPtr<IDispatch> pdispChildren;
254 hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
255 if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
257 CComVariant aFrames;
258 CComVariant nFlag( 4 );
259 hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
260 if ( SUCCEEDED( hr ) )
262 if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
263 && ( !aFrames.parray || aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0 ) )
265 // there is no frames open
266 // TODO: check whether the frames are hidden if they are open?
267 CComVariant dummyResult;
268 hr = ExecuteFunc( pdispDesktop, L"terminate", NULL, 0, &dummyResult );
272 return hr;
275 STDMETHODIMP CSOActiveX::InitNew ()
277 mnVersion = GetVersionConnected();
278 mbLoad = TRUE;
279 return S_OK;
282 STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
284 mnVersion = GetVersionConnected();
285 mbLoad = TRUE;
287 // may be later?
288 // for now just ignore
290 return S_OK;
293 STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
295 mnVersion = GetVersionConnected();
297 IPropertyBag2* pPropBag2;
298 HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
299 //ATLASSERT( hr >= 0 );
301 if( !SUCCEEDED( hr ) )
302 return hr;
304 unsigned long aNum;
305 hr = pPropBag2->CountProperties( &aNum );
306 //ATLASSERT( hr >= 0 );
307 if( !SUCCEEDED( hr ) )
308 return hr;
310 PROPBAG2* aPropNames = new PROPBAG2[aNum];
311 unsigned long aReaded;
313 hr = pPropBag2->GetPropertyInfo( 0,
314 aNum,
315 aPropNames,
316 &aReaded );
317 //ATLASSERT( hr >= 0 );
318 if( !SUCCEEDED( hr ) )
320 delete[] aPropNames;
321 return hr;
324 CComVariant* aVal = new CComVariant[aNum];
325 HRESULT* hvs = new HRESULT[aNum];
326 hr = pPropBag2->Read( aNum,
327 aPropNames,
328 NULL,
329 aVal,
330 hvs );
331 //ATLASSERT( hr >= 0 );
332 if( !SUCCEEDED( hr ) )
334 delete[] hvs;
335 delete[] aVal;
336 delete[] aPropNames;
337 return hr;
340 USES_CONVERSION;
341 for( unsigned long ind = 0; ind < aNum; ind++ )
343 // all information from the 'object' tag is in strings
344 if( aVal[ind].vt == VT_BSTR && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
346 mCurFileUrl = wcsdup( aVal[ind].bstrVal );
348 else if( aVal[ind].vt == VT_BSTR
349 && !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
351 if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
353 // the default value
354 mbViewOnly = TRUE;
356 else
358 mbViewOnly = FALSE;
363 delete[] hvs;
364 delete[] aVal;
365 delete[] aPropNames;
367 if( !mpDispFactory )
368 return hr;
370 mbReadyForActivation = FALSE;
371 hr = CBindStatusCallback<CSOActiveX>::Download( this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE );
372 if ( hr == MK_S_ASYNCHRONOUS )
373 hr = S_OK;
375 if ( !SUCCEEDED( hr ) )
377 // trigger initialization without stream
378 mbLoad = TRUE;
380 Invalidate();
381 UpdateWindow();
384 return hr;
387 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
389 CComVariant aComStruct( sStructName );
390 return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
393 HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
395 HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
396 if( !SUCCEEDED( hr ) ) return hr;
398 OLECHAR* sURLMemberName = L"Complete";
399 DISPID nURLID;
400 hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
401 if( !SUCCEEDED( hr ) ) return hr;
402 CComVariant aComUrl( sUrl );
403 hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
404 if( !SUCCEEDED( hr ) ) return hr;
406 CComPtr<IDispatch> pdispTransformer;
407 CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
408 hr = GetIDispByFunc( mpDispFactory,
409 L"createInstance",
410 &aServiceName,
412 pdispTransformer );
413 if( !SUCCEEDED( hr ) ) return hr;
415 CComVariant dummyResult;
416 CComVariant aParam[2];
417 aParam[1].ppdispVal = &pdispUrl;
418 aParam[1].vt = VT_DISPATCH | VT_BYREF;
419 aParam[0] = CComVariant( L"file:///" );
421 hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
422 if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
424 return S_OK;
427 HRESULT CSOActiveX::SetLayoutManagerProps()
429 if ( !mpDispFrame )
430 return E_FAIL;
432 CComVariant pVarLayoutMgr;
433 OLECHAR* sLMPropName = L"LayoutManager";
434 HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
435 if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == NULL )
436 return E_FAIL;
438 CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
441 if( !SUCCEEDED( hr ) || !pdispLM )
442 return E_FAIL;
444 OLECHAR* sATName = L"AutomaticToolbars";
445 CComVariant pATProp;
446 pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
447 hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
449 return hr;
452 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
454 if( !mpDispFactory )
455 return E_FAIL;
457 // create window handle holder
458 CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
459 pPeerToSend->SetHWNDInternally( hwnd );
460 CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
462 // create rectangle structure
463 CComPtr<IDispatch> pdispRectangle;
464 HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
465 if( !SUCCEEDED( hr ) ) return hr;
467 OLECHAR* sRectMemberNames[4] = { L"X",
468 L"Y",
469 L"Width",
470 L"Height" };
471 CComVariant pRectVariant[4];
472 pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
474 hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
475 if( !SUCCEEDED( hr ) ) return hr;
477 // create WindowDescriptor structure
478 CComPtr<IDispatch> pdispWinDescr;
479 hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
480 if( !SUCCEEDED( hr ) ) return hr;
482 // fill in descriptor with info
483 OLECHAR* sDescriptorMemberNames[6] = { L"Type",
484 L"WindowServiceName",
485 L"ParentIndex",
486 L"Parent",
487 L"Bounds",
488 L"WindowAttributes" };
489 CComVariant pDescriptorVar[6];
490 pDescriptorVar[0] = CComVariant( 0 );
491 pDescriptorVar[1] = CComVariant( L"workwindow" );
492 pDescriptorVar[2] = CComVariant( 1 );
493 pDescriptorVar[3] = CComVariant( pIDispToSend );
494 pDescriptorVar[4] = CComVariant( pdispRectangle );
495 pDescriptorVar[5] = CComVariant( 33 );
496 hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
497 if( !SUCCEEDED( hr ) ) return hr;
499 // create XToolkit instance
500 CComPtr<IDispatch> pdispToolkit;
501 CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
502 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
503 if( !SUCCEEDED( hr ) ) return hr;
505 // create window with toolkit
506 CComVariant aWinDescr( pdispWinDescr );
507 hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
508 if( !SUCCEEDED( hr ) ) return hr;
510 // create frame
511 aServiceName = CComVariant( L"com.sun.star.frame.Task" );
512 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
513 if( !SUCCEEDED( hr ) || !mpDispFrame )
515 // the interface com.sun.star.frame.Task is removed in 6.1
516 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
517 aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
518 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
519 if( !SUCCEEDED( hr ) ) return hr;
522 // initialize frame
523 CComVariant dummyResult;
524 CComVariant aDispWin( mpDispWin );
525 hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
526 if( !SUCCEEDED( hr ) ) return hr;
528 // set some properties to the layout manager, ignore errors for now
529 SetLayoutManagerProps();
531 // create desktop
532 CComPtr<IDispatch> pdispDesktop;
533 aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
534 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
535 if( !SUCCEEDED( hr ) ) return hr;
537 // create tree of frames
538 CComPtr<IDispatch> pdispChildren;
539 hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
540 if( !SUCCEEDED( hr ) ) return hr;
542 // insert new frame into desctop hierarchy
543 CComVariant aDispFrame( mpDispFrame );
544 hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
545 if( !SUCCEEDED( hr ) ) return hr;
547 // initialize window
548 CComVariant aTransparent( (long)0xFFFFFFFF );
549 hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
550 if( !SUCCEEDED( hr ) ) return hr;
552 CComVariant aTrue( TRUE );
553 hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
554 if( !SUCCEEDED( hr ) ) return hr;
556 CComVariant aPosArgs[5];
557 aPosArgs[4] = CComVariant( 0 );
558 aPosArgs[3] = CComVariant( 0 );
559 aPosArgs[2] = CComVariant( width );
560 aPosArgs[1] = CComVariant( height );
561 aPosArgs[0] = CComVariant( 12 );
562 hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
563 if( !SUCCEEDED( hr ) ) return hr;
565 // create frame locker if there is such service
566 aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
567 hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
568 if( SUCCEEDED( hr ) && mpInstanceLocker )
570 SAFEARRAY FAR* pInitVals = SafeArrayCreateVector( VT_VARIANT, 0, 3 );
572 // the first sequence element
573 long nInitInd = 0;
574 CComVariant pFrameVariant( mpDispFrame );
575 SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
577 // the second sequence element
578 nInitInd = 1;
579 CComVariant pStrArr( 1L );
580 SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
582 // the third sequence element
583 nInitInd = 2;
584 CComPtr<IDispatch> pdispValueObj;
585 hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", NULL, 0, pdispValueObj );
586 if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
588 CComVariant aValueArgs[2];
589 aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
590 CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
591 aValueArgs[0] = CComVariant ( pApproval );
593 hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
594 if( !SUCCEEDED( hr ) ) return hr;
596 CComVariant aValueObj( pdispValueObj );
597 SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
599 // execute initialize()
600 CComVariant aVarInitVals;
601 aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
602 hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
603 if( !SUCCEEDED( hr ) ) return hr;
606 return S_OK;
609 HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
611 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
612 long ix = 0;
613 CComPtr<IDispatch> pdispPropVal;
614 HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
615 if( !SUCCEEDED( hr ) ) return hr;
617 OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
618 CComVariant pPropVar[2];
619 pPropVar[0] = CComVariant( sArgName );
620 pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
621 hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
622 if( !SUCCEEDED( hr ) ) return hr;
624 SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
626 CComVariant aDispArgs[4];
627 aDispArgs[3] = CComVariant( sUrl );
628 aDispArgs[2] = CComVariant( L"_self" );
629 aDispArgs[1] = CComVariant( 0 );
630 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
631 aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
633 CComVariant dummyResult;
634 hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
635 if( !SUCCEEDED( hr ) ) return hr;
637 return S_OK;
640 HRESULT CSOActiveX::CallDispatchMethod( OLECHAR* sUrl,
641 CComVariant* aArgNames,
642 CComVariant* aArgVals,
643 unsigned int count )
645 CComPtr<IDispatch> pdispURL;
646 HRESULT hr = GetUrlStruct( sUrl, pdispURL );
647 if( !SUCCEEDED( hr ) ) return hr;
649 CComPtr<IDispatch> pdispXDispatch;
650 CComVariant aArgs[3];
651 aArgs[2] = CComVariant( pdispURL );
652 aArgs[1] = CComVariant( L"" );
653 aArgs[0] = CComVariant( (int)0 );
654 hr = GetIDispByFunc( mpDispFrame,
655 L"queryDispatch",
656 aArgs,
658 pdispXDispatch );
659 if( !SUCCEEDED( hr ) ) return hr;
661 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, count );
662 for( long ix = 0; ix < (long)count; ix ++ )
664 CComPtr<IDispatch> pdispPropVal;
665 hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
666 if( !SUCCEEDED( hr ) ) return hr;
668 OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
669 CComVariant pPropVar[2];
670 pPropVar[0] = aArgNames[ix];
671 pPropVar[1] = aArgVals[ix];
672 hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
673 if( !SUCCEEDED( hr ) ) return hr;
675 SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
678 CComVariant aDispArgs[2];
679 aDispArgs[1] = CComVariant( pdispURL );
680 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
681 aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
683 CComVariant dummyResult;
684 hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
685 if( !SUCCEEDED( hr ) ) return hr;
687 return S_OK;
690 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
692 if ( mbReadyForActivation )
693 return;
695 BOOL bSuccess = FALSE;
696 BOOL bFinishDownload = FALSE;
697 if ( !pBytes )
699 // means the download is finished, dwSize contains hresult
700 bFinishDownload = TRUE;
701 if ( SUCCEEDED( dwSize ) )
702 bSuccess = TRUE;
704 else
706 HRESULT hr = S_OK;
708 if ( !mpDispTempFile )
710 CComVariant aServiceName( L"com.sun.star.io.TempFile" );
711 hr = GetIDispByFunc( mpDispFactory,
712 L"createInstance",
713 &aServiceName,
715 mpDispTempFile );
718 if( SUCCEEDED( hr ) && mpDispTempFile )
720 SAFEARRAY FAR* pDataArray = SafeArrayCreateVector( VT_I1, 0, dwSize );
722 if ( pDataArray )
724 hr = SafeArrayLock( pDataArray );
725 if ( SUCCEEDED( hr ) )
727 for( DWORD ix = 0; ix < dwSize; ix++ )
728 ((BYTE*)(pDataArray->pvData))[ix] = pBytes[ix];
729 hr = SafeArrayUnlock( pDataArray );
730 if ( SUCCEEDED( hr ) )
732 CComVariant aArgs[1];
733 aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
734 CComVariant dummyResult;
735 hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
736 if( SUCCEEDED( hr ) )
737 bSuccess = TRUE;
744 if ( !bSuccess )
746 // the download failed, let StarOffice download
747 bFinishDownload = TRUE;
748 mpDispTempFile = CComPtr< IDispatch >();
751 if ( bFinishDownload )
753 // trigger the loading now
754 mbLoad = TRUE;
755 mbReadyForActivation = TRUE;
757 Invalidate();
758 UpdateWindow();
762 HRESULT CSOActiveX::LoadURLToFrame( )
764 CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
765 CComVariant aArgVals[4];
766 unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
768 aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
769 aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
770 aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
772 if ( mpDispTempFile )
774 aArgVals[3] = CComVariant( mpDispTempFile );
775 nCount = 4;
778 HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
779 if( !SUCCEEDED( hr ) ) return hr;
781 CComVariant aBarName( L"MenuBarVisible" );
782 CComVariant aBarVis;
783 aBarVis.vt = VT_BOOL; aBarVis.boolVal = VARIANT_FALSE;
784 hr = CallDispatchMethod( L"slot:6661", &aBarName, &aBarVis, 1 );
785 // does not work for some documents, but it is no error
786 // if( !SUCCEEDED( hr ) ) return hr;
788 // try to get the model and set the presetation specific property, the setting will fail for other document formats
789 CComPtr<IDispatch> pdispController;
790 hr = GetIDispByFunc( mpDispFrame, L"getController", NULL, 0, pdispController );
791 if ( SUCCEEDED( hr ) && pdispController )
793 CComPtr<IDispatch> pdispModel;
794 hr = GetIDispByFunc( pdispController, L"getModel", NULL, 0, pdispModel );
795 if ( SUCCEEDED( hr ) && pdispModel )
797 CComPtr<IDispatch> pdispPres;
798 hr = GetIDispByFunc( pdispModel, L"getPresentation", NULL, 0, pdispPres );
799 if ( SUCCEEDED( hr ) && pdispPres )
801 // this is a presentation
802 // let the slide show be shown in the document window
803 OLECHAR* pPropName = L"IsFullScreen";
804 CComVariant pPresProp;
805 pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
806 hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
808 // start the slide show
809 if ( SUCCEEDED( hr ) )
811 CComVariant dummyResult;
812 ExecuteFunc( pdispPres, L"Start", NULL, 0, &dummyResult );
818 // create dispatch interceptor
819 mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
820 mpDispatchInterceptor->AddRef();
821 mpDispatchInterceptor->SetParent( this );
822 CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
824 // register dispatch interceptor in the frame
825 CComVariant aDispVariant( pIDispDispInter );
826 CComVariant dummyResult;
827 hr = ExecuteFunc( mpDispFrame,
828 L"registerDispatchProviderInterceptor",
829 &aDispVariant,
831 &dummyResult );
833 if( !SUCCEEDED( hr ) ) return hr;
835 return S_OK;
838 SOVersion CSOActiveX::GetVersionConnected()
840 SOVersion bResult = SO_NOT_DETECTED;
841 if( mpDispFactory )
843 // create ConfigurationProvider instance
844 CComPtr<IDispatch> pdispConfProv;
845 CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
846 HRESULT hr = GetIDispByFunc( mpDispFactory,
847 L"createInstance",
848 &aServiceName,
850 pdispConfProv );
852 if( SUCCEEDED( hr ) && pdispConfProv )
854 CComPtr<IDispatch> pdispConfAccess;
856 SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
858 if( pInitParams )
860 long ix = 0;
861 CComVariant aConfPath( L"org.openoffice.Setup" );
862 SafeArrayPutElement( pInitParams, &ix, &aConfPath );
864 CComVariant aArgs[2];
865 aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
866 aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
868 hr = GetIDispByFunc( pdispConfProv,
869 L"createInstanceWithArguments",
870 aArgs,
872 pdispConfAccess );
874 if( SUCCEEDED( hr ) && pdispConfAccess )
876 CComVariant aOfficeName;
878 CComVariant aProductName( L"Product/ooName" );
879 hr = ExecuteFunc( pdispConfAccess,
880 L"getByHierarchicalName",
881 &aProductName,
883 &aOfficeName );
885 if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
887 CComVariant aOfficeVersion;
889 CComVariant aProductVersion( L"Product/ooSetupVersion" );
890 hr = ExecuteFunc( pdispConfAccess,
891 L"getByHierarchicalName",
892 &aProductVersion,
894 &aOfficeVersion );
896 if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
898 USES_CONVERSION;
899 if( !strcmp( OLE2T( aOfficeName.bstrVal ), "StarOffice" ) )
901 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.1", 3 ) )
902 bResult = SO_61;
903 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.0", 3 ) )
904 bResult = SO_60;
905 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "5.2", 3 ) )
906 bResult = SO_52;
907 else
908 bResult = SO_UNKNOWN;
910 else // OpenOffice
912 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.1", 3 ) )
913 bResult = OO_11;
914 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.0", 3 ) )
915 bResult = OO_10;
916 else
917 bResult = OO_UNKNOWN;
926 return bResult;
929 class LockingGuard
931 BOOL& mbLocked;
932 public:
933 LockingGuard( BOOL& bLocked )
934 : mbLocked( bLocked )
936 mbLocked = TRUE;
939 ~LockingGuard()
941 mbLocked = FALSE;
945 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
947 // This method is called only in main thread, no need to lock it
949 // Get read of reentrance problems
950 if ( mbDrawLocked )
951 return S_OK;
952 LockingGuard aGuard( mbDrawLocked );
954 if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
956 HWND hwnd;
957 HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
958 if( !SUCCEEDED( hr ) ) return hr;
960 if( mParentWin != hwnd || !mOffWin )
962 if( mpDispFrame )
964 CComVariant dummyResult;
965 CComVariant aPropVar;
966 aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
967 HRESULT hr = ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
968 (void)hr;
969 mpDispFrame = CComPtr<IDispatch>();
972 mParentWin = hwnd;
973 mOffWin = CreateWindow(
974 STAROFFICE_WINDOWCLASS,
975 "OfficeContainer",
976 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
977 di.prcBounds->left,
978 di.prcBounds->top,
979 di.prcBounds->right - di.prcBounds->left,
980 di.prcBounds->bottom - di.prcBounds->top,
981 mParentWin,
982 NULL,
983 NULL,
984 NULL );
986 ::ShowWindow( mOffWin, SW_SHOW );
988 else
990 RECT aRect;
991 ::GetWindowRect( mOffWin, &aRect );
993 if( aRect.left != di.prcBounds->left || aRect.top != di.prcBounds->top
994 || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
996 // on this state the office window should exist already
997 ::SetWindowPos( mOffWin,
998 HWND_TOP,
999 di.prcBounds->left,
1000 di.prcBounds->top,
1001 di.prcBounds->right - di.prcBounds->left,
1002 di.prcBounds->bottom - di.prcBounds->top,
1003 SWP_NOZORDER );
1005 CComVariant aPosArgs[5];
1006 aPosArgs[4] = CComVariant( 0 );
1007 aPosArgs[3] = CComVariant( 0 );
1008 aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
1009 aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
1010 aPosArgs[0] = CComVariant( 12 );
1011 CComVariant dummyResult;
1012 hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
1013 if( !SUCCEEDED( hr ) ) return hr;
1017 if( !mnVersion )
1019 OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
1020 return E_FAIL;
1023 if( ! mpDispFrame )
1025 hr = CreateFrameOldWay( mOffWin,
1026 di.prcBounds->right - di.prcBounds->left,
1027 di.prcBounds->bottom - di.prcBounds->top );
1029 if( !SUCCEEDED( hr ) )
1031 // if the frame can not be opened do not try any more
1032 mbReadyForActivation = FALSE;
1033 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1034 return hr;
1038 if( mbLoad )
1040 hr = LoadURLToFrame();
1041 mbLoad = FALSE;
1043 if( !SUCCEEDED( hr ) )
1045 // if the document can not be opened do not try any more
1046 mbReadyForActivation = FALSE;
1048 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1050 return hr;
1054 else
1056 // activate the fallback
1057 CComControl<CSOActiveX>::OnDrawAdvanced( di );
1060 return S_OK;
1063 HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
1065 // fallback that is activated by the parent class
1066 if ( di.hdcDraw )
1067 FillRect( di.hdcDraw, (RECT*)di.prcBounds, (HBRUSH)COLOR_BACKGROUND );
1069 return S_OK;
1072 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
1074 HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
1076 if( !aClientSite )
1078 //ATLASSERT( mWebBrowser2 );
1079 if( mWebBrowser2 )
1080 AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
1081 return hr;
1084 CComPtr<IOleContainer> aContainer;
1085 m_spClientSite->GetContainer( &aContainer );
1086 // ATLASSERT( aContainer );
1088 if( SUCCEEDED( hr ) && aContainer )
1090 CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
1091 //ATLASSERT( aServiceProvider );
1093 if( aServiceProvider )
1095 aServiceProvider->QueryService( SID_SInternetExplorer,
1096 IID_IWebBrowser,
1097 (void**)&mWebBrowser2 );
1098 // ATLASSERT( mWebBrowser2 );
1099 if( mWebBrowser2 )
1100 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
1104 return hr;
1107 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
1108 REFIID riid,
1109 LCID lcid,
1110 WORD wFlags,
1111 DISPPARAMS* pDispParams,
1112 VARIANT* pvarResult,
1113 EXCEPINFO* pExcepInfo,
1114 UINT* puArgErr)
1116 if (riid != IID_NULL)
1117 return DISP_E_UNKNOWNINTERFACE;
1119 if (!pDispParams)
1120 return DISP_E_PARAMNOTOPTIONAL;
1122 if ( dispidMember == DISPID_ONQUIT )
1123 Cleanup();
1125 IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
1126 &LIBID_SO_ACTIVEXLib>::Invoke(
1127 dispidMember, riid, lcid, wFlags, pDispParams,
1128 pvarResult, pExcepInfo, puArgErr);
1130 return S_OK;
1133 HRESULT CSOActiveX::GetURL( const OLECHAR* url,
1134 const OLECHAR* target )
1136 CComVariant aEmpty1, aEmpty2, aEmpty3;
1137 CComVariant aUrl( url );
1138 CComVariant aTarget;
1139 if ( target )
1140 aTarget = CComVariant( target );
1142 return mWebBrowser2->Navigate2( &aUrl,
1143 &aEmpty1,
1144 &aTarget,
1145 &aEmpty2,
1146 &aEmpty3 );
1150 // ---------------------------------------------------------------------------