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 
23 
24 // SOActiveX.cpp : Implementation of CSOActiveX
25 
26 #include "stdafx2.h"
27 #include "so_activex.h"
28 #include "SOActiveX.h"
29 #include "SOComWindowPeer.h"
30 
31 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
32 
33 #define BARS_NUMBER  3
34 #define BARS_TO_SHOW 2
35 
36 OLECHAR* pSlotUrl[BARS_NUMBER] =
37 						{L"slot:5910" // SID_TOGGLEFUNCTIONBAR
38 						,L"slot:5920" // SID_TOGGLESTATUSBAR
39 						,L"slot:6661" // SID_TOGGLE_MENUBAR
40 //						,L"slot:10603" // SID_HYPERLINK_INSERT
41 						};
42 
43 OLECHAR* pSlotName[BARS_NUMBER] =
44 						{L"FunctionBarVisible"		// SID_TOGGLEFUNCTIONBAR
45 						,L"StatusBarVisible"		// SID_TOGGLESTATUSBAR
46 						,L"MenuBarVisible"			// SID_TOGGLE_MENUBAR
47 //						,L"InsertHyperlink"			// SID_HYPERLINK_INSERT
48 						};
49 
50 
51 
52 /////////////////////////////////////////////////////////////////////////////
53 
ExecuteFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComVariant * pResult)54 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
55 					 OLECHAR* sFuncName,
56 					 CComVariant* params,
57 					 unsigned int count,
58 					 CComVariant* pResult )
59 {
60 	if( !idispUnoObject )
61 		return E_FAIL;
62 
63 	DISPID id;
64 	HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
65 	if( !SUCCEEDED( hr ) ) return hr;
66 
67 	DISPPARAMS dispparams= { params, 0, count, 0};
68 
69 	// DEBUG
70 	EXCEPINFO myInfo;
71 	return idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
72                     &dispparams, pResult, &myInfo, 0);
73 }
74 
GetIDispByFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComPtr<IDispatch> & pdispResult)75 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
76 					  	OLECHAR* sFuncName,
77 					  	CComVariant* params,
78 					  	unsigned int count,
79 					  	CComPtr<IDispatch>& pdispResult )
80 {
81 	if( !idispUnoObject )
82 		return E_FAIL;
83 
84 	CComVariant result;
85 	HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
86 	if( !SUCCEEDED( hr ) ) return hr;
87 
88 	if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
89 		return hr;
90 
91 	pdispResult = CComPtr<IDispatch>( result.pdispVal );
92 
93 	return S_OK;
94 }
95 
PutPropertiesToIDisp(IDispatch * pdispObject,OLECHAR ** sMemberNames,CComVariant * pVariant,unsigned int count)96 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
97 							  OLECHAR** sMemberNames,
98 							  CComVariant* pVariant,
99 							  unsigned int count )
100 {
101 	for( unsigned int ind = 0; ind < count; ind++ )
102 	{
103 		DISPID id;
104 		HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
105 		if( !SUCCEEDED( hr ) ) return hr;
106 
107 		hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
108 		if( !SUCCEEDED( hr ) ) return hr;
109 	}
110 
111 	return S_OK;
112 }
113 
114 /////////////////////////////////////////////////////////////////////////////
115 // CSOActiveX
116 
CSOActiveX()117 CSOActiveX::CSOActiveX()
118 : mCookie(0)
119 , mCurFileUrl( L"private:factory/swriter" )
120 , mbLoad( FALSE )
121 , mParentWin( NULL )
122 , mOffWin( NULL )
123 , mbViewOnly( FALSE )
124 {
125 	CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
126 	HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
127 
128     mPWinClass.style			= CS_HREDRAW|CS_VREDRAW;
129     mPWinClass.lpfnWndProc		= ::DefWindowProc;
130     mPWinClass.cbClsExtra		= 0;
131     mPWinClass.cbWndExtra		= 0;
132     mPWinClass.hInstance		= (HINSTANCE) GetModuleHandle(NULL); //myInstance;
133     mPWinClass.hIcon			= NULL;
134     mPWinClass.hCursor			= NULL;
135     mPWinClass.hbrBackground	= (HBRUSH) COLOR_BACKGROUND;
136     mPWinClass.lpszMenuName	    = NULL;
137     mPWinClass.lpszClassName	= STAROFFICE_WINDOWCLASS;
138 
139 	RegisterClass(&mPWinClass);
140 }
141 
~CSOActiveX()142 CSOActiveX::~CSOActiveX()
143 {
144 	Cleanup();
145 
146 }
147 
Cleanup()148 HRESULT CSOActiveX::Cleanup()
149 {
150 	if( mpDispFrame && mbViewOnly )
151 	{
152 		ShowSomeBars();
153 		mbViewOnly = FALSE;
154 	}
155 
156 	if( mpDispFrame )
157 	{
158 		// mpDispFrame->dispose();
159 		CComVariant dummyResult;
160 		ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
161 		mpDispFrame = CComPtr< IDispatch >();
162 	}
163 
164 	if( ::IsWindow( mOffWin ) )
165 		::DestroyWindow( mOffWin );
166 
167 	return S_OK;
168 }
169 
170 
InitNew()171 STDMETHODIMP CSOActiveX::InitNew ()
172 {
173 	mbLoad = TRUE;
174     return S_OK;
175 }
176 
Load(LPSTREAM pStm)177 STDMETHODIMP CSOActiveX::Load ( LPSTREAM pStm )
178 {
179 	mbLoad = TRUE;
180 
181 	// may be later?
182 	// for now just ignore
183 
184     return S_OK;
185 }
186 
Load(LPPROPERTYBAG pPropBag,LPERRORLOG pErrorLog)187 STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog )
188 {
189     IPropertyBag2* pPropBag2;
190     HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
191     ATLASSERT( hr >= 0 );
192 
193     if( !SUCCEEDED( hr ) )
194         return hr;
195 
196     unsigned long aNum;
197     hr = pPropBag2->CountProperties( &aNum );
198     ATLASSERT( hr >= 0 );
199     if( !SUCCEEDED( hr ) )
200         return hr;
201 
202     PROPBAG2* aPropNames = new PROPBAG2[aNum];
203     unsigned long aReaded;
204 
205     hr = pPropBag2->GetPropertyInfo( 0,
206                                      aNum,
207                                      aPropNames,
208                                      &aReaded );
209     ATLASSERT( hr >= 0 );
210     if( !SUCCEEDED( hr ) )
211     {
212         delete[] aPropNames;
213         return hr;
214     }
215 
216 	CComVariant* aVal = new CComVariant[aNum];
217     HRESULT*     hvs = new HRESULT[aNum];
218 	hr = pPropBag2->Read( aNum,
219                           aPropNames,
220                           NULL,
221                           aVal,
222                           hvs );
223     ATLASSERT( hr >= 0 );
224     if( !SUCCEEDED( hr ) )
225     {
226         delete[] hvs;
227         delete[] aVal;
228         delete[] aPropNames;
229         return hr;
230     }
231 
232 	USES_CONVERSION;
233     for( unsigned long ind = 0; ind < aNum; ind++ )
234     {
235 		// all information from the 'object' tag is in strings
236 		if( aVal[ind].vt == VT_BSTR && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
237 		{
238             mCurFileUrl = wcsdup( aVal[ind].bstrVal );
239 		}
240 		else if( aVal[ind].vt == VT_BSTR
241 				&& !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
242 		{
243 			if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
244 			{
245 				mbViewOnly = TRUE;
246 			}
247 			else
248 			{
249 				// the default value
250 				mbViewOnly = FALSE;
251 			}
252 		}
253     }
254 
255     delete[] hvs;
256     delete[] aVal;
257     delete[] aPropNames;
258 
259 	if( !mpDispFactory )
260 		return hr;
261 
262 	mbLoad = TRUE;
263 
264     Invalidate();
265     UpdateWindow();
266 
267 	return hr;
268 }
269 
GetUnoStruct(OLECHAR * sStructName,CComPtr<IDispatch> & pdispResult)270 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
271 {
272 	return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &CComVariant( sStructName ), 1, pdispResult );
273 }
274 
GetUrlStruct(OLECHAR * sUrl,CComPtr<IDispatch> & pdispUrl)275 HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
276 {
277 	HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
278 	if( !SUCCEEDED( hr ) ) return hr;
279 
280 	OLECHAR* sURLMemberName = L"Complete";
281 	DISPID nURLID;
282 	hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
283 	if( !SUCCEEDED( hr ) ) return hr;
284 	hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &CComVariant( sUrl ) );
285 	if( !SUCCEEDED( hr ) ) return hr;
286 
287 	CComPtr<IDispatch> pdispTransformer;
288 	hr = GetIDispByFunc( mpDispFactory,
289 						 L"createInstance",
290 						 &CComVariant( L"com.sun.star.util.URLTransformer" ),
291 						 1,
292 						 pdispTransformer );
293 	if( !SUCCEEDED( hr ) ) return hr;
294 
295 	CComVariant dummyResult;
296 	CComVariant aInOutParam;
297 	aInOutParam.ppdispVal = &pdispUrl;
298 	aInOutParam.vt = VT_DISPATCH | VT_BYREF;
299 	hr = ExecuteFunc( pdispTransformer, L"parseStrict", &aInOutParam, 1, &dummyResult );
300 	if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
301 
302 	return S_OK;
303 }
304 
305 
CreateFrameOldWay(HWND hwnd,int width,int height)306 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
307 {
308 	if( !mpDispFactory )
309 		return E_FAIL;
310 
311 	// create window handle holder
312 	CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>( hwnd );
313 	pPeerToSend->SetHWNDInternally( hwnd );
314 	CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
315 
316 	// create rectangle structure
317 	CComPtr<IDispatch> pdispRectangle;
318 	HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
319 	if( !SUCCEEDED( hr ) ) return hr;
320 
321 	OLECHAR* sRectMemberNames[4] = { L"X",
322 								 	 L"Y",
323 								 	 L"Width",
324 								 	 L"Height" };
325 	CComVariant pRectVariant[4];
326 	pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
327 
328 	hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
329 	if( !SUCCEEDED( hr ) ) return hr;
330 
331 	// create WindowDescriptor structure
332 	CComPtr<IDispatch> pdispWinDescr;
333 	hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
334 	if( !SUCCEEDED( hr ) ) return hr;
335 
336 	// fill in descriptor with info
337 	OLECHAR* sDescriptorMemberNames[6] = { L"Type",
338 								 L"WindowServiceName",
339 								 L"ParentIndex",
340 								 L"Parent",
341 								 L"Bounds",
342 								 L"WindowAttributes" };
343 	CComVariant pDescriptorVar[6];
344 	pDescriptorVar[0] = CComVariant( 0 );
345 	pDescriptorVar[1] = CComVariant( L"workwindow" );
346 	pDescriptorVar[2] = CComVariant( 1 );
347 	pDescriptorVar[3] = CComVariant( pIDispToSend );
348 	pDescriptorVar[4] = CComVariant( pdispRectangle );
349 	pDescriptorVar[5] = CComVariant( 33 );
350 	hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
351 	if( !SUCCEEDED( hr ) ) return hr;
352 
353 	// create XToolkit instance
354 	CComPtr<IDispatch> pdispToolkit;
355 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &CComVariant( L"com.sun.star.awt.Toolkit" ), 1, pdispToolkit );
356 	if( !SUCCEEDED( hr ) ) return hr;
357 
358 	// create window with toolkit
359 	hr = GetIDispByFunc( pdispToolkit, L"createWindow", &CComVariant( pdispWinDescr ), 1, mpDispWin );
360 	if( !SUCCEEDED( hr ) ) return hr;
361 
362 	// create frame
363 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &CComVariant( L"com.sun.star.frame.Task" ), 1, mpDispFrame );
364 	if( !SUCCEEDED( hr ) || !mpDispFrame )
365 	{
366 		// the interface com.sun.star.frame.Task is removed in 6.1
367 		// but the interface com.sun.star.frame.Frame has some bugs in 6.0
368 		hr = GetIDispByFunc( mpDispFactory, L"createInstance", &CComVariant( L"com.sun.star.frame.Frame" ), 1, mpDispFrame );
369 		if( !SUCCEEDED( hr ) ) return hr;
370 	}
371 
372 	// initialize frame
373 	CComVariant dummyResult;
374 	hr = ExecuteFunc( mpDispFrame, L"initialize", &CComVariant( mpDispWin ), 1, &dummyResult );
375 	if( !SUCCEEDED( hr ) ) return hr;
376 
377 	// create desktop
378 	CComPtr<IDispatch> pdispDesktop;
379 	hr = GetIDispByFunc( mpDispFactory, L"createInstance", &CComVariant( L"com.sun.star.frame.Desktop" ), 1, pdispDesktop );
380 	if( !SUCCEEDED( hr ) ) return hr;
381 
382 	// create tree of frames
383 	CComPtr<IDispatch> pdispChildren;
384 	hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
385 	if( !SUCCEEDED( hr ) ) return hr;
386 
387 	// insert new frame into desctop hierarchy
388 	hr = ExecuteFunc( pdispChildren, L"append", &CComVariant( mpDispFrame ), 1, &dummyResult );
389 	if( !SUCCEEDED( hr ) ) return hr;
390 
391 	// initialize window
392 	hr = ExecuteFunc( mpDispWin, L"setBackground", &CComVariant( (long)0xFFFFFFFF ), 1, &dummyResult );
393 	if( !SUCCEEDED( hr ) ) return hr;
394 
395 	hr = ExecuteFunc( mpDispWin, L"setVisible", &CComVariant( TRUE ), 1, &dummyResult );
396 	if( !SUCCEEDED( hr ) ) return hr;
397 
398 	CComVariant aPosArgs[5];
399 	aPosArgs[4] = CComVariant( 0 );
400 	aPosArgs[3] = CComVariant( 0 );
401 	aPosArgs[2] = CComVariant( width );
402 	aPosArgs[1] = CComVariant( height );
403 	aPosArgs[0] = CComVariant( 12 );
404 	hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
405 	if( !SUCCEEDED( hr ) ) return hr;
406 
407 
408 	return S_OK;
409 }
410 
CallDispatch1PBool(OLECHAR * sUrl,OLECHAR * sArgName,BOOL sArgVal)411 HRESULT CSOActiveX::CallDispatch1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
412 {
413 	CComPtr<IDispatch> pdispURL;
414 	HRESULT hr = GetUrlStruct( sUrl, pdispURL );
415 	if( !SUCCEEDED( hr ) ) return hr;
416 
417 	CComPtr<IDispatch> pdispXDispatch;
418 	CComVariant aArgs[3];
419 	aArgs[2] = CComVariant( pdispURL );
420 	aArgs[1] = CComVariant( L"" );
421 	aArgs[0] = CComVariant( (int)0 );
422 	hr = GetIDispByFunc( mpDispFrame,
423 						 L"queryDispatch",
424 						 aArgs,
425 						 3,
426 						 pdispXDispatch );
427 	if( !SUCCEEDED( hr ) ) return hr;
428 
429 	SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
430 	long ix = 0;
431 	CComPtr<IDispatch> pdispPropVal;
432 	hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
433 	if( !SUCCEEDED( hr ) ) return hr;
434 
435 	OLECHAR* 	sPropMemberNames[2] = { L"Name", L"Value" };
436 	CComVariant pPropVar[2];
437 	pPropVar[0] = CComVariant( sArgName );
438 	pPropVar[1] = CComVariant(); pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
439 	hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
440 	if( !SUCCEEDED( hr ) ) return hr;
441 
442 	SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
443 
444 	CComVariant aDispArgs[2];
445 	aDispArgs[1] = CComVariant( pdispURL );
446 	// aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
447 	aDispArgs[0] = CComVariant(); aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
448 
449 	CComVariant dummyResult;
450 	hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
451 	if( !SUCCEEDED( hr ) ) return hr;
452 
453 	return S_OK;
454 }
455 
ShowSomeBars()456 HRESULT CSOActiveX::ShowSomeBars()
457 {
458 	// show FunctionBar and StatusBar
459 	for( int ind = 0; ind < BARS_TO_SHOW; ind ++ )
460 	{
461 		HRESULT hr = CallDispatch1PBool( pSlotUrl[ind], pSlotName[ind], TRUE );
462 		if( !SUCCEEDED( hr ) ) return hr;
463 	}
464 
465 	return S_OK;
466 }
467 
HideAllBars()468 HRESULT CSOActiveX::HideAllBars()
469 {
470 	for( int ind = 0; ind < BARS_NUMBER; ind ++ )
471 	{
472 		HRESULT hr = CallDispatch1PBool( pSlotUrl[ind], pSlotName[ind], FALSE );
473 		if( !SUCCEEDED( hr ) ) return hr;
474 	}
475 
476 	return S_OK;
477 }
478 
LoadURLToFrame()479 HRESULT CSOActiveX::LoadURLToFrame( )
480 {
481 	HRESULT hr = CallDispatch1PBool( mCurFileUrl, L"ReadOnly", mbViewOnly );
482 	if( !SUCCEEDED( hr ) ) return hr;
483 
484 	if( mbViewOnly )
485 		HideAllBars();
486 
487 	return S_OK;
488 }
489 
OnDrawAdvanced(ATL_DRAWINFO & di)490 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
491 {
492     if( m_spInPlaceSite && mCurFileUrl )
493     {
494     	HWND hwnd;
495 	    HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
496 		if( !SUCCEEDED( hr ) ) return hr;
497 
498         if( mParentWin != hwnd || !mOffWin )
499         {
500 			if( mpDispFrame )
501 			{
502 				CComVariant dummyResult;
503 				ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
504 				mpDispFrame = CComPtr<IDispatch>();
505 			}
506 
507             mParentWin = hwnd;
508             mOffWin = CreateWindow(
509 								STAROFFICE_WINDOWCLASS,
510 								"OfficeContainer",
511 								WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
512 								di.prcBounds->left,
513 								di.prcBounds->top,
514 								di.prcBounds->right - di.prcBounds->left,
515 								di.prcBounds->bottom - di.prcBounds->top,
516 								mParentWin,
517 								NULL,
518 								NULL,
519 								NULL );
520 
521 			::ShowWindow( mOffWin, SW_SHOW );
522         }
523         else
524         {
525             RECT aRect;
526             ::GetWindowRect( mOffWin, &aRect );
527 
528             if( aRect.left !=  di.prcBounds->left || aRect.top != di.prcBounds->top
529              || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
530 			{
531 				// on this state the office window should exist already
532                 ::SetWindowPos( mOffWin,
533                               HWND_TOP,
534 							  di.prcBounds->left,
535 							  di.prcBounds->top,
536 							  di.prcBounds->right - di.prcBounds->left,
537 							  di.prcBounds->bottom - di.prcBounds->top,
538                               SWP_NOZORDER );
539 
540 				CComVariant aPosArgs[5];
541 				aPosArgs[4] = CComVariant( 0 );
542 				aPosArgs[3] = CComVariant( 0 );
543 				aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
544 				aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
545 				aPosArgs[0] = CComVariant( 12 );
546 				CComVariant dummyResult;
547 				hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
548 				if( !SUCCEEDED( hr ) ) return hr;
549 			}
550         }
551 
552 		if( ! mpDispFrame )
553 		{
554 			hr = CreateFrameOldWay( mOffWin,
555 							di.prcBounds->right - di.prcBounds->left,
556 							di.prcBounds->bottom - di.prcBounds->top );
557 			if( !SUCCEEDED( hr ) ) return hr;
558 		}
559 
560 		if( mbLoad )
561 		{
562 			hr = LoadURLToFrame();
563 			if( !SUCCEEDED( hr ) ) return hr;
564 			mbLoad = FALSE;
565 		}
566 	}
567 
568 	return S_OK;
569 }
570 
571 
SetClientSite(IOleClientSite * aClientSite)572 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
573 {
574 	HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
575 
576 	if( !aClientSite )
577 	{
578 		ATLASSERT( mWebBrowser2 );
579 		if( mWebBrowser2 )
580 			AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
581 		return hr;
582 	}
583 
584 	CComPtr<IOleContainer> aContainer;
585 	m_spClientSite->GetContainer( &aContainer );
586 	ATLASSERT( aContainer );
587 
588 	if( SUCCEEDED( hr )  && aContainer )
589 	{
590 		CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
591 		ATLASSERT( aServiceProvider );
592 
593 		if( aServiceProvider )
594 		{
595 			aServiceProvider->QueryService( SID_SInternetExplorer,
596 											IID_IWebBrowser,
597 											(void**)&mWebBrowser2 );
598 			ATLASSERT( mWebBrowser2 );
599 			if( mWebBrowser2 )
600 				AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
601 		}
602 	}
603 
604 	return hr;
605 }
606 
Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pvarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)607 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
608 							    REFIID riid,
609 							    LCID lcid,
610                                 WORD wFlags,
611 							    DISPPARAMS* pDispParams,
612                                 VARIANT* pvarResult,
613 							    EXCEPINFO* pExcepInfo,
614                                 UINT* puArgErr)
615 {
616     if (riid != IID_NULL)
617         return DISP_E_UNKNOWNINTERFACE;
618 
619     if (!pDispParams)
620         return DISP_E_PARAMNOTOPTIONAL;
621 
622 	if ( dispidMember == DISPID_ONQUIT )
623 		Cleanup();
624 
625     IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
626                   &LIBID_SO_ACTIVEXLib>::Invoke(
627              dispidMember, riid, lcid, wFlags, pDispParams,
628              pvarResult, pExcepInfo, puArgErr);
629 
630     return S_OK;
631 }
632 
633 // ---------------------------------------------------------------------------
634 
635