1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // SOActiveX.cpp : Implementation of CSOActiveX
23 
24 #pragma warning (disable:4505)
25     // permanently suppress "unreferenced local function has been removed" warning
26 
27 #pragma warning (push,1)
28 #pragma warning (disable:4265)
29 
30 #include "stdafx2.h"
31 #include "so_activex.h"
32 #include "SOActiveX.h"
33 #include "SOComWindowPeer.h"
34 #include "SODispatchInterceptor.h"
35 #include "SOActionsApproval.h"
36 
37 #pragma warning (pop)
38 
39 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
40 
41 
42 /////////////////////////////////////////////////////////////////////////////
43 
OutputError_Impl(HWND hw,HRESULT ErrorCode)44 void OutputError_Impl( HWND hw, HRESULT ErrorCode )
45 {
46 	void* sMessage;
47 	FormatMessageA(
48 		FORMAT_MESSAGE_ALLOCATE_BUFFER |
49 		FORMAT_MESSAGE_FROM_SYSTEM,
50 		NULL,
51 		ErrorCode,
52 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
53 		(LPTSTR) &sMessage,
54 		0,
55 		NULL
56 	);
57 	::MessageBoxA( hw, (LPCTSTR)sMessage, NULL, MB_OK | MB_ICONINFORMATION );
58 	LocalFree( sMessage );
59 }
60 
ExecuteFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComVariant * pResult)61 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
62 					 OLECHAR* sFuncName,
63 					 CComVariant* params,
64 					 unsigned int count,
65 					 CComVariant* pResult )
66 {
67 	if( !idispUnoObject )
68 		return E_FAIL;
69 
70 	DISPID id;
71 	HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
72 	if( !SUCCEEDED( hr ) ) return hr;
73 
74 	DISPPARAMS dispparams= { params, 0, count, 0};
75 
76 	// DEBUG
77 	EXCEPINFO myInfo;
78 	hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
79                     &dispparams, pResult, &myInfo, 0);
80 
81 	// for debugging purposes
82 	// USES_CONVERSION;
83 	// if ( !SUCCEEDED( hr ) )
84 	//	::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
85 
86 	return hr;
87 }
88 
GetIDispByFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComPtr<IDispatch> & pdispResult)89 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
90 					  	OLECHAR* sFuncName,
91 					  	CComVariant* params,
92 					  	unsigned int count,
93 					  	CComPtr<IDispatch>& pdispResult )
94 {
95 	if( !idispUnoObject )
96 		return E_FAIL;
97 
98 	CComVariant result;
99 	HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
100 	if( !SUCCEEDED( hr ) ) return hr;
101 
102 	if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
103 		return E_FAIL;
104 
105 	pdispResult = CComPtr<IDispatch>( result.pdispVal );
106 
107 	return S_OK;
108 }
109 
PutPropertiesToIDisp(IDispatch * pdispObject,OLECHAR ** sMemberNames,CComVariant * pVariant,unsigned int count)110 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
111 							  OLECHAR** sMemberNames,
112 							  CComVariant* pVariant,
113 							  unsigned int count )
114 {
115 	for( unsigned int ind = 0; ind < count; ind++ )
116 	{
117 		DISPID id;
118 		HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
119 		if( !SUCCEEDED( hr ) ) return hr;
120 
121 		hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
122 		if( !SUCCEEDED( hr ) ) return hr;
123 	}
124 
125 	return S_OK;
126 }
127 
GetPropertiesFromIDisp(IDispatch * pdispObject,OLECHAR ** sMemberNames,CComVariant * pVariant,unsigned int count)128 HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
129 							    OLECHAR** sMemberNames,
130 							    CComVariant* pVariant,
131 							    unsigned int count )
132 {
133 	for( unsigned int ind = 0; ind < count; ind++ )
134 	{
135 		DISPID id;
136 		HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
137 		if( !SUCCEEDED( hr ) ) return hr;
138 
139 		hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
140 		if( !SUCCEEDED( hr ) ) return hr;
141 	}
142 
143 	return S_OK;
144 }
145 /////////////////////////////////////////////////////////////////////////////
146 // CSOActiveX
147 
CSOActiveX()148 CSOActiveX::CSOActiveX()
149 : mCookie(0)
150 , mCurFileUrl( L"private:factory/swriter" )
151 , mbLoad( FALSE )
152 , mParentWin( NULL )
153 , mOffWin( NULL )
154 , mbViewOnly( TRUE )
155 , mpDispatchInterceptor( NULL )
156 , mnVersion( SO_NOT_DETECTED )
157 , mbReadyForActivation( FALSE )
158 , mbDrawLocked( FALSE )
159 {
160 	CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
161 	HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
162 	if( !SUCCEEDED( hr ) )
163 		OutputError_Impl( NULL, hr );
164 
165     mPWinClass.style			= CS_HREDRAW|CS_VREDRAW;
166     mPWinClass.lpfnWndProc		= ::DefWindowProc;
167     mPWinClass.cbClsExtra		= 0;
168     mPWinClass.cbWndExtra		= 0;
169     mPWinClass.hInstance		= (HINSTANCE) GetModuleHandle(NULL); //myInstance;
170     mPWinClass.hIcon			= NULL;
171     mPWinClass.hCursor			= NULL;
172     mPWinClass.hbrBackground	= (HBRUSH) COLOR_BACKGROUND;
173     mPWinClass.lpszMenuName	    = NULL;
174     mPWinClass.lpszClassName	= STAROFFICE_WINDOWCLASS;
175 
176 	RegisterClass(&mPWinClass);
177 }
178 
~CSOActiveX()179 CSOActiveX::~CSOActiveX()
180 {
181 	Cleanup();
182 
183 }
184 
Cleanup()185 HRESULT CSOActiveX::Cleanup()
186 {
187 	CComVariant dummyResult;
188 
189 	if( mpDispatchInterceptor )
190 	{
191 		if( mpDispFrame )
192 		{
193 			// remove dispatch interceptor
194 			CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
195 		        CComVariant aVariant( pIDispDispInter );
196 			ExecuteFunc( mpDispFrame,
197 						 L"releaseDispatchProviderInterceptor",
198 						 &aVariant,
199 						 1,
200 						 &dummyResult );
201 		}
202 
203 		mpDispatchInterceptor->ClearParent();
204         mpDispatchInterceptor->Release();
205         mpDispatchInterceptor = NULL;
206 	}
207 
208 	mpDispTempFile = CComPtr< IDispatch >();
209 	mbReadyForActivation = FALSE;
210 
211 	if( mpInstanceLocker )
212 	{
213 		ExecuteFunc( mpInstanceLocker, L"dispose", NULL, 0, &dummyResult );
214 		mpInstanceLocker = CComPtr< IDispatch >();
215 	}
216 
217 	if( mpDispFrame )
218 	{
219 		BOOL bCloserActivated = FALSE;
220 
221 		CComPtr<IDispatch> pDispDocumentCloser;
222         CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
223 		HRESULT hr = GetIDispByFunc( mpDispFactory,
224 					 				L"createInstance",
225 					 				&aDocCloser,
226 					 				1,
227 					 				pDispDocumentCloser );
228 		if ( SUCCEEDED( hr ) && pDispDocumentCloser )
229 		{
230 			SAFEARRAY FAR* pInitFrame = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
231 			long nInitInd = 0;
232 			CComVariant pFrameVariant( mpDispFrame );
233 			SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
234 			CComVariant aVarInitFrame;
235 			aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
236 			hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
237 			if( SUCCEEDED( hr ) )
238 			{
239 				// the following call will let the closing happen
240 				hr = ExecuteFunc( pDispDocumentCloser, L"dispose", NULL, 0, &dummyResult );
241 				bCloserActivated = SUCCEEDED( hr );
242 			}
243 		}
244 
245 		if ( !bCloserActivated )
246 		{
247 			CComVariant aPropVar;
248 			aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
249 			if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
250 				ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
251 		}
252 
253 		mpDispFrame = CComPtr< IDispatch >();
254 	}
255 
256 	if( ::IsWindow( mOffWin ) )
257 		::DestroyWindow( mOffWin );
258 
259     TerminateOffice();
260 
261 	return S_OK;
262 }
263 
TerminateOffice()264 HRESULT CSOActiveX::TerminateOffice()
265 {
266     // create desktop
267 	CComPtr<IDispatch> pdispDesktop;
268     CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
269 
270     HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
271 	if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
272 
273 	// create tree of frames
274 	CComPtr<IDispatch> pdispChildren;
275 	hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
276 	if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
277 
278 	CComVariant aFrames;
279     CComVariant nFlag( 4 );
280 	hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
281     if ( SUCCEEDED( hr ) )
282     {
283 		if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
284           && ( !aFrames.parray || aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0 ) )
285         {
286             // there is no frames open
287             // TODO: check whether the frames are hidden if they are open?
288             CComVariant dummyResult;
289 	        hr = ExecuteFunc( pdispDesktop, L"terminate", NULL, 0, &dummyResult );
290         }
291     }
292 
293     return hr;
294 }
295 
InitNew()296 STDMETHODIMP CSOActiveX::InitNew ()
297 {
298 	mnVersion = GetVersionConnected();
299 	mbLoad = TRUE;
300     return S_OK;
301 }
302 
Load(LPSTREAM)303 STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
304 {
305 	mnVersion = GetVersionConnected();
306 	mbLoad = TRUE;
307 
308 	// may be later?
309 	// for now just ignore
310 
311     return S_OK;
312 }
313 
Load(LPPROPERTYBAG pPropBag,LPERRORLOG)314 STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
315 {
316 	mnVersion = GetVersionConnected();
317 
318     IPropertyBag2* pPropBag2;
319     HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
320     //ATLASSERT( hr >= 0 );
321 
322     if( !SUCCEEDED( hr ) )
323         return hr;
324 
325     unsigned long aNum;
326     hr = pPropBag2->CountProperties( &aNum );
327     //ATLASSERT( hr >= 0 );
328     if( !SUCCEEDED( hr ) )
329         return hr;
330 
331     PROPBAG2* aPropNames = new PROPBAG2[aNum];
332     unsigned long aReaded;
333 
334     hr = pPropBag2->GetPropertyInfo( 0,
335                                      aNum,
336                                      aPropNames,
337                                      &aReaded );
338     //ATLASSERT( hr >= 0 );
339     if( !SUCCEEDED( hr ) )
340     {
341         delete[] aPropNames;
342         return hr;
343     }
344 
345 	CComVariant* aVal = new CComVariant[aNum];
346     HRESULT*     hvs = new HRESULT[aNum];
347 	hr = pPropBag2->Read( aNum,
348                           aPropNames,
349                           NULL,
350                           aVal,
351                           hvs );
352     //ATLASSERT( hr >= 0 );
353     if( !SUCCEEDED( hr ) )
354     {
355         delete[] hvs;
356         delete[] aVal;
357         delete[] aPropNames;
358         return hr;
359     }
360 
361 	USES_CONVERSION;
362     for( unsigned long ind = 0; ind < aNum; ind++ )
363     {
364 		// all information from the 'object' tag is in strings
365 		if( aVal[ind].vt == VT_BSTR && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
366 		{
367             mCurFileUrl = wcsdup( aVal[ind].bstrVal );
368 		}
369 		else if( aVal[ind].vt == VT_BSTR
370 				&& !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
371 		{
372 			if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
373 			{
374 				// the default value
375 				mbViewOnly = TRUE;
376 			}
377 			else
378 			{
379 				mbViewOnly = FALSE;
380 			}
381 		}
382     }
383 
384     delete[] hvs;
385     delete[] aVal;
386     delete[] aPropNames;
387 
388 	if( !mpDispFactory )
389 		return hr;
390 
391 	mbReadyForActivation = FALSE;
392 	hr = CBindStatusCallback<CSOActiveX>::Download( this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE );
393 	if ( hr == MK_S_ASYNCHRONOUS )
394 		hr = S_OK;
395 
396 	if ( !SUCCEEDED( hr ) )
397 	{
398 		// trigger initialization without stream
399 		mbLoad = TRUE;
400 
401     	Invalidate();
402     	UpdateWindow();
403 	}
404 
405 	return hr;
406 }
407 
GetUnoStruct(OLECHAR * sStructName,CComPtr<IDispatch> & pdispResult)408 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
409 {
410     CComVariant aComStruct( sStructName );
411 	return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
412 }
413 
GetUrlStruct(OLECHAR * sUrl,CComPtr<IDispatch> & pdispUrl)414 HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
415 {
416 	HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
417 	if( !SUCCEEDED( hr ) ) return hr;
418 
419 	OLECHAR* sURLMemberName = L"Complete";
420 	DISPID nURLID;
421 	hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
422 	if( !SUCCEEDED( hr ) ) return hr;
423     CComVariant aComUrl( sUrl );
424 	hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
425 	if( !SUCCEEDED( hr ) ) return hr;
426 
427 	CComPtr<IDispatch> pdispTransformer;
428     CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
429 	hr = GetIDispByFunc( mpDispFactory,
430 						 L"createInstance",
431 						 &aServiceName,
432 						 1,
433 						 pdispTransformer );
434 	if( !SUCCEEDED( hr ) ) return hr;
435 
436 	CComVariant dummyResult;
437 	CComVariant aParam[2];
438 	aParam[1].ppdispVal = &pdispUrl;
439 	aParam[1].vt = VT_DISPATCH | VT_BYREF;
440 	aParam[0] = CComVariant( L"file:///" );
441 
442 	hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
443 	if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
444 
445 	return S_OK;
446 }
447 
SetLayoutManagerProps()448 HRESULT CSOActiveX::SetLayoutManagerProps()
449 {
450 	if ( !mpDispFrame )
451 		return E_FAIL;
452 
453 	CComVariant pVarLayoutMgr;
454 	OLECHAR* sLMPropName = L"LayoutManager";
455 	HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
456 	if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == NULL )
457 		return E_FAIL;
458 
459   	CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
460 
461 
462 	if( !SUCCEEDED( hr ) || !pdispLM )
463 		return E_FAIL;
464 
465 	OLECHAR* sATName = L"AutomaticToolbars";
466 	CComVariant pATProp;
467 	pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
468 	hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
469 
470 	return hr;
471 }
472 
CreateFrameOldWay(HWND hwnd,int width,int height)473 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
474 {
475 	if( !mpDispFactory )
476 		return E_FAIL;
477 
478 	// create window handle holder
479 	CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
480 	pPeerToSend->SetHWNDInternally( hwnd );
481 	CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
482 
483 	// create rectangle structure
484 	CComPtr<IDispatch> pdispRectangle;
485 	HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
486 	if( !SUCCEEDED( hr ) ) return hr;
487 
488 	OLECHAR* sRectMemberNames[4] = { L"X",
489 								 	 L"Y",
490 								 	 L"Width",
491 								 	 L"Height" };
492 	CComVariant pRectVariant[4];
493 	pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
494 
495 	hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
496 	if( !SUCCEEDED( hr ) ) return hr;
497 
498 	// create WindowDescriptor structure
499 	CComPtr<IDispatch> pdispWinDescr;
500 	hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
501 	if( !SUCCEEDED( hr ) ) return hr;
502 
503 	// fill in descriptor with info
504 	OLECHAR* sDescriptorMemberNames[6] = { L"Type",
505 								 L"WindowServiceName",
506 								 L"ParentIndex",
507 								 L"Parent",
508 								 L"Bounds",
509 								 L"WindowAttributes" };
510 	CComVariant pDescriptorVar[6];
511 	pDescriptorVar[0] = CComVariant( 0 );
512 	pDescriptorVar[1] = CComVariant( L"workwindow" );
513 	pDescriptorVar[2] = CComVariant( 1 );
514 	pDescriptorVar[3] = CComVariant( pIDispToSend );
515 	pDescriptorVar[4] = CComVariant( pdispRectangle );
516 	pDescriptorVar[5] = CComVariant( 33 );
517 	hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
518 	if( !SUCCEEDED( hr ) ) return hr;
519 
520 	// create XToolkit instance
521 	CComPtr<IDispatch> pdispToolkit;
522     CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
523 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
524 	if( !SUCCEEDED( hr ) ) return hr;
525 
526 	// create window with toolkit
527     CComVariant aWinDescr( pdispWinDescr );
528 	hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
529 	if( !SUCCEEDED( hr ) ) return hr;
530 
531 	// create frame
532     aServiceName = CComVariant( L"com.sun.star.frame.Task" );
533 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
534 	if( !SUCCEEDED( hr ) || !mpDispFrame )
535 	{
536 		// the interface com.sun.star.frame.Task is removed in 6.1
537 		// but the interface com.sun.star.frame.Frame has some bugs in 6.0
538         aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
539 		hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
540 		if( !SUCCEEDED( hr ) ) return hr;
541 	}
542 
543 	// initialize frame
544 	CComVariant dummyResult;
545     CComVariant aDispWin( mpDispWin );
546 	hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
547 	if( !SUCCEEDED( hr ) ) return hr;
548 
549 	// set some properties to the layout manager, ignore errors for now
550 	SetLayoutManagerProps();
551 
552 	// create desktop
553 	CComPtr<IDispatch> pdispDesktop;
554     aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
555 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
556 	if( !SUCCEEDED( hr ) ) return hr;
557 
558 	// create tree of frames
559 	CComPtr<IDispatch> pdispChildren;
560 	hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
561 	if( !SUCCEEDED( hr ) ) return hr;
562 
563 	// insert new frame into desctop hierarchy
564     CComVariant aDispFrame( mpDispFrame );
565 	hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
566 	if( !SUCCEEDED( hr ) ) return hr;
567 
568 	// initialize window
569     CComVariant aTransparent( (long)0xFFFFFFFF );
570 	hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
571 	if( !SUCCEEDED( hr ) ) return hr;
572 
573     CComVariant aTrue( TRUE );
574 	hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
575 	if( !SUCCEEDED( hr ) ) return hr;
576 
577 	CComVariant aPosArgs[5];
578 	aPosArgs[4] = CComVariant( 0 );
579 	aPosArgs[3] = CComVariant( 0 );
580 	aPosArgs[2] = CComVariant( width );
581 	aPosArgs[1] = CComVariant( height );
582 	aPosArgs[0] = CComVariant( 12 );
583 	hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
584 	if( !SUCCEEDED( hr ) ) return hr;
585 
586 	// create frame locker if there is such service
587     aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
588 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
589 	if( SUCCEEDED( hr ) && mpInstanceLocker )
590 	{
591 		SAFEARRAY FAR* pInitVals = SafeArrayCreateVector( VT_VARIANT, 0, 3 );
592 
593 		// the first sequence element
594 		long nInitInd = 0;
595 		CComVariant pFrameVariant( mpDispFrame );
596 		SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
597 
598 		// the second sequence element
599 		nInitInd = 1;
600 		CComVariant pStrArr( 1L );
601 		SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
602 
603 		// the third sequence element
604 		nInitInd = 2;
605 		CComPtr<IDispatch> pdispValueObj;
606 		hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", NULL, 0, pdispValueObj );
607 		if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
608 
609 		CComVariant aValueArgs[2];
610 		aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
611 		CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
612 		aValueArgs[0] = CComVariant ( pApproval );
613 
614 		hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
615 		if( !SUCCEEDED( hr ) ) return hr;
616 
617         CComVariant aValueObj( pdispValueObj );
618 		SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
619 
620 		// execute initialize()
621 		CComVariant aVarInitVals;
622 		aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
623 		hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
624 		if( !SUCCEEDED( hr ) ) return hr;
625 	}
626 
627 	return S_OK;
628 }
629 
CallLoadComponentFromURL1PBool(OLECHAR * sUrl,OLECHAR * sArgName,BOOL sArgVal)630 HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
631 {
632 	SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
633 	long ix = 0;
634 	CComPtr<IDispatch> pdispPropVal;
635 	HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
636 	if( !SUCCEEDED( hr ) ) return hr;
637 
638 	OLECHAR* 	sPropMemberNames[2] = { L"Name", L"Value" };
639 	CComVariant pPropVar[2];
640 	pPropVar[0] = CComVariant( sArgName );
641 	pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
642 	hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
643 	if( !SUCCEEDED( hr ) ) return hr;
644 
645 	SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
646 
647 	CComVariant aDispArgs[4];
648 	aDispArgs[3] = CComVariant( sUrl );
649 	aDispArgs[2] = CComVariant( L"_self" );
650 	aDispArgs[1] = CComVariant( 0 );
651 	// aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
652 	aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
653 
654 	CComVariant dummyResult;
655 	hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
656 	if( !SUCCEEDED( hr ) ) return hr;
657 
658 	return S_OK;
659 }
660 
CallDispatchMethod(OLECHAR * sUrl,CComVariant * aArgNames,CComVariant * aArgVals,unsigned int count)661 HRESULT CSOActiveX::CallDispatchMethod( OLECHAR* sUrl,
662 									    CComVariant* aArgNames,
663 									    CComVariant* aArgVals,
664 									    unsigned int count )
665 {
666 	CComPtr<IDispatch> pdispURL;
667 	HRESULT hr = GetUrlStruct( sUrl, pdispURL );
668 	if( !SUCCEEDED( hr ) ) return hr;
669 
670 	CComPtr<IDispatch> pdispXDispatch;
671 	CComVariant aArgs[3];
672 	aArgs[2] = CComVariant( pdispURL );
673 	aArgs[1] = CComVariant( L"" );
674 	aArgs[0] = CComVariant( (int)0 );
675 	hr = GetIDispByFunc( mpDispFrame,
676 						 L"queryDispatch",
677 						 aArgs,
678 						 3,
679 						 pdispXDispatch );
680 	if( !SUCCEEDED( hr ) ) return hr;
681 
682 	SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, count );
683 	for( long ix = 0; ix < (long)count; ix ++ )
684 	{
685 		CComPtr<IDispatch> pdispPropVal;
686 		hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
687 		if( !SUCCEEDED( hr ) ) return hr;
688 
689 		OLECHAR* 	sPropMemberNames[2] = { L"Name", L"Value" };
690 		CComVariant pPropVar[2];
691 		pPropVar[0] = aArgNames[ix];
692 		pPropVar[1] = aArgVals[ix];
693 		hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
694 		if( !SUCCEEDED( hr ) ) return hr;
695 
696 		SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
697 	}
698 
699 	CComVariant aDispArgs[2];
700 	aDispArgs[1] = CComVariant( pdispURL );
701 	// aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
702 	aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
703 
704 	CComVariant dummyResult;
705 	hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
706 	if( !SUCCEEDED( hr ) ) return hr;
707 
708 	return S_OK;
709 }
710 
CallbackCreateXInputStream(CBindStatusCallback<CSOActiveX> *,BYTE * pBytes,DWORD dwSize)711 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
712 {
713 	if ( mbReadyForActivation )
714 		return;
715 
716 	BOOL bSuccess = FALSE;
717 	BOOL bFinishDownload = FALSE;
718 	if ( !pBytes )
719 	{
720 		// means the download is finished, dwSize contains hresult
721 		bFinishDownload = TRUE;
722 		if ( SUCCEEDED( dwSize ) )
723 			bSuccess = TRUE;
724 	}
725 	else
726 	{
727 		HRESULT hr = S_OK;
728 
729 		if ( !mpDispTempFile )
730 		{
731             CComVariant aServiceName( L"com.sun.star.io.TempFile" );
732 			hr = GetIDispByFunc( mpDispFactory,
733 						 		L"createInstance",
734 						 		&aServiceName,
735 						 		1,
736 						 		mpDispTempFile );
737 		}
738 
739 		if( SUCCEEDED( hr ) && mpDispTempFile )
740 		{
741 			SAFEARRAY FAR* pDataArray = SafeArrayCreateVector( VT_I1, 0, dwSize );
742 
743 			if ( pDataArray )
744 			{
745 				hr = SafeArrayLock( pDataArray );
746 				if ( SUCCEEDED( hr ) )
747 				{
748 					for( DWORD ix = 0; ix < dwSize; ix++ )
749 						((BYTE*)(pDataArray->pvData))[ix] = pBytes[ix];
750 					hr = SafeArrayUnlock( pDataArray );
751 					if ( SUCCEEDED( hr ) )
752 					{
753 						CComVariant aArgs[1];
754 						aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
755 						CComVariant dummyResult;
756 						hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
757 						if( SUCCEEDED( hr ) )
758 							bSuccess = TRUE;
759 					}
760 				}
761 			}
762 		}
763 	}
764 
765 	if ( !bSuccess )
766 	{
767 		// the download failed, let StarOffice download
768 		bFinishDownload = TRUE;
769 		mpDispTempFile = CComPtr< IDispatch >();
770 	}
771 
772 	if ( bFinishDownload )
773 	{
774 		// trigger the loading now
775 		mbLoad = TRUE;
776 		mbReadyForActivation = TRUE;
777 
778     	Invalidate();
779     	UpdateWindow();
780 	}
781 }
782 
LoadURLToFrame()783 HRESULT CSOActiveX::LoadURLToFrame( )
784 {
785 	CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
786 	CComVariant aArgVals[4];
787 	unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
788 
789 	aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
790 	aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
791 	aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
792 
793 	if ( mpDispTempFile )
794 	{
795 		aArgVals[3] = CComVariant( mpDispTempFile );
796 		nCount = 4;
797 	}
798 
799 	HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
800 	if( !SUCCEEDED( hr ) ) return hr;
801 
802 	CComVariant aBarName( L"MenuBarVisible" );
803 	CComVariant aBarVis;
804 	aBarVis.vt = VT_BOOL; aBarVis.boolVal = VARIANT_FALSE;
805 	hr = CallDispatchMethod( L"slot:6661", &aBarName, &aBarVis, 1 );
806 	// does not work for some documents, but it is no error
807 	// if( !SUCCEEDED( hr ) ) return hr;
808 
809     // try to get the model and set the presetation specific property, the setting will fail for other document formats
810     CComPtr<IDispatch> pdispController;
811     hr = GetIDispByFunc( mpDispFrame, L"getController", NULL, 0, pdispController );
812     if ( SUCCEEDED( hr ) && pdispController )
813     {
814         CComPtr<IDispatch> pdispModel;
815         hr = GetIDispByFunc( pdispController, L"getModel", NULL, 0, pdispModel );
816         if ( SUCCEEDED( hr ) && pdispModel )
817         {
818             CComPtr<IDispatch> pdispPres;
819             hr = GetIDispByFunc( pdispModel, L"getPresentation", NULL, 0, pdispPres );
820             if ( SUCCEEDED( hr ) && pdispPres )
821             {
822                 // this is a presentation
823                 // let the slide show be shown in the document window
824                 OLECHAR* pPropName = L"IsFullScreen";
825                 CComVariant pPresProp;
826                 pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
827                 hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
828 
829                 // start the slide show
830                 if ( SUCCEEDED( hr ) )
831                 {
832                     CComVariant dummyResult;
833                     ExecuteFunc( pdispPres, L"Start", NULL, 0, &dummyResult );
834                 }
835             }
836         }
837     }
838 
839 	// create dispatch interceptor
840 	mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
841 	mpDispatchInterceptor->AddRef();
842 	mpDispatchInterceptor->SetParent( this );
843 	CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
844 
845 	// register dispatch interceptor in the frame
846         CComVariant aDispVariant( pIDispDispInter );
847 	CComVariant dummyResult;
848 	hr = ExecuteFunc( mpDispFrame,
849 					  L"registerDispatchProviderInterceptor",
850                                           &aDispVariant,
851 					  1,
852 					  &dummyResult );
853 
854 	if( !SUCCEEDED( hr ) ) return hr;
855 
856 	return S_OK;
857 }
858 
GetVersionConnected()859 SOVersion CSOActiveX::GetVersionConnected()
860 {
861 	SOVersion bResult = SO_NOT_DETECTED;
862 	if( mpDispFactory )
863 	{
864 		// create ConfigurationProvider instance
865 		CComPtr<IDispatch> pdispConfProv;
866         CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
867 		HRESULT hr = GetIDispByFunc( mpDispFactory,
868 							 L"createInstance",
869 							 &aServiceName,
870 							 1,
871 							 pdispConfProv );
872 
873 		if( SUCCEEDED( hr ) && pdispConfProv )
874 		{
875 			CComPtr<IDispatch> pdispConfAccess;
876 
877 			SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
878 
879 			if( pInitParams )
880 			{
881 				long ix = 0;
882 				CComVariant aConfPath( L"org.openoffice.Setup" );
883 				SafeArrayPutElement( pInitParams, &ix, &aConfPath );
884 
885 				CComVariant aArgs[2];
886 				aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
887 				aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
888 
889 				hr = GetIDispByFunc( pdispConfProv,
890 								 	L"createInstanceWithArguments",
891 									aArgs,
892 								 	2,
893 								 	pdispConfAccess );
894 
895 				if( SUCCEEDED( hr ) && pdispConfAccess )
896 				{
897 					CComVariant aOfficeName;
898 
899                     CComVariant aProductName( L"Product/ooName" );
900 					hr = ExecuteFunc( pdispConfAccess,
901 										L"getByHierarchicalName",
902 										&aProductName,
903 										1,
904 										&aOfficeName );
905 
906 					if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
907 					{
908 						CComVariant aOfficeVersion;
909 
910                         CComVariant aProductVersion( L"Product/ooSetupVersion" );
911 						hr = ExecuteFunc( pdispConfAccess,
912 											L"getByHierarchicalName",
913 											&aProductVersion,
914 											1,
915 											&aOfficeVersion );
916 
917 						if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
918 						{
919 							USES_CONVERSION;
920 							if( !strcmp( OLE2T( aOfficeName.bstrVal ), "StarOffice" ) )
921 							{
922 								if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.1", 3 ) )
923 									bResult = SO_61;
924 								else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.0", 3 ) )
925 									bResult = SO_60;
926 								else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "5.2", 3 ) )
927 									bResult = SO_52;
928 								else
929 									bResult = SO_UNKNOWN;
930 							}
931 							else // OpenOffice
932 							{
933 								if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.1", 3 ) )
934 									bResult = OO_11;
935 								else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.0", 3 ) )
936 									bResult = OO_10;
937 								else
938 									bResult = OO_UNKNOWN;
939 							}
940 						}
941 					}
942 				}
943 			}
944 		}
945 	}
946 
947 	return bResult;
948 }
949 
950 class LockingGuard
951 {
952 	BOOL& mbLocked;
953 public:
LockingGuard(BOOL & bLocked)954 	LockingGuard( BOOL& bLocked )
955 	: mbLocked( bLocked )
956 	{
957 		mbLocked = TRUE;
958 	}
959 
~LockingGuard()960 	~LockingGuard()
961 	{
962 		mbLocked = FALSE;
963 	}
964 };
965 
OnDrawAdvanced(ATL_DRAWINFO & di)966 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
967 {
968 	// This method is called only in main thread, no need to lock it
969 
970 	// Get read of reentrance problems
971 	if ( mbDrawLocked )
972 		return S_OK;
973 	LockingGuard aGuard( mbDrawLocked );
974 
975     if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
976     {
977     	HWND hwnd;
978 	    HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
979 		if( !SUCCEEDED( hr ) ) return hr;
980 
981         if( mParentWin != hwnd || !mOffWin )
982         {
983 			if( mpDispFrame )
984 			{
985 				CComVariant dummyResult;
986 				CComVariant aPropVar;
987 				aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
988 				HRESULT hr = ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
989                 (void)hr;
990 				mpDispFrame = CComPtr<IDispatch>();
991 			}
992 
993             mParentWin = hwnd;
994             mOffWin = CreateWindow(
995 								STAROFFICE_WINDOWCLASS,
996 								"OfficeContainer",
997 								WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
998 								di.prcBounds->left,
999 								di.prcBounds->top,
1000 								di.prcBounds->right - di.prcBounds->left,
1001 								di.prcBounds->bottom - di.prcBounds->top,
1002 								mParentWin,
1003 								NULL,
1004 								NULL,
1005 								NULL );
1006 
1007 			::ShowWindow( mOffWin, SW_SHOW );
1008         }
1009         else
1010         {
1011             RECT aRect;
1012             ::GetWindowRect( mOffWin, &aRect );
1013 
1014             if( aRect.left !=  di.prcBounds->left || aRect.top != di.prcBounds->top
1015              || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
1016 			{
1017 				// on this state the office window should exist already
1018                 ::SetWindowPos( mOffWin,
1019                               HWND_TOP,
1020 							  di.prcBounds->left,
1021 							  di.prcBounds->top,
1022 							  di.prcBounds->right - di.prcBounds->left,
1023 							  di.prcBounds->bottom - di.prcBounds->top,
1024                               SWP_NOZORDER );
1025 
1026 				CComVariant aPosArgs[5];
1027 				aPosArgs[4] = CComVariant( 0 );
1028 				aPosArgs[3] = CComVariant( 0 );
1029 				aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
1030 				aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
1031 				aPosArgs[0] = CComVariant( 12 );
1032 				CComVariant dummyResult;
1033 				hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
1034 				if( !SUCCEEDED( hr ) ) return hr;
1035 			}
1036         }
1037 
1038 		if( !mnVersion )
1039 		{
1040 			OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
1041 			return E_FAIL;
1042 		}
1043 
1044 		if( ! mpDispFrame )
1045 		{
1046 			hr = CreateFrameOldWay( mOffWin,
1047 							di.prcBounds->right - di.prcBounds->left,
1048 							di.prcBounds->bottom - di.prcBounds->top );
1049 
1050 			if( !SUCCEEDED( hr ) )
1051 			{
1052 				// if the frame can not be opened do not try any more
1053 				mbReadyForActivation = FALSE;
1054 				OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1055 				return hr;
1056 			}
1057 		}
1058 
1059 		if( mbLoad )
1060 		{
1061 			hr = LoadURLToFrame();
1062 			mbLoad = FALSE;
1063 
1064 			if( !SUCCEEDED( hr ) )
1065 			{
1066 				// if the document can not be opened do not try any more
1067 				mbReadyForActivation = FALSE;
1068 
1069 				OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1070 
1071 				return hr;
1072 			}
1073 		}
1074 	}
1075 	else
1076 	{
1077 		// activate the fallback
1078 		CComControl<CSOActiveX>::OnDrawAdvanced( di );
1079 	}
1080 
1081 	return S_OK;
1082 }
1083 
OnDraw(ATL_DRAWINFO & di)1084 HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
1085 {
1086 	// fallback that is activated by the parent class
1087 	if ( di.hdcDraw )
1088 		FillRect( di.hdcDraw, (RECT*)di.prcBounds, (HBRUSH)COLOR_BACKGROUND );
1089 
1090 	return S_OK;
1091 }
1092 
SetClientSite(IOleClientSite * aClientSite)1093 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
1094 {
1095 	HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
1096 
1097 	if( !aClientSite )
1098 	{
1099 		//ATLASSERT( mWebBrowser2 );
1100 		if( mWebBrowser2 )
1101 			AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
1102 		return hr;
1103 	}
1104 
1105 	CComPtr<IOleContainer> aContainer;
1106 	m_spClientSite->GetContainer( &aContainer );
1107 //	ATLASSERT( aContainer );
1108 
1109 	if( SUCCEEDED( hr )  && aContainer )
1110 	{
1111 		CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
1112 		//ATLASSERT( aServiceProvider );
1113 
1114 		if( aServiceProvider )
1115 		{
1116 			aServiceProvider->QueryService( SID_SInternetExplorer,
1117 											IID_IWebBrowser,
1118 											(void**)&mWebBrowser2 );
1119 //			ATLASSERT( mWebBrowser2 );
1120 			if( mWebBrowser2 )
1121 				AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
1122 		}
1123 	}
1124 
1125 	return hr;
1126 }
1127 
Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pvarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1128 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
1129 							    REFIID riid,
1130 							    LCID lcid,
1131                                 WORD wFlags,
1132 							    DISPPARAMS* pDispParams,
1133                                 VARIANT* pvarResult,
1134 							    EXCEPINFO* pExcepInfo,
1135                                 UINT* puArgErr)
1136 {
1137     if (riid != IID_NULL)
1138         return DISP_E_UNKNOWNINTERFACE;
1139 
1140     if (!pDispParams)
1141         return DISP_E_PARAMNOTOPTIONAL;
1142 
1143 	if ( dispidMember == DISPID_ONQUIT )
1144 		Cleanup();
1145 
1146     IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
1147                   &LIBID_SO_ACTIVEXLib>::Invoke(
1148              dispidMember, riid, lcid, wFlags, pDispParams,
1149              pvarResult, pExcepInfo, puArgErr);
1150 
1151     return S_OK;
1152 }
1153 
GetURL(const OLECHAR * url,const OLECHAR * target)1154 HRESULT CSOActiveX::GetURL( const OLECHAR* url,
1155                               const OLECHAR* target )
1156 {
1157     CComVariant aEmpty1, aEmpty2, aEmpty3;
1158     CComVariant aUrl( url );
1159     CComVariant aTarget;
1160     if ( target )
1161         aTarget = CComVariant( target );
1162 
1163     return mWebBrowser2->Navigate2( &aUrl,
1164                                   &aEmpty1,
1165                                   &aTarget,
1166                                   &aEmpty2,
1167                                   &aEmpty3 );
1168 }
1169 
1170 
1171 // ---------------------------------------------------------------------------
1172 
1173