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