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