Update ooo320-m1
[ooovba.git] / odk / examples / OLE / activex / SOActiveX.cpp
blobfd44a9aa16471c0e4d1e50230e7e78b4341da23b
1 /*************************************************************************
3 * $RCSfile: SOActiveX.cpp,v $
5 * $Revision: 1.4 $
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
10 * the BSD license.
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
17 * are met:
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
43 #include "stdafx2.h"
44 #include "so_activex.h"
45 #include "SOActiveX.h"
46 #include "SOComWindowPeer.h"
48 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
50 #define BARS_NUMBER 3
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,
72 OLECHAR* sFuncName,
73 CComVariant* params,
74 unsigned int count,
75 CComVariant* pResult )
77 if( !idispUnoObject )
78 return E_FAIL;
80 DISPID id;
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};
86 // DEBUG
87 EXCEPINFO myInfo;
88 return idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
89 &dispparams, pResult, &myInfo, 0);
92 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
93 OLECHAR* sFuncName,
94 CComVariant* params,
95 unsigned int count,
96 CComPtr<IDispatch>& pdispResult )
98 if( !idispUnoObject )
99 return E_FAIL;
101 CComVariant result;
102 HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
103 if( !SUCCEEDED( hr ) ) return hr;
105 if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
106 return hr;
108 pdispResult = CComPtr<IDispatch>( result.pdispVal );
110 return S_OK;
113 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
114 OLECHAR** sMemberNames,
115 CComVariant* pVariant,
116 unsigned int count )
118 for( unsigned int ind = 0; ind < count; ind++ )
120 DISPID id;
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;
128 return S_OK;
131 /////////////////////////////////////////////////////////////////////////////
132 // CSOActiveX
134 CSOActiveX::CSOActiveX()
135 : mCookie(0)
136 , mCurFileUrl( L"private:factory/swriter" )
137 , mbLoad( FALSE )
138 , mParentWin( NULL )
139 , mOffWin( NULL )
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()
161 Cleanup();
165 HRESULT CSOActiveX::Cleanup()
167 if( mpDispFrame && mbViewOnly )
169 ShowSomeBars();
170 mbViewOnly = FALSE;
173 if( mpDispFrame )
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 );
184 return S_OK;
188 STDMETHODIMP CSOActiveX::InitNew ()
190 mbLoad = TRUE;
191 return S_OK;
194 STDMETHODIMP CSOActiveX::Load ( LPSTREAM pStm )
196 mbLoad = TRUE;
198 // may be later?
199 // for now just ignore
201 return S_OK;
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 ) )
211 return hr;
213 unsigned long aNum;
214 hr = pPropBag2->CountProperties( &aNum );
215 ATLASSERT( hr >= 0 );
216 if( !SUCCEEDED( hr ) )
217 return hr;
219 PROPBAG2* aPropNames = new PROPBAG2[aNum];
220 unsigned long aReaded;
222 hr = pPropBag2->GetPropertyInfo( 0,
223 aNum,
224 aPropNames,
225 &aReaded );
226 ATLASSERT( hr >= 0 );
227 if( !SUCCEEDED( hr ) )
229 delete[] aPropNames;
230 return hr;
233 CComVariant* aVal = new CComVariant[aNum];
234 HRESULT* hvs = new HRESULT[aNum];
235 hr = pPropBag2->Read( aNum,
236 aPropNames,
237 NULL,
238 aVal,
239 hvs );
240 ATLASSERT( hr >= 0 );
241 if( !SUCCEEDED( hr ) )
243 delete[] hvs;
244 delete[] aVal;
245 delete[] aPropNames;
246 return hr;
249 USES_CONVERSION;
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" ) )
262 mbViewOnly = TRUE;
264 else
266 // the default value
267 mbViewOnly = FALSE;
272 delete[] hvs;
273 delete[] aVal;
274 delete[] aPropNames;
276 if( !mpDispFactory )
277 return hr;
279 mbLoad = TRUE;
281 Invalidate();
282 UpdateWindow();
284 return hr;
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";
298 DISPID nURLID;
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,
306 L"createInstance",
307 &CComVariant( L"com.sun.star.util.URLTransformer" ),
309 pdispTransformer );
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;
319 return S_OK;
323 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
325 if( !mpDispFactory )
326 return E_FAIL;
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",
339 L"Y",
340 L"Width",
341 L"Height" };
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",
356 L"ParentIndex",
357 L"Parent",
358 L"Bounds",
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;
379 // create frame
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;
389 // initialize frame
390 CComVariant dummyResult;
391 hr = ExecuteFunc( mpDispFrame, L"initialize", &CComVariant( mpDispWin ), 1, &dummyResult );
392 if( !SUCCEEDED( hr ) ) return hr;
394 // create desktop
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;
408 // initialize window
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;
425 return S_OK;
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,
440 L"queryDispatch",
441 aArgs,
443 pdispXDispatch );
444 if( !SUCCEEDED( hr ) ) return hr;
446 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
447 long ix = 0;
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;
470 return S_OK;
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;
482 return S_OK;
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;
493 return S_OK;
496 HRESULT CSOActiveX::LoadURLToFrame( )
498 HRESULT hr = CallDispatch1PBool( mCurFileUrl, L"ReadOnly", mbViewOnly );
499 if( !SUCCEEDED( hr ) ) return hr;
501 if( mbViewOnly )
502 HideAllBars();
504 return S_OK;
507 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
509 if( m_spInPlaceSite && mCurFileUrl )
511 HWND hwnd;
512 HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
513 if( !SUCCEEDED( hr ) ) return hr;
515 if( mParentWin != hwnd || !mOffWin )
517 if( mpDispFrame )
519 CComVariant dummyResult;
520 ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
521 mpDispFrame = CComPtr<IDispatch>();
524 mParentWin = hwnd;
525 mOffWin = CreateWindow(
526 STAROFFICE_WINDOWCLASS,
527 "OfficeContainer",
528 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
529 di.prcBounds->left,
530 di.prcBounds->top,
531 di.prcBounds->right - di.prcBounds->left,
532 di.prcBounds->bottom - di.prcBounds->top,
533 mParentWin,
534 NULL,
535 NULL,
536 NULL );
538 ::ShowWindow( mOffWin, SW_SHOW );
540 else
542 RECT aRect;
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,
550 HWND_TOP,
551 di.prcBounds->left,
552 di.prcBounds->top,
553 di.prcBounds->right - di.prcBounds->left,
554 di.prcBounds->bottom - di.prcBounds->top,
555 SWP_NOZORDER );
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;
569 if( ! mpDispFrame )
571 hr = CreateFrameOldWay( mOffWin,
572 di.prcBounds->right - di.prcBounds->left,
573 di.prcBounds->bottom - di.prcBounds->top );
574 if( !SUCCEEDED( hr ) ) return hr;
577 if( mbLoad )
579 hr = LoadURLToFrame();
580 if( !SUCCEEDED( hr ) ) return hr;
581 mbLoad = FALSE;
585 return S_OK;
589 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
591 HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
593 if( !aClientSite )
595 ATLASSERT( mWebBrowser2 );
596 if( mWebBrowser2 )
597 AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
598 return hr;
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,
613 IID_IWebBrowser,
614 (void**)&mWebBrowser2 );
615 ATLASSERT( mWebBrowser2 );
616 if( mWebBrowser2 )
617 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
621 return hr;
624 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
625 REFIID riid,
626 LCID lcid,
627 WORD wFlags,
628 DISPPARAMS* pDispParams,
629 VARIANT* pvarResult,
630 EXCEPINFO* pExcepInfo,
631 UINT* puArgErr)
633 if (riid != IID_NULL)
634 return DISP_E_UNKNOWNINTERFACE;
636 if (!pDispParams)
637 return DISP_E_PARAMNOTOPTIONAL;
639 if ( dispidMember == DISPID_ONQUIT )
640 Cleanup();
642 IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
643 &LIBID_SO_ACTIVEXLib>::Invoke(
644 dispidMember, riid, lcid, wFlags, pDispParams,
645 pvarResult, pExcepInfo, puArgErr);
647 return S_OK;
650 // ---------------------------------------------------------------------------