1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
7 * Copyright 2000, 2010 Oracle and/or its affiliates.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *************************************************************************/
36 // SOActiveX.cpp : Implementation of CSOActiveX
39 #include "so_activex.h"
40 #include "SOActiveX.h"
41 #include "SOComWindowPeer.h"
43 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
46 #define BARS_TO_SHOW 2
48 OLECHAR
* pSlotUrl
[BARS_NUMBER
] =
49 {L
"slot:5910" // SID_TOGGLEFUNCTIONBAR
50 ,L
"slot:5920" // SID_TOGGLESTATUSBAR
51 ,L
"slot:6661" // SID_TOGGLE_MENUBAR
54 OLECHAR
* pSlotName
[BARS_NUMBER
] =
55 {L
"FunctionBarVisible" // SID_TOGGLEFUNCTIONBAR
56 ,L
"StatusBarVisible" // SID_TOGGLESTATUSBAR
57 ,L
"MenuBarVisible" // SID_TOGGLE_MENUBAR
64 HRESULT
ExecuteFunc( IDispatch
* idispUnoObject
,
68 CComVariant
* pResult
)
74 HRESULT hr
= idispUnoObject
->GetIDsOfNames( IID_NULL
, &sFuncName
, 1, LOCALE_USER_DEFAULT
, &id
);
75 if( !SUCCEEDED( hr
) ) return hr
;
77 DISPPARAMS dispparams
= { params
, 0, count
, 0};
81 return idispUnoObject
->Invoke( id
, IID_NULL
,LOCALE_USER_DEFAULT
, DISPATCH_METHOD
,
82 &dispparams
, pResult
, &myInfo
, 0);
85 HRESULT
GetIDispByFunc( IDispatch
* idispUnoObject
,
89 CComPtr
<IDispatch
>& pdispResult
)
95 HRESULT hr
= ExecuteFunc( idispUnoObject
, sFuncName
, params
, count
, &result
);
96 if( !SUCCEEDED( hr
) ) return hr
;
98 if( result
.vt
!= VT_DISPATCH
|| result
.pdispVal
== NULL
)
101 pdispResult
= CComPtr
<IDispatch
>( result
.pdispVal
);
106 HRESULT
PutPropertiesToIDisp( IDispatch
* pdispObject
,
107 OLECHAR
** sMemberNames
,
108 CComVariant
* pVariant
,
111 for( unsigned int ind
= 0; ind
< count
; ind
++ )
114 HRESULT hr
= pdispObject
->GetIDsOfNames( IID_NULL
, &sMemberNames
[ind
], 1, LOCALE_USER_DEFAULT
, &id
);
115 if( !SUCCEEDED( hr
) ) return hr
;
117 hr
= CComDispatchDriver::PutProperty( pdispObject
, id
, &pVariant
[ind
] );
118 if( !SUCCEEDED( hr
) ) return hr
;
127 CSOActiveX::CSOActiveX()
129 , mCurFileUrl( L
"private:factory/swriter" )
133 , mbViewOnly( FALSE
)
135 CLSID clsFactory
= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
136 HRESULT hr
= CoCreateInstance( clsFactory
, NULL
, CLSCTX_ALL
, __uuidof(IDispatch
), (void**)&mpDispFactory
);
138 mPWinClass
.style
= CS_HREDRAW
|CS_VREDRAW
;
139 mPWinClass
.lpfnWndProc
= ::DefWindowProc
;
140 mPWinClass
.cbClsExtra
= 0;
141 mPWinClass
.cbWndExtra
= 0;
142 mPWinClass
.hInstance
= (HINSTANCE
) GetModuleHandle(NULL
); //myInstance;
143 mPWinClass
.hIcon
= NULL
;
144 mPWinClass
.hCursor
= NULL
;
145 mPWinClass
.hbrBackground
= (HBRUSH
) COLOR_BACKGROUND
;
146 mPWinClass
.lpszMenuName
= NULL
;
147 mPWinClass
.lpszClassName
= STAROFFICE_WINDOWCLASS
;
149 RegisterClass(&mPWinClass
);
152 CSOActiveX::~CSOActiveX()
158 HRESULT
CSOActiveX::Cleanup()
160 if( mpDispFrame
&& mbViewOnly
)
168 // mpDispFrame->dispose();
169 CComVariant dummyResult
;
170 ExecuteFunc( mpDispFrame
, L
"dispose", NULL
, 0, &dummyResult
);
171 mpDispFrame
= CComPtr
< IDispatch
>();
174 if( ::IsWindow( mOffWin
) )
175 ::DestroyWindow( mOffWin
);
181 STDMETHODIMP
CSOActiveX::InitNew ()
187 STDMETHODIMP
CSOActiveX::Load ( LPSTREAM pStm
)
192 // for now just ignore
197 STDMETHODIMP
CSOActiveX::Load( LPPROPERTYBAG pPropBag
, LPERRORLOG pErrorLog
)
199 IPropertyBag2
* pPropBag2
;
200 HRESULT hr
= pPropBag
->QueryInterface( IID_IPropertyBag2
, (void**)&pPropBag2
);
201 ATLASSERT( hr
>= 0 );
203 if( !SUCCEEDED( hr
) )
207 hr
= pPropBag2
->CountProperties( &aNum
);
208 ATLASSERT( hr
>= 0 );
209 if( !SUCCEEDED( hr
) )
212 PROPBAG2
* aPropNames
= new PROPBAG2
[aNum
];
213 unsigned long aReaded
;
215 hr
= pPropBag2
->GetPropertyInfo( 0,
219 ATLASSERT( hr
>= 0 );
220 if( !SUCCEEDED( hr
) )
226 CComVariant
* aVal
= new CComVariant
[aNum
];
227 HRESULT
* hvs
= new HRESULT
[aNum
];
228 hr
= pPropBag2
->Read( aNum
,
233 ATLASSERT( hr
>= 0 );
234 if( !SUCCEEDED( hr
) )
243 for( unsigned long ind
= 0; ind
< aNum
; ind
++ )
245 // all information from the 'object' tag is in strings
246 if( aVal
[ind
].vt
== VT_BSTR
&& !strcmp( OLE2T( aPropNames
[ind
].pstrName
), "src" ) )
248 mCurFileUrl
= wcsdup( aVal
[ind
].bstrVal
);
250 else if( aVal
[ind
].vt
== VT_BSTR
251 && !strcmp( OLE2T( aPropNames
[ind
].pstrName
), "readonly" ) )
253 if( !strcmp( OLE2T( aVal
[ind
].bstrVal
), "true" ) )
280 HRESULT
CSOActiveX::GetUnoStruct( OLECHAR
* sStructName
, CComPtr
<IDispatch
>& pdispResult
)
282 return GetIDispByFunc( mpDispFactory
, L
"Bridge_GetStruct", &CComVariant( sStructName
), 1, pdispResult
);
285 HRESULT
CSOActiveX::GetUrlStruct( OLECHAR
* sUrl
, CComPtr
<IDispatch
>& pdispUrl
)
287 HRESULT hr
= GetUnoStruct( L
"com.sun.star.util.URL", pdispUrl
);
288 if( !SUCCEEDED( hr
) ) return hr
;
290 OLECHAR
* sURLMemberName
= L
"Complete";
292 hr
= pdispUrl
->GetIDsOfNames( IID_NULL
, &sURLMemberName
, 1, LOCALE_USER_DEFAULT
, &nURLID
);
293 if( !SUCCEEDED( hr
) ) return hr
;
294 hr
= CComDispatchDriver::PutProperty( pdispUrl
, nURLID
, &CComVariant( sUrl
) );
295 if( !SUCCEEDED( hr
) ) return hr
;
297 CComPtr
<IDispatch
> pdispTransformer
;
298 hr
= GetIDispByFunc( mpDispFactory
,
300 &CComVariant( L
"com.sun.star.util.URLTransformer" ),
303 if( !SUCCEEDED( hr
) ) return hr
;
305 CComVariant dummyResult
;
306 CComVariant aInOutParam
;
307 aInOutParam
.ppdispVal
= &pdispUrl
;
308 aInOutParam
.vt
= VT_DISPATCH
| VT_BYREF
;
309 hr
= ExecuteFunc( pdispTransformer
, L
"parseStrict", &aInOutParam
, 1, &dummyResult
);
310 if( !SUCCEEDED( hr
) || dummyResult
.vt
!= VT_BOOL
|| !dummyResult
.boolVal
) return hr
;
316 HRESULT
CSOActiveX::CreateFrameOldWay( HWND hwnd
, int width
, int height
)
321 // create window handle holder
322 CComPtr
< CComObject
< SOComWindowPeer
> > pPeerToSend
= new CComObject
<SOComWindowPeer
>( hwnd
);
323 pPeerToSend
->SetHWNDInternally( hwnd
);
324 CComQIPtr
< IDispatch
, &IID_IDispatch
> pIDispToSend( pPeerToSend
);
326 // create rectangle structure
327 CComPtr
<IDispatch
> pdispRectangle
;
328 HRESULT hr
= GetUnoStruct( L
"com.sun.star.awt.Rectangle", pdispRectangle
);
329 if( !SUCCEEDED( hr
) ) return hr
;
331 OLECHAR
* sRectMemberNames
[4] = { L
"X",
335 CComVariant pRectVariant
[4];
336 pRectVariant
[0] = pRectVariant
[1] = pRectVariant
[2] = pRectVariant
[3] = CComVariant( 0 );
338 hr
= PutPropertiesToIDisp( pdispRectangle
, sRectMemberNames
, pRectVariant
, 4 );
339 if( !SUCCEEDED( hr
) ) return hr
;
341 // create WindowDescriptor structure
342 CComPtr
<IDispatch
> pdispWinDescr
;
343 hr
= GetUnoStruct( L
"com.sun.star.awt.WindowDescriptor", pdispWinDescr
);
344 if( !SUCCEEDED( hr
) ) return hr
;
346 // fill in descriptor with info
347 OLECHAR
* sDescriptorMemberNames
[6] = { L
"Type",
348 L
"WindowServiceName",
352 L
"WindowAttributes" };
353 CComVariant pDescriptorVar
[6];
354 pDescriptorVar
[0] = CComVariant( 0 );
355 pDescriptorVar
[1] = CComVariant( L
"workwindow" );
356 pDescriptorVar
[2] = CComVariant( 1 );
357 pDescriptorVar
[3] = CComVariant( pIDispToSend
);
358 pDescriptorVar
[4] = CComVariant( pdispRectangle
);
359 pDescriptorVar
[5] = CComVariant( 33 );
360 hr
= PutPropertiesToIDisp( pdispWinDescr
, sDescriptorMemberNames
, pDescriptorVar
, 6 );
361 if( !SUCCEEDED( hr
) ) return hr
;
363 // create XToolkit instance
364 CComPtr
<IDispatch
> pdispToolkit
;
365 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.awt.Toolkit" ), 1, pdispToolkit
);
366 if( !SUCCEEDED( hr
) ) return hr
;
368 // create window with toolkit
369 hr
= GetIDispByFunc( pdispToolkit
, L
"createWindow", &CComVariant( pdispWinDescr
), 1, mpDispWin
);
370 if( !SUCCEEDED( hr
) ) return hr
;
373 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Task" ), 1, mpDispFrame
);
374 if( !SUCCEEDED( hr
) || !mpDispFrame
)
376 // the interface com.sun.star.frame.Task is removed in 6.1
377 // but the interface com.sun.star.frame.Frame has some bugs in 6.0
378 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Frame" ), 1, mpDispFrame
);
379 if( !SUCCEEDED( hr
) ) return hr
;
383 CComVariant dummyResult
;
384 hr
= ExecuteFunc( mpDispFrame
, L
"initialize", &CComVariant( mpDispWin
), 1, &dummyResult
);
385 if( !SUCCEEDED( hr
) ) return hr
;
388 CComPtr
<IDispatch
> pdispDesktop
;
389 hr
= GetIDispByFunc( mpDispFactory
, L
"createInstance", &CComVariant( L
"com.sun.star.frame.Desktop" ), 1, pdispDesktop
);
390 if( !SUCCEEDED( hr
) ) return hr
;
392 // create tree of frames
393 CComPtr
<IDispatch
> pdispChildren
;
394 hr
= GetIDispByFunc( pdispDesktop
, L
"getFrames", NULL
, 0, pdispChildren
);
395 if( !SUCCEEDED( hr
) ) return hr
;
397 // insert new frame into desctop hierarchy
398 hr
= ExecuteFunc( pdispChildren
, L
"append", &CComVariant( mpDispFrame
), 1, &dummyResult
);
399 if( !SUCCEEDED( hr
) ) return hr
;
402 hr
= ExecuteFunc( mpDispWin
, L
"setBackground", &CComVariant( (long)0xFFFFFFFF ), 1, &dummyResult
);
403 if( !SUCCEEDED( hr
) ) return hr
;
405 hr
= ExecuteFunc( mpDispWin
, L
"setVisible", &CComVariant( TRUE
), 1, &dummyResult
);
406 if( !SUCCEEDED( hr
) ) return hr
;
408 CComVariant aPosArgs
[5];
409 aPosArgs
[4] = CComVariant( 0 );
410 aPosArgs
[3] = CComVariant( 0 );
411 aPosArgs
[2] = CComVariant( width
);
412 aPosArgs
[1] = CComVariant( height
);
413 aPosArgs
[0] = CComVariant( 12 );
414 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
415 if( !SUCCEEDED( hr
) ) return hr
;
421 HRESULT
CSOActiveX::CallDispatch1PBool( OLECHAR
* sUrl
, OLECHAR
* sArgName
, BOOL sArgVal
)
423 CComPtr
<IDispatch
> pdispURL
;
424 HRESULT hr
= GetUrlStruct( sUrl
, pdispURL
);
425 if( !SUCCEEDED( hr
) ) return hr
;
427 CComPtr
<IDispatch
> pdispXDispatch
;
428 CComVariant aArgs
[3];
429 aArgs
[2] = CComVariant( pdispURL
);
430 aArgs
[1] = CComVariant( L
"" );
431 aArgs
[0] = CComVariant( (int)0 );
432 hr
= GetIDispByFunc( mpDispFrame
,
437 if( !SUCCEEDED( hr
) ) return hr
;
439 SAFEARRAY FAR
* pPropVals
= SafeArrayCreateVector( VT_DISPATCH
, 0, 1 );
441 CComPtr
<IDispatch
> pdispPropVal
;
442 hr
= GetUnoStruct( L
"com.sun.star.beans.PropertyValue", pdispPropVal
);
443 if( !SUCCEEDED( hr
) ) return hr
;
445 OLECHAR
* sPropMemberNames
[2] = { L
"Name", L
"Value" };
446 CComVariant pPropVar
[2];
447 pPropVar
[0] = CComVariant( sArgName
);
448 pPropVar
[1] = CComVariant(); pPropVar
[1].vt
= VT_BOOL
; pPropVar
[1].boolVal
= sArgVal
? VARIANT_TRUE
: VARIANT_FALSE
;
449 hr
= PutPropertiesToIDisp( pdispPropVal
, sPropMemberNames
, pPropVar
, 2 );
450 if( !SUCCEEDED( hr
) ) return hr
;
452 SafeArrayPutElement( pPropVals
, &ix
, pdispPropVal
);
454 CComVariant aDispArgs
[2];
455 aDispArgs
[1] = CComVariant( pdispURL
);
456 // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
457 aDispArgs
[0] = CComVariant(); aDispArgs
[0].vt
= VT_ARRAY
| VT_DISPATCH
; aDispArgs
[0].parray
= pPropVals
;
459 CComVariant dummyResult
;
460 hr
= ExecuteFunc( pdispXDispatch
, L
"dispatch", aDispArgs
, 2, &dummyResult
);
461 if( !SUCCEEDED( hr
) ) return hr
;
466 HRESULT
CSOActiveX::ShowSomeBars()
468 // show FunctionBar and StatusBar
469 for( int ind
= 0; ind
< BARS_TO_SHOW
; ind
++ )
471 HRESULT hr
= CallDispatch1PBool( pSlotUrl
[ind
], pSlotName
[ind
], TRUE
);
472 if( !SUCCEEDED( hr
) ) return hr
;
478 HRESULT
CSOActiveX::HideAllBars()
480 for( int ind
= 0; ind
< BARS_NUMBER
; ind
++ )
482 HRESULT hr
= CallDispatch1PBool( pSlotUrl
[ind
], pSlotName
[ind
], FALSE
);
483 if( !SUCCEEDED( hr
) ) return hr
;
489 HRESULT
CSOActiveX::LoadURLToFrame( )
491 HRESULT hr
= CallDispatch1PBool( mCurFileUrl
, L
"ReadOnly", mbViewOnly
);
492 if( !SUCCEEDED( hr
) ) return hr
;
500 HRESULT
CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO
& di
)
502 if( m_spInPlaceSite
&& mCurFileUrl
)
505 HRESULT hr
= m_spInPlaceSite
->GetWindow( &hwnd
);
506 if( !SUCCEEDED( hr
) ) return hr
;
508 if( mParentWin
!= hwnd
|| !mOffWin
)
512 CComVariant dummyResult
;
513 ExecuteFunc( mpDispFrame
, L
"dispose", NULL
, 0, &dummyResult
);
514 mpDispFrame
= CComPtr
<IDispatch
>();
518 mOffWin
= CreateWindow(
519 STAROFFICE_WINDOWCLASS
,
521 WS_CHILD
| WS_CLIPCHILDREN
| WS_BORDER
,
524 di
.prcBounds
->right
- di
.prcBounds
->left
,
525 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
531 ::ShowWindow( mOffWin
, SW_SHOW
);
536 ::GetWindowRect( mOffWin
, &aRect
);
538 if( aRect
.left
!= di
.prcBounds
->left
|| aRect
.top
!= di
.prcBounds
->top
539 || aRect
.right
!= di
.prcBounds
->right
|| aRect
.bottom
!= di
.prcBounds
->bottom
)
541 // on this state the office window should exist already
542 ::SetWindowPos( mOffWin
,
546 di
.prcBounds
->right
- di
.prcBounds
->left
,
547 di
.prcBounds
->bottom
- di
.prcBounds
->top
,
550 CComVariant aPosArgs
[5];
551 aPosArgs
[4] = CComVariant( 0 );
552 aPosArgs
[3] = CComVariant( 0 );
553 aPosArgs
[2] = CComVariant( int(di
.prcBounds
->right
- di
.prcBounds
->left
) );
554 aPosArgs
[1] = CComVariant( int(di
.prcBounds
->bottom
- di
.prcBounds
->top
) );
555 aPosArgs
[0] = CComVariant( 12 );
556 CComVariant dummyResult
;
557 hr
= ExecuteFunc( mpDispWin
, L
"setPosSize", aPosArgs
, 5, &dummyResult
);
558 if( !SUCCEEDED( hr
) ) return hr
;
564 hr
= CreateFrameOldWay( mOffWin
,
565 di
.prcBounds
->right
- di
.prcBounds
->left
,
566 di
.prcBounds
->bottom
- di
.prcBounds
->top
);
567 if( !SUCCEEDED( hr
) ) return hr
;
572 hr
= LoadURLToFrame();
573 if( !SUCCEEDED( hr
) ) return hr
;
582 STDMETHODIMP
CSOActiveX::SetClientSite( IOleClientSite
* aClientSite
)
584 HRESULT hr
= IOleObjectImpl
<CSOActiveX
>::SetClientSite( aClientSite
);
588 ATLASSERT( mWebBrowser2
);
590 AtlUnadvise( mWebBrowser2
, DIID_DWebBrowserEvents2
, mCookie
);
594 CComPtr
<IOleContainer
> aContainer
;
595 m_spClientSite
->GetContainer( &aContainer
);
596 ATLASSERT( aContainer
);
598 if( SUCCEEDED( hr
) && aContainer
)
600 CComQIPtr
<IServiceProvider
, &IID_IServiceProvider
> aServiceProvider( aContainer
);
601 ATLASSERT( aServiceProvider
);
603 if( aServiceProvider
)
605 aServiceProvider
->QueryService( SID_SInternetExplorer
,
607 (void**)&mWebBrowser2
);
608 ATLASSERT( mWebBrowser2
);
610 AtlAdvise( mWebBrowser2
, GetUnknown(), DIID_DWebBrowserEvents2
, &mCookie
);
617 STDMETHODIMP
CSOActiveX::Invoke(DISPID dispidMember
,
621 DISPPARAMS
* pDispParams
,
623 EXCEPINFO
* pExcepInfo
,
626 if (riid
!= IID_NULL
)
627 return DISP_E_UNKNOWNINTERFACE
;
630 return DISP_E_PARAMNOTOPTIONAL
;
632 if ( dispidMember
== DISPID_ONQUIT
)
635 IDispatchImpl
<ISOActiveX
, &IID_ISOActiveX
,
636 &LIBID_SO_ACTIVEXLib
>::Invoke(
637 dispidMember
, riid
, lcid
, wFlags
, pDispParams
,
638 pvarResult
, pExcepInfo
, puArgErr
);
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */