xref: /AOO41X/main/odk/examples/OLE/activex/SOActiveX.cpp (revision 34dd1e2512dbacb6a9a7e4c7f17b9296daa8eff3)
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