1 /*************************************************************************
3 * $RCSfile: SOActiveX.cpp,v $
7 * last change: $Author: hr $ $Date: 2003-06-30 15:49:35 $
9 * The Contents of this file are made available subject to the terms of
12 * Copyright (c) 2003 by Sun Microsystems, Inc.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *************************************************************************/
41 // SOActiveX.cpp : Implementation of CSOActiveX
44 #include "so_activex.h"
45 #include "SOActiveX.h"
46 #include "SOComWindowPeer.h"
48 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
51 #define BARS_TO_SHOW 2
53 OLECHAR
* pSlotUrl
[BARS_NUMBER
] =
54 {L
"slot:5910" // SID_TOGGLEFUNCTIONBAR
55 ,L
"slot:5920" // SID_TOGGLESTATUSBAR
56 ,L
"slot:6661" // SID_TOGGLE_MENUBAR
57 // ,L"slot:10603" // SID_HYPERLINK_INSERT
60 OLECHAR
* pSlotName
[BARS_NUMBER
] =
61 {L
"FunctionBarVisible" // SID_TOGGLEFUNCTIONBAR
62 ,L
"StatusBarVisible" // SID_TOGGLESTATUSBAR
63 ,L
"MenuBarVisible" // SID_TOGGLE_MENUBAR
64 // ,L"InsertHyperlink" // SID_HYPERLINK_INSERT
69 /////////////////////////////////////////////////////////////////////////////
71 HRESULT
ExecuteFunc( IDispatch
* idispUnoObject
,
75 CComVariant
* pResult
)
81 HRESULT hr
= idispUnoObject
->GetIDsOfNames( IID_NULL
, &sFuncName
, 1, LOCALE_USER_DEFAULT
, &id
);
82 if( !SUCCEEDED( hr
) ) return hr
;
84 DISPPARAMS dispparams
= { params
, 0, count
, 0};
88 return idispUnoObject
->Invoke( id
, IID_NULL
,LOCALE_USER_DEFAULT
, DISPATCH_METHOD
,
89 &dispparams
, pResult
, &myInfo
, 0);
92 HRESULT
GetIDispByFunc( IDispatch
* idispUnoObject
,
96 CComPtr
<IDispatch
>& pdispResult
)
102 HRESULT hr
= ExecuteFunc( idispUnoObject
, sFuncName
, params
, count
, &result
);
103 if( !SUCCEEDED( hr
) ) return hr
;
105 if( result
.vt
!= VT_DISPATCH
|| result
.pdispVal
== NULL
)
108 pdispResult
= CComPtr
<IDispatch
>( result
.pdispVal
);
113 HRESULT
PutPropertiesToIDisp( IDispatch
* pdispObject
,
114 OLECHAR
** sMemberNames
,
115 CComVariant
* pVariant
,
118 for( unsigned int ind
= 0; ind
< count
; ind
++ )
121 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, &sMemberNames
[ind
], 1, LOCALE_USER_DEFAULT
, &id
);
122 if( !SUCCEEDED( hr
) ) return hr
;
124 hr
= CComDispatchDriver::PutProperty( pdispObject
, id
, &pVariant
[ind
] );
125 if( !SUCCEEDED( hr
) ) return hr
;
131 /////////////////////////////////////////////////////////////////////////////
134 CSOActiveX::CSOActiveX()
136 , mCurFileUrl( L
"private:factory/swriter" )
140 , mbViewOnly( FALSE
)
142 CLSID clsFactory
= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
143 HRESULT hr
= CoCreateInstance( clsFactory
, NULL
, CLSCTX_ALL
, __uuidof(IDispatch
), (void**)&mpDispFactory
);
145 mPWinClass
.style
= CS_HREDRAW
|CS_VREDRAW
;
146 mPWinClass
.lpfnWndProc
= ::DefWindowProc
;
147 mPWinClass
.cbClsExtra
= 0;
148 mPWinClass
.cbWndExtra
= 0;
149 mPWinClass
.hInstance
= (HINSTANCE
) GetModuleHandle(NULL
); //myInstance;
150 mPWinClass
.hIcon
= NULL
;
151 mPWinClass
.hCursor
= NULL
;
152 mPWinClass
.hbrBackground
= (HBRUSH
) COLOR_BACKGROUND
;
153 mPWinClass
.lpszMenuName
= NULL
;
154 mPWinClass
.lpszClassName
= STAROFFICE_WINDOWCLASS
;
156 RegisterClass(&mPWinClass
);
159 CSOActiveX::~CSOActiveX()
165 HRESULT
CSOActiveX::Cleanup()
167 if( mpDispFrame
&& mbViewOnly
)
175 // mpDispFrame->dispose();
176 CComVariant dummyResult
;
177 ExecuteFunc( mpDispFrame
, L
"dispose", NULL
, 0, &dummyResult
);
178 mpDispFrame
= CComPtr
< IDispatch
>();
181 if( ::IsWindow( mOffWin
) )
182 ::DestroyWindow( mOffWin
);
188 STDMETHODIMP
CSOActiveX::InitNew ()
194 STDMETHODIMP
CSOActiveX::Load ( LPSTREAM pStm
)
199 // for now just ignore
204 STDMETHODIMP
CSOActiveX::Load( LPPROPERTYBAG pPropBag
, LPERRORLOG pErrorLog
)
206 IPropertyBag2
* pPropBag2
;
207 HRESULT hr
= pPropBag
->QueryInterface( IID_IPropertyBag2
, (void**)&pPropBag2
);
208 ATLASSERT( hr
>= 0 );
210 if( !SUCCEEDED( hr
) )
214 hr
= pPropBag2
->CountProperties( &aNum
);
215 ATLASSERT( hr
>= 0 );
216 if( !SUCCEEDED( hr
) )
219 PROPBAG2
* aPropNames
= new PROPBAG2
[aNum
];
220 unsigned long aReaded
;
222 hr
= pPropBag2
->GetPropertyInfo( 0,
226 ATLASSERT( hr
>= 0 );
227 if( !SUCCEEDED( hr
) )
233 CComVariant
* aVal
= new CComVariant
[aNum
];
234 HRESULT
* hvs
= new HRESULT
[aNum
];
235 hr
= pPropBag2
->Read( aNum
,
240 ATLASSERT( hr
>= 0 );
241 if( !SUCCEEDED( hr
) )
250 for( unsigned long ind
= 0; ind
< aNum
; ind
++ )
252 // all information from the 'object' tag is in strings
253 if( aVal
[ind
].vt
== VT_BSTR
&& !strcmp( OLE2T( aPropNames
[ind
].pstrName
), "src" ) )
255 mCurFileUrl
= wcsdup( aVal
[ind
].bstrVal
);
257 else if( aVal
[ind
].vt
== VT_BSTR
258 && !strcmp( OLE2T( aPropNames
[ind
].pstrName
), "readonly" ) )
260 if( !strcmp( OLE2T( aVal
[ind
].bstrVal
), "true" ) )
287 HRESULT
CSOActiveX::GetUnoStruct( OLECHAR
* sStructName
, CComPtr
<IDispatch
>& pdispResult
)
289 return GetIDispByFunc( mpDispFactory
, L
"Bridge_GetStruct", &CComVariant( sStructName
), 1, pdispResult
);
292 HRESULT
CSOActiveX::GetUrlStruct( OLECHAR
* sUrl
, CComPtr
<IDispatch
>& pdispUrl
)
294 HRESULT hr
= GetUnoStruct( L
"com.sun.star.util.URL", pdispUrl
);
295 if( !SUCCEEDED( hr
) ) return hr
;
297 OLECHAR
* sURLMemberName
= L
"Complete";
299 hr
= pdispUrl
->GetIDsOfNames( IID_NULL
, &sURLMemberName
, 1, LOCALE_USER_DEFAULT
, &nURLID
);
300 if( !SUCCEEDED( hr
) ) return hr
;
301 hr
= CComDispatchDriver::PutProperty( pdispUrl
, nURLID
, &CComVariant( sUrl
) );
302 if( !SUCCEEDED( hr
) ) return hr
;
304 CComPtr
<IDispatch
> pdispTransformer
;
305 hr
= GetIDispByFunc( mpDispFactory
,
307 &CComVariant( L
"com.sun.star.util.URLTransformer" ),
310 if( !SUCCEEDED( hr
) ) return hr
;
312 CComVariant dummyResult
;
313 CComVariant aInOutParam
;
314 aInOutParam
.ppdispVal
= &pdispUrl
;
315 aInOutParam
.vt
= VT_DISPATCH
| VT_BYREF
;
316 hr
= ExecuteFunc( pdispTransformer
, L
"parseStrict", &aInOutParam
, 1, &dummyResult
);
317 if( !SUCCEEDED( hr
) || dummyResult
.vt
!= VT_BOOL
|| !dummyResult
.boolVal
) return hr
;
323 HRESULT
CSOActiveX::CreateFrameOldWay( HWND hwnd
, int width
, int height
)
328 // create window handle holder
329 CComPtr
< CComObject
< SOComWindowPeer
> > pPeerToSend
= new CComObject
<SOComWindowPeer
>( hwnd
);
330 pPeerToSend
->SetHWNDInternally( hwnd
);
331 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispToSend( pPeerToSend
);
333 // create rectangle structure
334 CComPtr
<IDispatch
> pdispRectangle
;
335 HRESULT hr
= GetUnoStruct( L
"com.sun.star.awt.Rectangle", pdispRectangle
);
336 if( !SUCCEEDED( hr
) ) return hr
;
338 OLECHAR
* sRectMemberNames
[4] = { L
"X",
342 CComVariant pRectVariant
[4];
343 pRectVariant
[0] = pRectVariant
[1] = pRectVariant
[2] = pRectVariant
[3] = CComVariant( 0 );
345 hr
= PutPropertiesToIDisp( pdispRectangle
, sRectMemberNames
, pRectVariant
, 4 );
346 if( !SUCCEEDED( hr
) ) return hr
;
348 // create WindowDescriptor structure
349 CComPtr
<IDispatch
> pdispWinDescr
;
350 hr
= GetUnoStruct( L
"com.sun.star.awt.WindowDescriptor", pdispWinDescr
);
351 if( !SUCCEEDED( hr
) ) return hr
;
353 // fill in descriptor with info
354 OLECHAR
* sDescriptorMemberNames
[6] = { L
"Type",
355 L
"WindowServiceName",
359 L
"WindowAttributes" };
360 CComVariant pDescriptorVar
[6];
361 pDescriptorVar
[0] = CComVariant( 0 );
362 pDescriptorVar
[1] = CComVariant( L
"workwindow" );
363 pDescriptorVar
[2] = CComVariant( 1 );
364 pDescriptorVar
[3] = CComVariant( pIDispToSend
);
365 pDescriptorVar
[4] = CComVariant( pdispRectangle
);
366 pDescriptorVar
[5] = CComVariant( 33 );
367 hr
= PutPropertiesToIDisp( pdispWinDescr
, sDescriptorMemberNames
, pDescriptorVar
, 6 );
368 if( !SUCCEEDED( hr
) ) return hr
;
370 // create XToolkit instance
371 CComPtr
<IDispatch
> pdispToolkit
;
372 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.awt.Toolkit" ), 1, pdispToolkit
);
373 if( !SUCCEEDED( hr
) ) return hr
;
375 // create window with toolkit
376 hr
= GetIDispByFunc( pdispToolkit
, L
"createWindow", &CComVariant( pdispWinDescr
), 1, mpDispWin
);
377 if( !SUCCEEDED( hr
) ) return hr
;
380 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Task" ), 1, mpDispFrame
);
381 if( !SUCCEEDED( hr
) || !mpDispFrame
)
383 // the interface com.sun.star.frame.Task is removed in 6.1
384 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
385 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Frame" ), 1, mpDispFrame
);
386 if( !SUCCEEDED( hr
) ) return hr
;
390 CComVariant dummyResult
;
391 hr
= ExecuteFunc( mpDispFrame
, L
"initialize", &CComVariant( mpDispWin
), 1, &dummyResult
);
392 if( !SUCCEEDED( hr
) ) return hr
;
395 CComPtr
<IDispatch
> pdispDesktop
;
396 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Desktop" ), 1, pdispDesktop
);
397 if( !SUCCEEDED( hr
) ) return hr
;
399 // create tree of frames
400 CComPtr
<IDispatch
> pdispChildren
;
401 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", NULL
, 0, pdispChildren
);
402 if( !SUCCEEDED( hr
) ) return hr
;
404 // insert new frame into desctop hierarchy
405 hr
= ExecuteFunc( pdispChildren
, L
"append", &CComVariant( mpDispFrame
), 1, &dummyResult
);
406 if( !SUCCEEDED( hr
) ) return hr
;
409 hr
= ExecuteFunc( mpDispWin
, L
"setBackground", &CComVariant( (long)0xFFFFFFFF ), 1, &dummyResult
);
410 if( !SUCCEEDED( hr
) ) return hr
;
412 hr
= ExecuteFunc( mpDispWin
, L
"setVisible", &CComVariant( TRUE
), 1, &dummyResult
);
413 if( !SUCCEEDED( hr
) ) return hr
;
415 CComVariant aPosArgs
[5];
416 aPosArgs
[4] = CComVariant( 0 );
417 aPosArgs
[3] = CComVariant( 0 );
418 aPosArgs
[2] = CComVariant( width
);
419 aPosArgs
[1] = CComVariant( height
);
420 aPosArgs
[0] = CComVariant( 12 );
421 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
422 if( !SUCCEEDED( hr
) ) return hr
;
428 HRESULT
CSOActiveX::CallDispatch1PBool( OLECHAR
* sUrl
, OLECHAR
* sArgName
, BOOL sArgVal
)
430 CComPtr
<IDispatch
> pdispURL
;
431 HRESULT hr
= GetUrlStruct( sUrl
, pdispURL
);
432 if( !SUCCEEDED( hr
) ) return hr
;
434 CComPtr
<IDispatch
> pdispXDispatch
;
435 CComVariant aArgs
[3];
436 aArgs
[2] = CComVariant( pdispURL
);
437 aArgs
[1] = CComVariant( L
"" );
438 aArgs
[0] = CComVariant( (int)0 );
439 hr
= GetIDispByFunc( mpDispFrame
,
444 if( !SUCCEEDED( hr
) ) return hr
;
446 SAFEARRAY FAR
* pPropVals
= SafeArrayCreateVector( VT_DISPATCH
, 0, 1 );
448 CComPtr
<IDispatch
> pdispPropVal
;
449 hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
450 if( !SUCCEEDED( hr
) ) return hr
;
452 OLECHAR
* sPropMemberNames
[2] = { L
"Name", L
"Value" };
453 CComVariant pPropVar
[2];
454 pPropVar
[0] = CComVariant( sArgName
);
455 pPropVar
[1] = CComVariant(); pPropVar
[1].vt
= VT_BOOL
; pPropVar
[1].boolVal
= sArgVal
? VARIANT_TRUE
: VARIANT_FALSE
;
456 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
457 if( !SUCCEEDED( hr
) ) return hr
;
459 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
461 CComVariant aDispArgs
[2];
462 aDispArgs
[1] = CComVariant( pdispURL
);
463 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
464 aDispArgs
[0] = CComVariant(); aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
466 CComVariant dummyResult
;
467 hr
= ExecuteFunc( pdispXDispatch
, L
"dispatch", aDispArgs
, 2, &dummyResult
);
468 if( !SUCCEEDED( hr
) ) return hr
;
473 HRESULT
CSOActiveX::ShowSomeBars()
475 // show FunctionBar and StatusBar
476 for( int ind
= 0; ind
< BARS_TO_SHOW
; ind
++ )
478 HRESULT hr
= CallDispatch1PBool( pSlotUrl
[ind
], pSlotName
[ind
], TRUE
);
479 if( !SUCCEEDED( hr
) ) return hr
;
485 HRESULT
CSOActiveX::HideAllBars()
487 for( int ind
= 0; ind
< BARS_NUMBER
; ind
++ )
489 HRESULT hr
= CallDispatch1PBool( pSlotUrl
[ind
], pSlotName
[ind
], FALSE
);
490 if( !SUCCEEDED( hr
) ) return hr
;
496 HRESULT
CSOActiveX::LoadURLToFrame( )
498 HRESULT hr
= CallDispatch1PBool( mCurFileUrl
, L
"ReadOnly", mbViewOnly
);
499 if( !SUCCEEDED( hr
) ) return hr
;
507 HRESULT
CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO
& di
)
509 if( m_spInPlaceSite
&& mCurFileUrl
)
512 HRESULT hr
= m_spInPlaceSite
->GetWindow( &hwnd
);
513 if( !SUCCEEDED( hr
) ) return hr
;
515 if( mParentWin
!= hwnd
|| !mOffWin
)
519 CComVariant dummyResult
;
520 ExecuteFunc( mpDispFrame
, L
"dispose", NULL
, 0, &dummyResult
);
521 mpDispFrame
= CComPtr
<IDispatch
>();
525 mOffWin
= CreateWindow(
526 STAROFFICE_WINDOWCLASS
,
528 WS_CHILD
| WS_CLIPCHILDREN
| WS_BORDER
,
531 di
.prcBounds
->right
- di
.prcBounds
->left
,
532 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
538 ::ShowWindow( mOffWin
, SW_SHOW
);
543 ::GetWindowRect( mOffWin
, &aRect
);
545 if( aRect
.left
!= di
.prcBounds
->left
|| aRect
.top
!= di
.prcBounds
->top
546 || aRect
.right
!= di
.prcBounds
->right
|| aRect
.bottom
!= di
.prcBounds
->bottom
)
548 // on this state the office window should exist already
549 ::SetWindowPos( mOffWin
,
553 di
.prcBounds
->right
- di
.prcBounds
->left
,
554 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
557 CComVariant aPosArgs
[5];
558 aPosArgs
[4] = CComVariant( 0 );
559 aPosArgs
[3] = CComVariant( 0 );
560 aPosArgs
[2] = CComVariant( int(di
.prcBounds
->right
- di
.prcBounds
->left
) );
561 aPosArgs
[1] = CComVariant( int(di
.prcBounds
->bottom
- di
.prcBounds
->top
) );
562 aPosArgs
[0] = CComVariant( 12 );
563 CComVariant dummyResult
;
564 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
565 if( !SUCCEEDED( hr
) ) return hr
;
571 hr
= CreateFrameOldWay( mOffWin
,
572 di
.prcBounds
->right
- di
.prcBounds
->left
,
573 di
.prcBounds
->bottom
- di
.prcBounds
->top
);
574 if( !SUCCEEDED( hr
) ) return hr
;
579 hr
= LoadURLToFrame();
580 if( !SUCCEEDED( hr
) ) return hr
;
589 STDMETHODIMP
CSOActiveX::SetClientSite( IOleClientSite
* aClientSite
)
591 HRESULT hr
= IOleObjectImpl
<CSOActiveX
>::SetClientSite( aClientSite
);
595 ATLASSERT( mWebBrowser2
);
597 AtlUnadvise( mWebBrowser2
, DIID_DWebBrowserEvents2
, mCookie
);
601 CComPtr
<IOleContainer
> aContainer
;
602 m_spClientSite
->GetContainer( &aContainer
);
603 ATLASSERT( aContainer
);
605 if( SUCCEEDED( hr
) && aContainer
)
607 CComQIPtr
<IServiceProvider
, &IID_IServiceProvider
> aServiceProvider( aContainer
);
608 ATLASSERT( aServiceProvider
);
610 if( aServiceProvider
)
612 aServiceProvider
->QueryService( SID_SInternetExplorer
,
614 (void**)&mWebBrowser2
);
615 ATLASSERT( mWebBrowser2
);
617 AtlAdvise( mWebBrowser2
, GetUnknown(), DIID_DWebBrowserEvents2
, &mCookie
);
624 STDMETHODIMP
CSOActiveX::Invoke(DISPID dispidMember
,
628 DISPPARAMS
* pDispParams
,
630 EXCEPINFO
* pExcepInfo
,
633 if (riid
!= IID_NULL
)
634 return DISP_E_UNKNOWNINTERFACE
;
637 return DISP_E_PARAMNOTOPTIONAL
;
639 if ( dispidMember
== DISPID_ONQUIT
)
642 IDispatchImpl
<ISOActiveX
, &IID_ISOActiveX
,
643 &LIBID_SO_ACTIVEXLib
>::Invoke(
644 dispidMember
, riid
, lcid
, wFlags
, pDispParams
,
645 pvarResult
, pExcepInfo
, puArgErr
);
650 // ---------------------------------------------------------------------------