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 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 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 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 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 142 CSOActiveX::~CSOActiveX() 143 { 144 Cleanup(); 145 146 } 147 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 171 STDMETHODIMP CSOActiveX::InitNew () 172 { 173 mbLoad = TRUE; 174 return S_OK; 175 } 176 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 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 270 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult ) 271 { 272 return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &CComVariant( sStructName ), 1, pdispResult ); 273 } 274 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 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 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 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 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 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 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 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 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