Branch libreoffice-5-0-4
[LibreOffice.git] / odk / examples / OLE / activex / SOActiveX.cpp
blobe264290a6db677c011e2f28cc6b7ce857463256d
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
5 * the BSD license.
7 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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
38 #include "stdafx2.h"
39 #include "so_activex.h"
40 #include "SOActiveX.h"
41 #include "SOComWindowPeer.h"
43 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
45 #define BARS_NUMBER 3
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,
65 OLECHAR* sFuncName,
66 CComVariant* params,
67 unsigned int count,
68 CComVariant* pResult )
70 if( !idispUnoObject )
71 return E_FAIL;
73 DISPID id;
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};
79 // DEBUG
80 EXCEPINFO myInfo;
81 return idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
82 &dispparams, pResult, &myInfo, 0);
85 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
86 OLECHAR* sFuncName,
87 CComVariant* params,
88 unsigned int count,
89 CComPtr<IDispatch>& pdispResult )
91 if( !idispUnoObject )
92 return E_FAIL;
94 CComVariant result;
95 HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
96 if( !SUCCEEDED( hr ) ) return hr;
98 if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
99 return hr;
101 pdispResult = CComPtr<IDispatch>( result.pdispVal );
103 return S_OK;
106 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
107 OLECHAR** sMemberNames,
108 CComVariant* pVariant,
109 unsigned int count )
111 for( unsigned int ind = 0; ind < count; ind++ )
113 DISPID id;
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;
121 return S_OK;
125 // CSOActiveX
127 CSOActiveX::CSOActiveX()
128 : mCookie(0)
129 , mCurFileUrl( L"private:factory/swriter" )
130 , mbLoad( FALSE )
131 , mParentWin( NULL )
132 , mOffWin( NULL )
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()
154 Cleanup();
158 HRESULT CSOActiveX::Cleanup()
160 if( mpDispFrame && mbViewOnly )
162 ShowSomeBars();
163 mbViewOnly = FALSE;
166 if( mpDispFrame )
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 );
177 return S_OK;
181 STDMETHODIMP CSOActiveX::InitNew ()
183 mbLoad = TRUE;
184 return S_OK;
187 STDMETHODIMP CSOActiveX::Load ( LPSTREAM pStm )
189 mbLoad = TRUE;
191 // may be later?
192 // for now just ignore
194 return S_OK;
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 ) )
204 return hr;
206 unsigned long aNum;
207 hr = pPropBag2->CountProperties( &aNum );
208 ATLASSERT( hr >= 0 );
209 if( !SUCCEEDED( hr ) )
210 return hr;
212 PROPBAG2* aPropNames = new PROPBAG2[aNum];
213 unsigned long aReaded;
215 hr = pPropBag2->GetPropertyInfo( 0,
216 aNum,
217 aPropNames,
218 &aReaded );
219 ATLASSERT( hr >= 0 );
220 if( !SUCCEEDED( hr ) )
222 delete[] aPropNames;
223 return hr;
226 CComVariant* aVal = new CComVariant[aNum];
227 HRESULT* hvs = new HRESULT[aNum];
228 hr = pPropBag2->Read( aNum,
229 aPropNames,
230 NULL,
231 aVal,
232 hvs );
233 ATLASSERT( hr >= 0 );
234 if( !SUCCEEDED( hr ) )
236 delete[] hvs;
237 delete[] aVal;
238 delete[] aPropNames;
239 return hr;
242 USES_CONVERSION;
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" ) )
255 mbViewOnly = TRUE;
257 else
259 // the default value
260 mbViewOnly = FALSE;
265 delete[] hvs;
266 delete[] aVal;
267 delete[] aPropNames;
269 if( !mpDispFactory )
270 return hr;
272 mbLoad = TRUE;
274 Invalidate();
275 UpdateWindow();
277 return hr;
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";
291 DISPID nURLID;
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,
299 L"createInstance",
300 &CComVariant( L"com.sun.star.util.URLTransformer" ),
302 pdispTransformer );
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;
312 return S_OK;
316 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
318 if( !mpDispFactory )
319 return E_FAIL;
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",
332 L"Y",
333 L"Width",
334 L"Height" };
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",
349 L"ParentIndex",
350 L"Parent",
351 L"Bounds",
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;
372 // create frame
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;
382 // initialize frame
383 CComVariant dummyResult;
384 hr = ExecuteFunc( mpDispFrame, L"initialize", &CComVariant( mpDispWin ), 1, &dummyResult );
385 if( !SUCCEEDED( hr ) ) return hr;
387 // create desktop
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;
401 // initialize window
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;
418 return S_OK;
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,
433 L"queryDispatch",
434 aArgs,
436 pdispXDispatch );
437 if( !SUCCEEDED( hr ) ) return hr;
439 SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
440 long ix = 0;
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;
463 return S_OK;
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;
475 return S_OK;
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;
486 return S_OK;
489 HRESULT CSOActiveX::LoadURLToFrame( )
491 HRESULT hr = CallDispatch1PBool( mCurFileUrl, L"ReadOnly", mbViewOnly );
492 if( !SUCCEEDED( hr ) ) return hr;
494 if( mbViewOnly )
495 HideAllBars();
497 return S_OK;
500 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
502 if( m_spInPlaceSite && mCurFileUrl )
504 HWND hwnd;
505 HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
506 if( !SUCCEEDED( hr ) ) return hr;
508 if( mParentWin != hwnd || !mOffWin )
510 if( mpDispFrame )
512 CComVariant dummyResult;
513 ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
514 mpDispFrame = CComPtr<IDispatch>();
517 mParentWin = hwnd;
518 mOffWin = CreateWindow(
519 STAROFFICE_WINDOWCLASS,
520 "OfficeContainer",
521 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
522 di.prcBounds->left,
523 di.prcBounds->top,
524 di.prcBounds->right - di.prcBounds->left,
525 di.prcBounds->bottom - di.prcBounds->top,
526 mParentWin,
527 NULL,
528 NULL,
529 NULL );
531 ::ShowWindow( mOffWin, SW_SHOW );
533 else
535 RECT aRect;
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,
543 HWND_TOP,
544 di.prcBounds->left,
545 di.prcBounds->top,
546 di.prcBounds->right - di.prcBounds->left,
547 di.prcBounds->bottom - di.prcBounds->top,
548 SWP_NOZORDER );
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;
562 if( ! mpDispFrame )
564 hr = CreateFrameOldWay( mOffWin,
565 di.prcBounds->right - di.prcBounds->left,
566 di.prcBounds->bottom - di.prcBounds->top );
567 if( !SUCCEEDED( hr ) ) return hr;
570 if( mbLoad )
572 hr = LoadURLToFrame();
573 if( !SUCCEEDED( hr ) ) return hr;
574 mbLoad = FALSE;
578 return S_OK;
582 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
584 HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
586 if( !aClientSite )
588 ATLASSERT( mWebBrowser2 );
589 if( mWebBrowser2 )
590 AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
591 return hr;
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,
606 IID_IWebBrowser,
607 (void**)&mWebBrowser2 );
608 ATLASSERT( mWebBrowser2 );
609 if( mWebBrowser2 )
610 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
614 return hr;
617 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
618 REFIID riid,
619 LCID lcid,
620 WORD wFlags,
621 DISPPARAMS* pDispParams,
622 VARIANT* pvarResult,
623 EXCEPINFO* pExcepInfo,
624 UINT* puArgErr)
626 if (riid != IID_NULL)
627 return DISP_E_UNKNOWNINTERFACE;
629 if (!pDispParams)
630 return DISP_E_PARAMNOTOPTIONAL;
632 if ( dispidMember == DISPID_ONQUIT )
633 Cleanup();
635 IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
636 &LIBID_SO_ACTIVEXLib>::Invoke(
637 dispidMember, riid, lcid, wFlags, pDispParams,
638 pvarResult, pExcepInfo, puArgErr);
640 return S_OK;
645 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */