xref: /AOO41X/main/extensions/source/activex/main/SOActiveX.cpp (revision 520fa26520b0e796579cd98364c4c8e80094d346)
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 // SOActiveX.cpp : Implementation of CSOActiveX
23 
24 #pragma warning (disable:4505)
25     // permanently suppress "unreferenced local function has been removed" warning
26 
27 #pragma warning (push,1)
28 #pragma warning (disable:4265)
29 
30 #include "stdafx2.h"
31 #include "so_activex.h"
32 #include "SOActiveX.h"
33 #include "SOComWindowPeer.h"
34 #include "SODispatchInterceptor.h"
35 #include "SOActionsApproval.h"
36 
37 #pragma warning (pop)
38 
39 #define STAROFFICE_WINDOWCLASS "SOParentWindow"
40 
41 
42 /////////////////////////////////////////////////////////////////////////////
43 
OutputError_Impl(HWND hw,HRESULT ErrorCode)44 void OutputError_Impl( HWND hw, HRESULT ErrorCode )
45 {
46     void* sMessage;
47     FormatMessageA(
48         FORMAT_MESSAGE_ALLOCATE_BUFFER |
49         FORMAT_MESSAGE_FROM_SYSTEM,
50         NULL,
51         ErrorCode,
52         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
53         (LPTSTR) &sMessage,
54         0,
55         NULL
56     );
57     ::MessageBoxA( hw, (LPCTSTR)sMessage, NULL, MB_OK | MB_ICONINFORMATION );
58     LocalFree( sMessage );
59 }
60 
ExecuteFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComVariant * pResult)61 HRESULT ExecuteFunc( IDispatch* idispUnoObject,
62                      OLECHAR* sFuncName,
63                      CComVariant* params,
64                      unsigned int count,
65                      CComVariant* pResult )
66 {
67     if( !idispUnoObject )
68         return E_FAIL;
69 
70     DISPID id;
71     HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
72     if( !SUCCEEDED( hr ) ) return hr;
73 
74     DISPPARAMS dispparams= { params, 0, count, 0};
75 
76     // DEBUG
77     EXCEPINFO myInfo;
78     hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
79                     &dispparams, pResult, &myInfo, 0);
80 
81     // for debugging purposes
82     // USES_CONVERSION;
83     // if ( !SUCCEEDED( hr ) )
84     //  ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
85 
86     return hr;
87 }
88 
GetIDispByFunc(IDispatch * idispUnoObject,OLECHAR * sFuncName,CComVariant * params,unsigned int count,CComPtr<IDispatch> & pdispResult)89 HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
90                         OLECHAR* sFuncName,
91                         CComVariant* params,
92                         unsigned int count,
93                         CComPtr<IDispatch>& pdispResult )
94 {
95     if( !idispUnoObject )
96         return E_FAIL;
97 
98     CComVariant result;
99     HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
100     if( !SUCCEEDED( hr ) ) return hr;
101 
102     if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
103         return E_FAIL;
104 
105     pdispResult = CComPtr<IDispatch>( result.pdispVal );
106 
107     return S_OK;
108 }
109 
PutPropertiesToIDisp(IDispatch * pdispObject,OLECHAR ** sMemberNames,CComVariant * pVariant,unsigned int count)110 HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
111                               OLECHAR** sMemberNames,
112                               CComVariant* pVariant,
113                               unsigned int count )
114 {
115     for( unsigned int ind = 0; ind < count; ind++ )
116     {
117         DISPID id;
118         HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
119         if( !SUCCEEDED( hr ) ) return hr;
120 
121         hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
122         if( !SUCCEEDED( hr ) ) return hr;
123     }
124 
125     return S_OK;
126 }
127 
GetPropertiesFromIDisp(IDispatch * pdispObject,OLECHAR ** sMemberNames,CComVariant * pVariant,unsigned int count)128 HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
129                                 OLECHAR** sMemberNames,
130                                 CComVariant* pVariant,
131                                 unsigned int count )
132 {
133     for( unsigned int ind = 0; ind < count; ind++ )
134     {
135         DISPID id;
136         HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
137         if( !SUCCEEDED( hr ) ) return hr;
138 
139         hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
140         if( !SUCCEEDED( hr ) ) return hr;
141     }
142 
143     return S_OK;
144 }
145 /////////////////////////////////////////////////////////////////////////////
146 // CSOActiveX
147 
CSOActiveX()148 CSOActiveX::CSOActiveX()
149 : mCookie(0)
150 , mCurFileUrl( L"private:factory/swriter" )
151 , mbLoad( FALSE )
152 , mParentWin( NULL )
153 , mOffWin( NULL )
154 , mbViewOnly( TRUE )
155 , mpDispatchInterceptor( NULL )
156 , mnVersion( SO_NOT_DETECTED )
157 , mbReadyForActivation( FALSE )
158 , mbDrawLocked( FALSE )
159 {
160     CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
161     HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
162     if( !SUCCEEDED( hr ) )
163         OutputError_Impl( NULL, hr );
164 
165     mPWinClass.style            = CS_HREDRAW|CS_VREDRAW;
166     mPWinClass.lpfnWndProc      = ::DefWindowProc;
167     mPWinClass.cbClsExtra       = 0;
168     mPWinClass.cbWndExtra       = 0;
169     mPWinClass.hInstance        = (HINSTANCE) GetModuleHandle(NULL); //myInstance;
170     mPWinClass.hIcon            = NULL;
171     mPWinClass.hCursor          = NULL;
172     mPWinClass.hbrBackground    = (HBRUSH) COLOR_BACKGROUND;
173     mPWinClass.lpszMenuName     = NULL;
174     mPWinClass.lpszClassName    = STAROFFICE_WINDOWCLASS;
175 
176     RegisterClass(&mPWinClass);
177 }
178 
~CSOActiveX()179 CSOActiveX::~CSOActiveX()
180 {
181     Cleanup();
182 
183 }
184 
Cleanup()185 HRESULT CSOActiveX::Cleanup()
186 {
187     CComVariant dummyResult;
188 
189     if( mpDispatchInterceptor )
190     {
191         if( mpDispFrame )
192         {
193             // remove dispatch interceptor
194             CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
195                 CComVariant aVariant( pIDispDispInter );
196             ExecuteFunc( mpDispFrame,
197                          L"releaseDispatchProviderInterceptor",
198                          &aVariant,
199                          1,
200                          &dummyResult );
201         }
202 
203         mpDispatchInterceptor->ClearParent();
204         mpDispatchInterceptor->Release();
205         mpDispatchInterceptor = NULL;
206     }
207 
208     mpDispTempFile = CComPtr< IDispatch >();
209     mbReadyForActivation = FALSE;
210 
211     if( mpInstanceLocker )
212     {
213         ExecuteFunc( mpInstanceLocker, L"dispose", NULL, 0, &dummyResult );
214         mpInstanceLocker = CComPtr< IDispatch >();
215     }
216 
217     if( mpDispFrame )
218     {
219         BOOL bCloserActivated = FALSE;
220 
221         CComPtr<IDispatch> pDispDocumentCloser;
222         CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
223         HRESULT hr = GetIDispByFunc( mpDispFactory,
224                                     L"createInstance",
225                                     &aDocCloser,
226                                     1,
227                                     pDispDocumentCloser );
228         if ( SUCCEEDED( hr ) && pDispDocumentCloser )
229         {
230             SAFEARRAY FAR* pInitFrame = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
231             long nInitInd = 0;
232             CComVariant pFrameVariant( mpDispFrame );
233             SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
234             CComVariant aVarInitFrame;
235             aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
236             hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
237             if( SUCCEEDED( hr ) )
238             {
239                 // the following call will let the closing happen
240                 hr = ExecuteFunc( pDispDocumentCloser, L"dispose", NULL, 0, &dummyResult );
241                 bCloserActivated = SUCCEEDED( hr );
242             }
243         }
244 
245         if ( !bCloserActivated )
246         {
247             CComVariant aPropVar;
248             aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
249             if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
250                 ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
251         }
252 
253         mpDispFrame = CComPtr< IDispatch >();
254     }
255 
256     if( ::IsWindow( mOffWin ) )
257         ::DestroyWindow( mOffWin );
258 
259     TerminateOffice();
260 
261     return S_OK;
262 }
263 
TerminateOffice()264 HRESULT CSOActiveX::TerminateOffice()
265 {
266     // create desktop
267     CComPtr<IDispatch> pdispDesktop;
268     CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
269 
270     HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
271     if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
272 
273     // create tree of frames
274     CComPtr<IDispatch> pdispChildren;
275     hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
276     if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
277 
278     CComVariant aFrames;
279     CComVariant nFlag( 4 );
280     hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
281     if ( SUCCEEDED( hr ) )
282     {
283         if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
284           && ( !aFrames.parray || aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0 ) )
285         {
286             // there is no frames open
287             // TODO: check whether the frames are hidden if they are open?
288             CComVariant dummyResult;
289             hr = ExecuteFunc( pdispDesktop, L"terminate", NULL, 0, &dummyResult );
290         }
291     }
292 
293     return hr;
294 }
295 
InitNew()296 STDMETHODIMP CSOActiveX::InitNew ()
297 {
298     mnVersion = GetVersionConnected();
299     mbLoad = TRUE;
300     return S_OK;
301 }
302 
Load(LPSTREAM)303 STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
304 {
305     mnVersion = GetVersionConnected();
306     mbLoad = TRUE;
307 
308     // may be later?
309     // for now just ignore
310 
311     return S_OK;
312 }
313 
Load(LPPROPERTYBAG pPropBag,LPERRORLOG)314 STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
315 {
316     mnVersion = GetVersionConnected();
317 
318     IPropertyBag2* pPropBag2;
319     HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
320     //ATLASSERT( hr >= 0 );
321 
322     if( !SUCCEEDED( hr ) )
323         return hr;
324 
325     unsigned long aNum;
326     hr = pPropBag2->CountProperties( &aNum );
327     //ATLASSERT( hr >= 0 );
328     if( !SUCCEEDED( hr ) )
329         return hr;
330 
331     PROPBAG2* aPropNames = new PROPBAG2[aNum];
332     unsigned long aReaded;
333 
334     hr = pPropBag2->GetPropertyInfo( 0,
335                                      aNum,
336                                      aPropNames,
337                                      &aReaded );
338     //ATLASSERT( hr >= 0 );
339     if( !SUCCEEDED( hr ) )
340     {
341         delete[] aPropNames;
342         return hr;
343     }
344 
345     CComVariant* aVal = new CComVariant[aNum];
346     HRESULT*     hvs = new HRESULT[aNum];
347     hr = pPropBag2->Read( aNum,
348                           aPropNames,
349                           NULL,
350                           aVal,
351                           hvs );
352     //ATLASSERT( hr >= 0 );
353     if( !SUCCEEDED( hr ) )
354     {
355         delete[] hvs;
356         delete[] aVal;
357         delete[] aPropNames;
358         return hr;
359     }
360 
361     USES_CONVERSION;
362     for( unsigned long ind = 0; ind < aNum; ind++ )
363     {
364         // all information from the 'object' tag is in strings
365         if( aVal[ind].vt == VT_BSTR && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
366         {
367             mCurFileUrl = wcsdup( aVal[ind].bstrVal );
368         }
369         else if( aVal[ind].vt == VT_BSTR
370                 && !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
371         {
372             if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
373             {
374                 // the default value
375                 mbViewOnly = TRUE;
376             }
377             else
378             {
379                 mbViewOnly = FALSE;
380             }
381         }
382     }
383 
384     delete[] hvs;
385     delete[] aVal;
386     delete[] aPropNames;
387 
388     if( !mpDispFactory )
389         return hr;
390 
391     mbReadyForActivation = FALSE;
392     hr = CBindStatusCallback<CSOActiveX>::Download( this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE );
393     if ( hr == MK_S_ASYNCHRONOUS )
394         hr = S_OK;
395 
396     if ( !SUCCEEDED( hr ) )
397     {
398         // trigger initialization without stream
399         mbLoad = TRUE;
400 
401         Invalidate();
402         UpdateWindow();
403     }
404 
405     return hr;
406 }
407 
GetUnoStruct(OLECHAR * sStructName,CComPtr<IDispatch> & pdispResult)408 HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
409 {
410     CComVariant aComStruct( sStructName );
411     return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
412 }
413 
GetUrlStruct(OLECHAR * sUrl,CComPtr<IDispatch> & pdispUrl)414 HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
415 {
416     HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
417     if( !SUCCEEDED( hr ) ) return hr;
418 
419     OLECHAR* sURLMemberName = L"Complete";
420     DISPID nURLID;
421     hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
422     if( !SUCCEEDED( hr ) ) return hr;
423     CComVariant aComUrl( sUrl );
424     hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
425     if( !SUCCEEDED( hr ) ) return hr;
426 
427     CComPtr<IDispatch> pdispTransformer;
428     CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
429     hr = GetIDispByFunc( mpDispFactory,
430                          L"createInstance",
431                          &aServiceName,
432                          1,
433                          pdispTransformer );
434     if( !SUCCEEDED( hr ) ) return hr;
435 
436     CComVariant dummyResult;
437     CComVariant aParam[2];
438     aParam[1].ppdispVal = &pdispUrl;
439     aParam[1].vt = VT_DISPATCH | VT_BYREF;
440     aParam[0] = CComVariant( L"file:///" );
441 
442     hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
443     if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
444 
445     return S_OK;
446 }
447 
SetLayoutManagerProps()448 HRESULT CSOActiveX::SetLayoutManagerProps()
449 {
450     if ( !mpDispFrame )
451         return E_FAIL;
452 
453     CComVariant pVarLayoutMgr;
454     OLECHAR* sLMPropName = L"LayoutManager";
455     HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
456     if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == NULL )
457         return E_FAIL;
458 
459     CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
460 
461 
462     if( !SUCCEEDED( hr ) || !pdispLM )
463         return E_FAIL;
464 
465     OLECHAR* sATName = L"AutomaticToolbars";
466     CComVariant pATProp;
467     pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
468     hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
469 
470     return hr;
471 }
472 
CreateFrameOldWay(HWND hwnd,int width,int height)473 HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
474 {
475     if( !mpDispFactory )
476         return E_FAIL;
477 
478     // create window handle holder
479     CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
480     pPeerToSend->SetHWNDInternally( hwnd );
481     CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
482 
483     // create rectangle structure
484     CComPtr<IDispatch> pdispRectangle;
485     HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
486     if( !SUCCEEDED( hr ) ) return hr;
487 
488     OLECHAR* sRectMemberNames[4] = { L"X",
489                                      L"Y",
490                                      L"Width",
491                                      L"Height" };
492     CComVariant pRectVariant[4];
493     pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
494 
495     hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
496     if( !SUCCEEDED( hr ) ) return hr;
497 
498     // create WindowDescriptor structure
499     CComPtr<IDispatch> pdispWinDescr;
500     hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
501     if( !SUCCEEDED( hr ) ) return hr;
502 
503     // fill in descriptor with info
504     OLECHAR* sDescriptorMemberNames[6] = { L"Type",
505                                  L"WindowServiceName",
506                                  L"ParentIndex",
507                                  L"Parent",
508                                  L"Bounds",
509                                  L"WindowAttributes" };
510     CComVariant pDescriptorVar[6];
511     pDescriptorVar[0] = CComVariant( 0 );
512     pDescriptorVar[1] = CComVariant( L"workwindow" );
513     pDescriptorVar[2] = CComVariant( 1 );
514     pDescriptorVar[3] = CComVariant( pIDispToSend );
515     pDescriptorVar[4] = CComVariant( pdispRectangle );
516     pDescriptorVar[5] = CComVariant( 33 );
517     hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
518     if( !SUCCEEDED( hr ) ) return hr;
519 
520     // create XToolkit instance
521     CComPtr<IDispatch> pdispToolkit;
522     CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
523     hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
524     if( !SUCCEEDED( hr ) ) return hr;
525 
526     // create window with toolkit
527     CComVariant aWinDescr( pdispWinDescr );
528     hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
529     if( !SUCCEEDED( hr ) ) return hr;
530 
531     // create frame
532     aServiceName = CComVariant( L"com.sun.star.frame.Task" );
533     hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
534     if( !SUCCEEDED( hr ) || !mpDispFrame )
535     {
536         // the interface com.sun.star.frame.Task is removed in 6.1
537         // but the interface com.sun.star.frame.Frame has some bugs in 6.0
538         aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
539         hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
540         if( !SUCCEEDED( hr ) ) return hr;
541     }
542 
543     // initialize frame
544     CComVariant dummyResult;
545     CComVariant aDispWin( mpDispWin );
546     hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
547     if( !SUCCEEDED( hr ) ) return hr;
548 
549     // set some properties to the layout manager, ignore errors for now
550     SetLayoutManagerProps();
551 
552     // create desktop
553     CComPtr<IDispatch> pdispDesktop;
554     aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
555     hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
556     if( !SUCCEEDED( hr ) ) return hr;
557 
558     // create tree of frames
559     CComPtr<IDispatch> pdispChildren;
560     hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
561     if( !SUCCEEDED( hr ) ) return hr;
562 
563     // insert new frame into desctop hierarchy
564     CComVariant aDispFrame( mpDispFrame );
565     hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
566     if( !SUCCEEDED( hr ) ) return hr;
567 
568     // initialize window
569     CComVariant aTransparent( (long)0xFFFFFFFF );
570     hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
571     if( !SUCCEEDED( hr ) ) return hr;
572 
573     CComVariant aTrue( TRUE );
574     hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
575     if( !SUCCEEDED( hr ) ) return hr;
576 
577     CComVariant aPosArgs[5];
578     aPosArgs[4] = CComVariant( 0 );
579     aPosArgs[3] = CComVariant( 0 );
580     aPosArgs[2] = CComVariant( width );
581     aPosArgs[1] = CComVariant( height );
582     aPosArgs[0] = CComVariant( 12 );
583     hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
584     if( !SUCCEEDED( hr ) ) return hr;
585 
586     // create frame locker if there is such service
587     aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
588     hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
589     if( SUCCEEDED( hr ) && mpInstanceLocker )
590     {
591         SAFEARRAY FAR* pInitVals = SafeArrayCreateVector( VT_VARIANT, 0, 3 );
592 
593         // the first sequence element
594         long nInitInd = 0;
595         CComVariant pFrameVariant( mpDispFrame );
596         SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
597 
598         // the second sequence element
599         nInitInd = 1;
600         CComVariant pStrArr( 1L );
601         SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
602 
603         // the third sequence element
604         nInitInd = 2;
605         CComPtr<IDispatch> pdispValueObj;
606         hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", NULL, 0, pdispValueObj );
607         if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
608 
609         CComVariant aValueArgs[2];
610         aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
611         CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
612         aValueArgs[0] = CComVariant ( pApproval );
613 
614         hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
615         if( !SUCCEEDED( hr ) ) return hr;
616 
617         CComVariant aValueObj( pdispValueObj );
618         SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
619 
620         // execute initialize()
621         CComVariant aVarInitVals;
622         aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
623         hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
624         if( !SUCCEEDED( hr ) ) return hr;
625     }
626 
627     return S_OK;
628 }
629 
CallLoadComponentFromURL1PBool(OLECHAR * sUrl,OLECHAR * sArgName,BOOL sArgVal)630 HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
631 {
632     SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
633     long ix = 0;
634     CComPtr<IDispatch> pdispPropVal;
635     HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
636     if( !SUCCEEDED( hr ) ) return hr;
637 
638     OLECHAR*    sPropMemberNames[2] = { L"Name", L"Value" };
639     CComVariant pPropVar[2];
640     pPropVar[0] = CComVariant( sArgName );
641     pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
642     hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
643     if( !SUCCEEDED( hr ) ) return hr;
644 
645     SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
646 
647     CComVariant aDispArgs[4];
648     aDispArgs[3] = CComVariant( sUrl );
649     aDispArgs[2] = CComVariant( L"_self" );
650     aDispArgs[1] = CComVariant( 0 );
651     // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
652     aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
653 
654     CComVariant dummyResult;
655     hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
656     if( !SUCCEEDED( hr ) ) return hr;
657 
658     return S_OK;
659 }
660 
CallDispatchMethod(OLECHAR * sUrl,CComVariant * aArgNames,CComVariant * aArgVals,unsigned int count)661 HRESULT CSOActiveX::CallDispatchMethod( OLECHAR* sUrl,
662                                         CComVariant* aArgNames,
663                                         CComVariant* aArgVals,
664                                         unsigned int count )
665 {
666     CComPtr<IDispatch> pdispURL;
667     HRESULT hr = GetUrlStruct( sUrl, pdispURL );
668     if( !SUCCEEDED( hr ) ) return hr;
669 
670     CComPtr<IDispatch> pdispXDispatch;
671     CComVariant aArgs[3];
672     aArgs[2] = CComVariant( pdispURL );
673     aArgs[1] = CComVariant( L"" );
674     aArgs[0] = CComVariant( (int)0 );
675     hr = GetIDispByFunc( mpDispFrame,
676                          L"queryDispatch",
677                          aArgs,
678                          3,
679                          pdispXDispatch );
680     if( !SUCCEEDED( hr ) ) return hr;
681 
682     SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, count );
683     for( long ix = 0; ix < (long)count; ix ++ )
684     {
685         CComPtr<IDispatch> pdispPropVal;
686         hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
687         if( !SUCCEEDED( hr ) ) return hr;
688 
689         OLECHAR*    sPropMemberNames[2] = { L"Name", L"Value" };
690         CComVariant pPropVar[2];
691         pPropVar[0] = aArgNames[ix];
692         pPropVar[1] = aArgVals[ix];
693         hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
694         if( !SUCCEEDED( hr ) ) return hr;
695 
696         SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
697     }
698 
699     CComVariant aDispArgs[2];
700     aDispArgs[1] = CComVariant( pdispURL );
701     // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
702     aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
703 
704     CComVariant dummyResult;
705     hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
706     if( !SUCCEEDED( hr ) ) return hr;
707 
708     return S_OK;
709 }
710 
CallbackCreateXInputStream(CBindStatusCallback<CSOActiveX> *,BYTE * pBytes,DWORD dwSize)711 void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
712 {
713     if ( mbReadyForActivation )
714         return;
715 
716     BOOL bSuccess = FALSE;
717     BOOL bFinishDownload = FALSE;
718     if ( !pBytes )
719     {
720         // means the download is finished, dwSize contains hresult
721         bFinishDownload = TRUE;
722         if ( SUCCEEDED( dwSize ) )
723             bSuccess = TRUE;
724     }
725     else
726     {
727         HRESULT hr = S_OK;
728 
729         if ( !mpDispTempFile )
730         {
731             CComVariant aServiceName( L"com.sun.star.io.TempFile" );
732             hr = GetIDispByFunc( mpDispFactory,
733                                 L"createInstance",
734                                 &aServiceName,
735                                 1,
736                                 mpDispTempFile );
737         }
738 
739         if( SUCCEEDED( hr ) && mpDispTempFile )
740         {
741             SAFEARRAY FAR* pDataArray = SafeArrayCreateVector( VT_I1, 0, dwSize );
742 
743             if ( pDataArray )
744             {
745                 hr = SafeArrayLock( pDataArray );
746                 if ( SUCCEEDED( hr ) )
747                 {
748                     for( DWORD ix = 0; ix < dwSize; ix++ )
749                         ((BYTE*)(pDataArray->pvData))[ix] = pBytes[ix];
750                     hr = SafeArrayUnlock( pDataArray );
751                     if ( SUCCEEDED( hr ) )
752                     {
753                         CComVariant aArgs[1];
754                         aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
755                         CComVariant dummyResult;
756                         hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
757                         if( SUCCEEDED( hr ) )
758                             bSuccess = TRUE;
759                     }
760                 }
761             }
762         }
763     }
764 
765     if ( !bSuccess )
766     {
767         // the download failed, let StarOffice download
768         bFinishDownload = TRUE;
769         mpDispTempFile = CComPtr< IDispatch >();
770     }
771 
772     if ( bFinishDownload )
773     {
774         // trigger the loading now
775         mbLoad = TRUE;
776         mbReadyForActivation = TRUE;
777 
778         Invalidate();
779         UpdateWindow();
780     }
781 }
782 
LoadURLToFrame()783 HRESULT CSOActiveX::LoadURLToFrame( )
784 {
785     CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
786     CComVariant aArgVals[4];
787     unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
788 
789     aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
790     aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
791     aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
792 
793     if ( mpDispTempFile )
794     {
795         aArgVals[3] = CComVariant( mpDispTempFile );
796         nCount = 4;
797     }
798 
799     HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
800     if( !SUCCEEDED( hr ) ) return hr;
801 
802     CComVariant aBarName( L"MenuBarVisible" );
803     CComVariant aBarVis;
804     aBarVis.vt = VT_BOOL; aBarVis.boolVal = VARIANT_FALSE;
805     hr = CallDispatchMethod( L"slot:6661", &aBarName, &aBarVis, 1 );
806     // does not work for some documents, but it is no error
807     // if( !SUCCEEDED( hr ) ) return hr;
808 
809     // try to get the model and set the presetation specific property, the setting will fail for other document formats
810     CComPtr<IDispatch> pdispController;
811     hr = GetIDispByFunc( mpDispFrame, L"getController", NULL, 0, pdispController );
812     if ( SUCCEEDED( hr ) && pdispController )
813     {
814         CComPtr<IDispatch> pdispModel;
815         hr = GetIDispByFunc( pdispController, L"getModel", NULL, 0, pdispModel );
816         if ( SUCCEEDED( hr ) && pdispModel )
817         {
818             CComPtr<IDispatch> pdispPres;
819             hr = GetIDispByFunc( pdispModel, L"getPresentation", NULL, 0, pdispPres );
820             if ( SUCCEEDED( hr ) && pdispPres )
821             {
822                 // this is a presentation
823                 // let the slide show be shown in the document window
824                 OLECHAR* pPropName = L"IsFullScreen";
825                 CComVariant pPresProp;
826                 pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
827                 hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
828 
829                 // start the slide show
830                 if ( SUCCEEDED( hr ) )
831                 {
832                     CComVariant dummyResult;
833                     ExecuteFunc( pdispPres, L"Start", NULL, 0, &dummyResult );
834                 }
835             }
836         }
837     }
838 
839     // create dispatch interceptor
840     mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
841     mpDispatchInterceptor->AddRef();
842     mpDispatchInterceptor->SetParent( this );
843     CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
844 
845     // register dispatch interceptor in the frame
846         CComVariant aDispVariant( pIDispDispInter );
847     CComVariant dummyResult;
848     hr = ExecuteFunc( mpDispFrame,
849                       L"registerDispatchProviderInterceptor",
850                                           &aDispVariant,
851                       1,
852                       &dummyResult );
853 
854     if( !SUCCEEDED( hr ) ) return hr;
855 
856     return S_OK;
857 }
858 
GetVersionConnected()859 SOVersion CSOActiveX::GetVersionConnected()
860 {
861     SOVersion bResult = SO_NOT_DETECTED;
862     if( mpDispFactory )
863     {
864         // create ConfigurationProvider instance
865         CComPtr<IDispatch> pdispConfProv;
866         CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
867         HRESULT hr = GetIDispByFunc( mpDispFactory,
868                              L"createInstance",
869                              &aServiceName,
870                              1,
871                              pdispConfProv );
872 
873         if( SUCCEEDED( hr ) && pdispConfProv )
874         {
875             CComPtr<IDispatch> pdispConfAccess;
876 
877             SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
878 
879             if( pInitParams )
880             {
881                 long ix = 0;
882                 CComVariant aConfPath( L"org.openoffice.Setup" );
883                 SafeArrayPutElement( pInitParams, &ix, &aConfPath );
884 
885                 CComVariant aArgs[2];
886                 aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
887                 aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
888 
889                 hr = GetIDispByFunc( pdispConfProv,
890                                     L"createInstanceWithArguments",
891                                     aArgs,
892                                     2,
893                                     pdispConfAccess );
894 
895                 if( SUCCEEDED( hr ) && pdispConfAccess )
896                 {
897                     CComVariant aOfficeName;
898 
899                     CComVariant aProductName( L"Product/ooName" );
900                     hr = ExecuteFunc( pdispConfAccess,
901                                         L"getByHierarchicalName",
902                                         &aProductName,
903                                         1,
904                                         &aOfficeName );
905 
906                     if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
907                     {
908                         CComVariant aOfficeVersion;
909 
910                         CComVariant aProductVersion( L"Product/ooSetupVersion" );
911                         hr = ExecuteFunc( pdispConfAccess,
912                                             L"getByHierarchicalName",
913                                             &aProductVersion,
914                                             1,
915                                             &aOfficeVersion );
916 
917                         if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
918                         {
919                             USES_CONVERSION;
920                             if( !strcmp( OLE2T( aOfficeName.bstrVal ), "StarOffice" ) )
921                             {
922                                 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.1", 3 ) )
923                                     bResult = SO_61;
924                                 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.0", 3 ) )
925                                     bResult = SO_60;
926                                 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "5.2", 3 ) )
927                                     bResult = SO_52;
928                                 else
929                                     bResult = SO_UNKNOWN;
930                             }
931                             else // OpenOffice
932                             {
933                                 if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.1", 3 ) )
934                                     bResult = OO_11;
935                                 else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.0", 3 ) )
936                                     bResult = OO_10;
937                                 else
938                                     bResult = OO_UNKNOWN;
939                             }
940                         }
941                     }
942                 }
943             }
944         }
945     }
946 
947     return bResult;
948 }
949 
950 class LockingGuard
951 {
952     BOOL& mbLocked;
953 public:
LockingGuard(BOOL & bLocked)954     LockingGuard( BOOL& bLocked )
955     : mbLocked( bLocked )
956     {
957         mbLocked = TRUE;
958     }
959 
~LockingGuard()960     ~LockingGuard()
961     {
962         mbLocked = FALSE;
963     }
964 };
965 
OnDrawAdvanced(ATL_DRAWINFO & di)966 HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
967 {
968     // This method is called only in main thread, no need to lock it
969 
970     // Get read of reentrance problems
971     if ( mbDrawLocked )
972         return S_OK;
973     LockingGuard aGuard( mbDrawLocked );
974 
975     if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
976     {
977         HWND hwnd;
978         HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
979         if( !SUCCEEDED( hr ) ) return hr;
980 
981         if( mParentWin != hwnd || !mOffWin )
982         {
983             if( mpDispFrame )
984             {
985                 CComVariant dummyResult;
986                 CComVariant aPropVar;
987                 aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
988                 HRESULT hr = ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
989                 (void)hr;
990                 mpDispFrame = CComPtr<IDispatch>();
991             }
992 
993             mParentWin = hwnd;
994             mOffWin = CreateWindow(
995                                 STAROFFICE_WINDOWCLASS,
996                                 "OfficeContainer",
997                                 WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
998                                 di.prcBounds->left,
999                                 di.prcBounds->top,
1000                                 di.prcBounds->right - di.prcBounds->left,
1001                                 di.prcBounds->bottom - di.prcBounds->top,
1002                                 mParentWin,
1003                                 NULL,
1004                                 NULL,
1005                                 NULL );
1006 
1007             ::ShowWindow( mOffWin, SW_SHOW );
1008         }
1009         else
1010         {
1011             RECT aRect;
1012             ::GetWindowRect( mOffWin, &aRect );
1013 
1014             if( aRect.left !=  di.prcBounds->left || aRect.top != di.prcBounds->top
1015              || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
1016             {
1017                 // on this state the office window should exist already
1018                 ::SetWindowPos( mOffWin,
1019                               HWND_TOP,
1020                               di.prcBounds->left,
1021                               di.prcBounds->top,
1022                               di.prcBounds->right - di.prcBounds->left,
1023                               di.prcBounds->bottom - di.prcBounds->top,
1024                               SWP_NOZORDER );
1025 
1026                 CComVariant aPosArgs[5];
1027                 aPosArgs[4] = CComVariant( 0 );
1028                 aPosArgs[3] = CComVariant( 0 );
1029                 aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
1030                 aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
1031                 aPosArgs[0] = CComVariant( 12 );
1032                 CComVariant dummyResult;
1033                 hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
1034                 if( !SUCCEEDED( hr ) ) return hr;
1035             }
1036         }
1037 
1038         if( !mnVersion )
1039         {
1040             OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
1041             return E_FAIL;
1042         }
1043 
1044         if( ! mpDispFrame )
1045         {
1046             hr = CreateFrameOldWay( mOffWin,
1047                             di.prcBounds->right - di.prcBounds->left,
1048                             di.prcBounds->bottom - di.prcBounds->top );
1049 
1050             if( !SUCCEEDED( hr ) )
1051             {
1052                 // if the frame can not be opened do not try any more
1053                 mbReadyForActivation = FALSE;
1054                 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1055                 return hr;
1056             }
1057         }
1058 
1059         if( mbLoad )
1060         {
1061             hr = LoadURLToFrame();
1062             mbLoad = FALSE;
1063 
1064             if( !SUCCEEDED( hr ) )
1065             {
1066                 // if the document can not be opened do not try any more
1067                 mbReadyForActivation = FALSE;
1068 
1069                 OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
1070 
1071                 return hr;
1072             }
1073         }
1074     }
1075     else
1076     {
1077         // activate the fallback
1078         CComControl<CSOActiveX>::OnDrawAdvanced( di );
1079     }
1080 
1081     return S_OK;
1082 }
1083 
OnDraw(ATL_DRAWINFO & di)1084 HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
1085 {
1086     // fallback that is activated by the parent class
1087     if ( di.hdcDraw )
1088         FillRect( di.hdcDraw, (RECT*)di.prcBounds, (HBRUSH)COLOR_BACKGROUND );
1089 
1090     return S_OK;
1091 }
1092 
SetClientSite(IOleClientSite * aClientSite)1093 STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
1094 {
1095     HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
1096 
1097     if( !aClientSite )
1098     {
1099         //ATLASSERT( mWebBrowser2 );
1100         if( mWebBrowser2 )
1101             AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
1102         return hr;
1103     }
1104 
1105     CComPtr<IOleContainer> aContainer;
1106     m_spClientSite->GetContainer( &aContainer );
1107 //  ATLASSERT( aContainer );
1108 
1109     if( SUCCEEDED( hr )  && aContainer )
1110     {
1111         CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
1112         //ATLASSERT( aServiceProvider );
1113 
1114         if( aServiceProvider )
1115         {
1116             aServiceProvider->QueryService( SID_SInternetExplorer,
1117                                             IID_IWebBrowser,
1118                                             (void**)&mWebBrowser2 );
1119 //          ATLASSERT( mWebBrowser2 );
1120             if( mWebBrowser2 )
1121                 AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
1122         }
1123     }
1124 
1125     return hr;
1126 }
1127 
Invoke(DISPID dispidMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pvarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1128 STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
1129                                 REFIID riid,
1130                                 LCID lcid,
1131                                 WORD wFlags,
1132                                 DISPPARAMS* pDispParams,
1133                                 VARIANT* pvarResult,
1134                                 EXCEPINFO* pExcepInfo,
1135                                 UINT* puArgErr)
1136 {
1137     if (riid != IID_NULL)
1138         return DISP_E_UNKNOWNINTERFACE;
1139 
1140     if (!pDispParams)
1141         return DISP_E_PARAMNOTOPTIONAL;
1142 
1143     if ( dispidMember == DISPID_ONQUIT )
1144         Cleanup();
1145 
1146     IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
1147                   &LIBID_SO_ACTIVEXLib>::Invoke(
1148              dispidMember, riid, lcid, wFlags, pDispParams,
1149              pvarResult, pExcepInfo, puArgErr);
1150 
1151     return S_OK;
1152 }
1153 
GetURL(const OLECHAR * url,const OLECHAR * target)1154 HRESULT CSOActiveX::GetURL( const OLECHAR* url,
1155                               const OLECHAR* target )
1156 {
1157     CComVariant aEmpty1, aEmpty2, aEmpty3;
1158     CComVariant aUrl( url );
1159     CComVariant aTarget;
1160     if ( target )
1161         aTarget = CComVariant( target );
1162 
1163     return mWebBrowser2->Navigate2( &aUrl,
1164                                   &aEmpty1,
1165                                   &aTarget,
1166                                   &aEmpty2,
1167                                   &aEmpty3 );
1168 }
1169 
1170 
1171 // ---------------------------------------------------------------------------
1172 
1173