summaryrefslogtreecommitdiff
path: root/extensions/source/activex/main
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/activex/main')
-rw-r--r--extensions/source/activex/main/README.txt33
-rw-r--r--extensions/source/activex/main/SOActionsApproval.cpp32
-rw-r--r--extensions/source/activex/main/SOActionsApproval.h83
-rw-r--r--extensions/source/activex/main/SOActionsApproval.rgs24
-rw-r--r--extensions/source/activex/main/SOActiveX.cpp1153
-rw-r--r--extensions/source/activex/main/SOActiveX.h178
-rw-r--r--extensions/source/activex/main/SOActiveX.rgs33
-rw-r--r--extensions/source/activex/main/SOComWindowPeer.cpp31
-rw-r--r--extensions/source/activex/main/SOComWindowPeer.h136
-rw-r--r--extensions/source/activex/main/SOComWindowPeer.rgs23
-rw-r--r--extensions/source/activex/main/SODispatchInterceptor.cpp225
-rw-r--r--extensions/source/activex/main/SODispatchInterceptor.h158
-rw-r--r--extensions/source/activex/main/SODispatchInterceptor.rgs23
-rw-r--r--extensions/source/activex/main/StdAfx2.cpp21
-rw-r--r--extensions/source/activex/main/StdAfx2.h45
-rw-r--r--extensions/source/activex/main/com_uno_helper.h26
-rw-r--r--extensions/source/activex/main/example.html26
-rw-r--r--extensions/source/activex/main/makefile.mk155
-rw-r--r--extensions/source/activex/main/resource.h28
-rw-r--r--extensions/source/activex/main/so_activex.cpp692
-rw-r--r--extensions/source/activex/main/so_activex.def13
-rw-r--r--extensions/source/activex/main/so_activex.rc113
22 files changed, 3251 insertions, 0 deletions
diff --git a/extensions/source/activex/main/README.txt b/extensions/source/activex/main/README.txt
new file mode 100644
index 000000000000..9d647987aaa7
--- /dev/null
+++ b/extensions/source/activex/main/README.txt
@@ -0,0 +1,33 @@
+ Description.
+
+The StarOffice ActiveX control shows an example of access to UNO through COM technology.
+It requires a properly installed StarOffice version 6.0/6.1 or OpenOffice 1.0.
+This is a Lite ActiveX control so it can be used only in containers that
+allows to use such controls.
+
+Pressing to any link to staroffice document should activate the control.
+So the document will be opened in ReadOnly mode.
+
+Also it can be activated with an <OBJECT> tag from a html-page.
+Without any parameters for an object tag a new writer document will be
+opened for editing. Possible parameters are
+ src - full URL to the file that should be edited/viewed;
+ it can contain "private:factory/..." URLs to open new documents
+ for edit, for example "private:factory/swriter"
+ readonly - the default value is "true", in case it is set to any other
+ value the document is opened for editing
+
+As any ActiveX control this one should be registered.
+To let MSIE register it itself the "CODEBASE" parameter
+for the "OBJECT" tag should be specified
+with an URL to the library "so_activex.dll".
+The example of registration with "OBJECT" tag is in example.html.
+
+Also it can be done using regsvr32 application.
+To do it please write
+<Path to Windows installation>\System32\regsvr32 so_activex.dll
+
+To unregister the control please use /u option:
+<Path to Windows installation>\system32\regsvr32 so_activex.dll /u
+
+
diff --git a/extensions/source/activex/main/SOActionsApproval.cpp b/extensions/source/activex/main/SOActionsApproval.cpp
new file mode 100644
index 000000000000..e0ce5c5da58e
--- /dev/null
+++ b/extensions/source/activex/main/SOActionsApproval.cpp
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOActionsApproval.cpp : Implementation of CHelpApp and DLL registration.
+
+#include "stdafx2.h"
+
+#include "so_activex.h"
+#include "SOActionsApproval.h"
+#include <sal/macros.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+STDMETHODIMP SOActionsApproval::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] =
+ {
+ &IID_ISOActionsApproval,
+ };
+
+ for (int i=0;i<SAL_N_ELEMENTS(arr);i++)
+ {
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+ if (InlineIsEqualGUID(*arr[i],riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i],riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOActionsApproval.h b/extensions/source/activex/main/SOActionsApproval.h
new file mode 100644
index 000000000000..a5570312864d
--- /dev/null
+++ b/extensions/source/activex/main/SOActionsApproval.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOActionsApproval.h: Definition of the SOActionsApproval class
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined __SODOCUMENTEVENTLISTENER_H_
+#define __SODOCUMENTEVENTLISTENER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h" // main symbols
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+
+#include <atlctl.h>
+
+#include "so_activex.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// SOActionsApproval
+
+class SOActionsApproval :
+ public IDispatchImpl<ISOActionsApproval, &IID_ISOActionsApproval, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SOActionsApproval,&CLSID_SOActionsApproval>
+{
+public:
+ SOActionsApproval() {}
+ virtual ~SOActionsApproval() {}
+
+BEGIN_COM_MAP(SOActionsApproval)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISOActionsApproval)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+END_COM_MAP()
+DECLARE_NOT_AGGREGATABLE(SOActionsApproval)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SODOCUMENTEVENTLISTENER)
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
+
+// ISOActionsApproval
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE approveAction(
+ /* [in] */ long nActionID,
+ /* [retval][out] */ boolean *pbApproval)
+ {
+ // only PreventClose is approved
+ USES_CONVERSION;
+ *pbApproval = ( nActionID == 1 );
+
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal)
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 1 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ long ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.embed.XActionsApproval" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+};
+
+#endif // __SODOCUMENTEVENTLISTENER_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOActionsApproval.rgs b/extensions/source/activex/main/SOActionsApproval.rgs
new file mode 100644
index 000000000000..543320813948
--- /dev/null
+++ b/extensions/source/activex/main/SOActionsApproval.rgs
@@ -0,0 +1,24 @@
+HKCR
+{
+9F3697AC-7A18-4335-AF0A-65FAC2C35CC1
+ so_activex.SOActionsApproval.1 = s 'SOActionsApproval Class'
+ {
+ CLSID = s '{9F3697AC-7A18-4335-AF0A-65FAC2C35CC1}'
+ }
+ so_activex.SOActionsApproval = s 'SOActionsApproval Class'
+ {
+ CLSID = s '{9F3697AC-7A18-4335-AF0A-65FAC2C35CC1}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {9F3697AC-7A18-4335-AF0A-65FAC2C35CC1} = s 'SOActionsApproval Class'
+ {
+ ProgID = s 'so_activex.SOActionsApproval.1'
+ VersionIndependentProgID = s 'so_activex.SOActionsApproval'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/main/SOActiveX.cpp b/extensions/source/activex/main/SOActiveX.cpp
new file mode 100644
index 000000000000..f95e42772185
--- /dev/null
+++ b/extensions/source/activex/main/SOActiveX.cpp
@@ -0,0 +1,1153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOActiveX.cpp : Implementation of CSOActiveX
+
+#pragma warning (disable:4505)
+ // permanently suppress "unreferenced local function has been removed" warning
+
+#pragma warning (push,1)
+#pragma warning (disable:4265)
+
+#include "stdafx2.h"
+#include "so_activex.h"
+#include "SOActiveX.h"
+#include "SOComWindowPeer.h"
+#include "SODispatchInterceptor.h"
+#include "SOActionsApproval.h"
+
+#pragma warning (pop)
+
+#define STAROFFICE_WINDOWCLASS "SOParentWindow"
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+void OutputError_Impl( HWND hw, HRESULT ErrorCode )
+{
+ void* sMessage;
+ FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ ErrorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &sMessage,
+ 0,
+ NULL
+ );
+ ::MessageBoxA( hw, (LPCTSTR)sMessage, NULL, MB_OK | MB_ICONINFORMATION );
+ LocalFree( sMessage );
+}
+
+HRESULT ExecuteFunc( IDispatch* idispUnoObject,
+ OLECHAR* sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComVariant* pResult )
+{
+ if( !idispUnoObject )
+ return E_FAIL;
+
+ DISPID id;
+ HRESULT hr = idispUnoObject->GetIDsOfNames( IID_NULL, &sFuncName, 1, LOCALE_USER_DEFAULT, &id);
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ DISPPARAMS dispparams= { params, 0, count, 0};
+
+ // DEBUG
+ EXCEPINFO myInfo;
+ hr = idispUnoObject->Invoke( id, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_METHOD,
+ &dispparams, pResult, &myInfo, 0);
+
+ // for debugging purposes
+ // USES_CONVERSION;
+ // if ( !SUCCEEDED( hr ) )
+ // ::MessageBox( NULL, OLE2A( myInfo.bstrDescription ), OLE2A( myInfo.bstrSource ), MB_OK | MB_ICONINFORMATION );
+
+ return hr;
+}
+
+HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
+ OLECHAR* sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComPtr<IDispatch>& pdispResult )
+{
+ if( !idispUnoObject )
+ return E_FAIL;
+
+ CComVariant result;
+ HRESULT hr = ExecuteFunc( idispUnoObject, sFuncName, params, count, &result );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( result.vt != VT_DISPATCH || result.pdispVal == NULL )
+ return E_FAIL;
+
+ pdispResult = CComPtr<IDispatch>( result.pdispVal );
+
+ return S_OK;
+}
+
+HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
+ OLECHAR** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count )
+{
+ for( unsigned int ind = 0; ind < count; ind++ )
+ {
+ DISPID id;
+ HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::PutProperty( pdispObject, id, &pVariant[ind] );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
+ OLECHAR** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count )
+{
+ for( unsigned int ind = 0; ind < count; ind++ )
+ {
+ DISPID id;
+ HRESULT hr = pdispObject->GetIDsOfNames( IID_NULL, &sMemberNames[ind], 1, LOCALE_USER_DEFAULT, &id );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::GetProperty( pdispObject, id, &pVariant[ind] );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+/////////////////////////////////////////////////////////////////////////////
+// CSOActiveX
+
+CSOActiveX::CSOActiveX()
+: mCookie(0)
+, mCurFileUrl( L"private:factory/swriter" )
+, mbLoad( FALSE )
+, mParentWin( NULL )
+, mOffWin( NULL )
+, mbViewOnly( TRUE )
+, mpDispatchInterceptor( NULL )
+, mnVersion( SO_NOT_DETECTED )
+, mbReadyForActivation( FALSE )
+, mbDrawLocked( FALSE )
+{
+ CLSID clsFactory = {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}};
+ HRESULT hr = CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&mpDispFactory);
+ if( !SUCCEEDED( hr ) )
+ OutputError_Impl( NULL, hr );
+
+ mPWinClass.style = CS_HREDRAW|CS_VREDRAW;
+ mPWinClass.lpfnWndProc = ::DefWindowProc;
+ mPWinClass.cbClsExtra = 0;
+ mPWinClass.cbWndExtra = 0;
+ mPWinClass.hInstance = (HINSTANCE) GetModuleHandle(NULL); //myInstance;
+ mPWinClass.hIcon = NULL;
+ mPWinClass.hCursor = NULL;
+ mPWinClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
+ mPWinClass.lpszMenuName = NULL;
+ mPWinClass.lpszClassName = STAROFFICE_WINDOWCLASS;
+
+ RegisterClass(&mPWinClass);
+}
+
+CSOActiveX::~CSOActiveX()
+{
+ Cleanup();
+
+}
+
+HRESULT CSOActiveX::Cleanup()
+{
+ CComVariant dummyResult;
+
+ if( mpDispatchInterceptor )
+ {
+ if( mpDispFrame )
+ {
+ // remove dispatch interceptor
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
+ CComVariant aVariant( pIDispDispInter );
+ ExecuteFunc( mpDispFrame,
+ L"releaseDispatchProviderInterceptor",
+ &aVariant,
+ 1,
+ &dummyResult );
+ }
+
+ mpDispatchInterceptor->ClearParent();
+ mpDispatchInterceptor->Release();
+ mpDispatchInterceptor = NULL;
+ }
+
+ mpDispTempFile = CComPtr< IDispatch >();
+ mbReadyForActivation = FALSE;
+
+ if( mpInstanceLocker )
+ {
+ ExecuteFunc( mpInstanceLocker, L"dispose", NULL, 0, &dummyResult );
+ mpInstanceLocker = CComPtr< IDispatch >();
+ }
+
+ if( mpDispFrame )
+ {
+ BOOL bCloserActivated = FALSE;
+
+ CComPtr<IDispatch> pDispDocumentCloser;
+ CComVariant aDocCloser( L"com.sun.star.embed.DocumentCloser" );
+ HRESULT hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aDocCloser,
+ 1,
+ pDispDocumentCloser );
+ if ( SUCCEEDED( hr ) && pDispDocumentCloser )
+ {
+ SAFEARRAY FAR* pInitFrame = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
+ long nInitInd = 0;
+ CComVariant pFrameVariant( mpDispFrame );
+ SafeArrayPutElement( pInitFrame, &nInitInd, &pFrameVariant );
+ CComVariant aVarInitFrame;
+ aVarInitFrame.vt = VT_ARRAY | VT_VARIANT; aVarInitFrame.parray = pInitFrame;
+ hr = ExecuteFunc( pDispDocumentCloser, L"initialize", &aVarInitFrame, 1, &dummyResult );
+ if( SUCCEEDED( hr ) )
+ {
+ // the following call will let the closing happen
+ hr = ExecuteFunc( pDispDocumentCloser, L"dispose", NULL, 0, &dummyResult );
+ bCloserActivated = SUCCEEDED( hr );
+ }
+ }
+
+ if ( !bCloserActivated )
+ {
+ CComVariant aPropVar;
+ aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_TRUE;
+ if ( !SUCCEEDED( ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult ) ) )
+ ExecuteFunc( mpDispFrame, L"dispose", NULL, 0, &dummyResult );
+ }
+
+ mpDispFrame = CComPtr< IDispatch >();
+ }
+
+ if( ::IsWindow( mOffWin ) )
+ ::DestroyWindow( mOffWin );
+
+ TerminateOffice();
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::TerminateOffice()
+{
+ // create desktop
+ CComPtr<IDispatch> pdispDesktop;
+ CComVariant aDesktopServiceName( L"com.sun.star.frame.Desktop" );
+
+ HRESULT hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aDesktopServiceName, 1, pdispDesktop );
+ if( !pdispDesktop || !SUCCEEDED( hr ) ) return hr;
+
+ // create tree of frames
+ CComPtr<IDispatch> pdispChildren;
+ hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
+ if( !pdispChildren || !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aFrames;
+ CComVariant nFlag( 4 );
+ hr = ExecuteFunc( pdispChildren, L"queryFrames", &nFlag, 1, &aFrames );
+ if ( SUCCEEDED( hr ) )
+ {
+ if ( ( aFrames.vt == ( VT_ARRAY | VT_DISPATCH ) || aFrames.vt == ( VT_ARRAY | VT_VARIANT ) )
+ && ( !aFrames.parray || aFrames.parray->cDims == 1 && aFrames.parray->rgsabound[0].cElements == 0 ) )
+ {
+ // there is no frames open
+ // TODO: check whether the frames are hidden if they are open?
+ CComVariant dummyResult;
+ hr = ExecuteFunc( pdispDesktop, L"terminate", NULL, 0, &dummyResult );
+ }
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CSOActiveX::InitNew ()
+{
+ mnVersion = GetVersionConnected();
+ mbLoad = TRUE;
+ return S_OK;
+}
+
+STDMETHODIMP CSOActiveX::Load ( LPSTREAM /*pStm*/ )
+{
+ mnVersion = GetVersionConnected();
+ mbLoad = TRUE;
+
+ // may be later?
+ // for now just ignore
+
+ return S_OK;
+}
+
+STDMETHODIMP CSOActiveX::Load( LPPROPERTYBAG pPropBag, LPERRORLOG /*pErrorLog*/ )
+{
+ mnVersion = GetVersionConnected();
+
+ IPropertyBag2* pPropBag2;
+ HRESULT hr = pPropBag->QueryInterface( IID_IPropertyBag2, (void**)&pPropBag2 );
+ //ATLASSERT( hr >= 0 );
+
+ if( !SUCCEEDED( hr ) )
+ return hr;
+
+ unsigned long aNum;
+ hr = pPropBag2->CountProperties( &aNum );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ return hr;
+
+ PROPBAG2* aPropNames = new PROPBAG2[aNum];
+ unsigned long aReaded;
+
+ hr = pPropBag2->GetPropertyInfo( 0,
+ aNum,
+ aPropNames,
+ &aReaded );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ {
+ delete[] aPropNames;
+ return hr;
+ }
+
+ CComVariant* aVal = new CComVariant[aNum];
+ HRESULT* hvs = new HRESULT[aNum];
+ hr = pPropBag2->Read( aNum,
+ aPropNames,
+ NULL,
+ aVal,
+ hvs );
+ //ATLASSERT( hr >= 0 );
+ if( !SUCCEEDED( hr ) )
+ {
+ delete[] hvs;
+ delete[] aVal;
+ delete[] aPropNames;
+ return hr;
+ }
+
+ USES_CONVERSION;
+ for( unsigned long ind = 0; ind < aNum; ind++ )
+ {
+ // all information from the 'object' tag is in strings
+ if( aVal[ind].vt == VT_BSTR && !strcmp( OLE2T( aPropNames[ind].pstrName ), "src" ) )
+ {
+ mCurFileUrl = wcsdup( aVal[ind].bstrVal );
+ }
+ else if( aVal[ind].vt == VT_BSTR
+ && !strcmp( OLE2T( aPropNames[ind].pstrName ), "readonly" ) )
+ {
+ if( !strcmp( OLE2T( aVal[ind].bstrVal ), "true" ) )
+ {
+ // the default value
+ mbViewOnly = TRUE;
+ }
+ else
+ {
+ mbViewOnly = FALSE;
+ }
+ }
+ }
+
+ delete[] hvs;
+ delete[] aVal;
+ delete[] aPropNames;
+
+ if( !mpDispFactory )
+ return hr;
+
+ mbReadyForActivation = FALSE;
+ hr = CBindStatusCallback<CSOActiveX>::Download( this, &CSOActiveX::CallbackCreateXInputStream, mCurFileUrl, m_spClientSite, FALSE );
+ if ( hr == MK_S_ASYNCHRONOUS )
+ hr = S_OK;
+
+ if ( !SUCCEEDED( hr ) )
+ {
+ // trigger initialization without stream
+ mbLoad = TRUE;
+
+ Invalidate();
+ UpdateWindow();
+ }
+
+ return hr;
+}
+
+HRESULT CSOActiveX::GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult )
+{
+ CComVariant aComStruct( sStructName );
+ return GetIDispByFunc( mpDispFactory, L"Bridge_GetStruct", &aComStruct, 1, pdispResult );
+}
+
+HRESULT CSOActiveX::GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl )
+{
+ HRESULT hr = GetUnoStruct( L"com.sun.star.util.URL", pdispUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR* sURLMemberName = L"Complete";
+ DISPID nURLID;
+ hr = pdispUrl->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
+ if( !SUCCEEDED( hr ) ) return hr;
+ CComVariant aComUrl( sUrl );
+ hr = CComDispatchDriver::PutProperty( pdispUrl, nURLID, &aComUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComPtr<IDispatch> pdispTransformer;
+ CComVariant aServiceName( L"com.sun.star.util.URLTransformer" );
+ hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ pdispTransformer );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant dummyResult;
+ CComVariant aParam[2];
+ aParam[1].ppdispVal = &pdispUrl;
+ aParam[1].vt = VT_DISPATCH | VT_BYREF;
+ aParam[0] = CComVariant( L"file:///" );
+
+ hr = ExecuteFunc( pdispTransformer, L"parseSmart", aParam, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) || dummyResult.vt != VT_BOOL || !dummyResult.boolVal ) return hr;
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::SetLayoutManagerProps()
+{
+ if ( !mpDispFrame )
+ return E_FAIL;
+
+ CComVariant pVarLayoutMgr;
+ OLECHAR* sLMPropName = L"LayoutManager";
+ HRESULT hr = GetPropertiesFromIDisp( mpDispFrame, &sLMPropName, &pVarLayoutMgr, 1 );
+ if( pVarLayoutMgr.vt != VT_DISPATCH || pVarLayoutMgr.pdispVal == NULL )
+ return E_FAIL;
+
+ CComPtr<IDispatch> pdispLM( pVarLayoutMgr.pdispVal );
+
+
+ if( !SUCCEEDED( hr ) || !pdispLM )
+ return E_FAIL;
+
+ OLECHAR* sATName = L"AutomaticToolbars";
+ CComVariant pATProp;
+ pATProp.vt = VT_BOOL; pATProp.boolVal = VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispLM, &sATName, &pATProp, 1 );
+
+ return hr;
+}
+
+HRESULT CSOActiveX::CreateFrameOldWay( HWND hwnd, int width, int height )
+{
+ if( !mpDispFactory )
+ return E_FAIL;
+
+ // create window handle holder
+ CComPtr< CComObject< SOComWindowPeer > > pPeerToSend = new CComObject<SOComWindowPeer>();
+ pPeerToSend->SetHWNDInternally( hwnd );
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispToSend( pPeerToSend );
+
+ // create rectangle structure
+ CComPtr<IDispatch> pdispRectangle;
+ HRESULT hr = GetUnoStruct( L"com.sun.star.awt.Rectangle", pdispRectangle );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR* sRectMemberNames[4] = { L"X",
+ L"Y",
+ L"Width",
+ L"Height" };
+ CComVariant pRectVariant[4];
+ pRectVariant[0] = pRectVariant[1] = pRectVariant[2] = pRectVariant[3] = CComVariant( 0 );
+
+ hr = PutPropertiesToIDisp( pdispRectangle, sRectMemberNames, pRectVariant, 4 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create WindowDescriptor structure
+ CComPtr<IDispatch> pdispWinDescr;
+ hr = GetUnoStruct( L"com.sun.star.awt.WindowDescriptor", pdispWinDescr );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // fill in descriptor with info
+ OLECHAR* sDescriptorMemberNames[6] = { L"Type",
+ L"WindowServiceName",
+ L"ParentIndex",
+ L"Parent",
+ L"Bounds",
+ L"WindowAttributes" };
+ CComVariant pDescriptorVar[6];
+ pDescriptorVar[0] = CComVariant( 0 );
+ pDescriptorVar[1] = CComVariant( L"workwindow" );
+ pDescriptorVar[2] = CComVariant( 1 );
+ pDescriptorVar[3] = CComVariant( pIDispToSend );
+ pDescriptorVar[4] = CComVariant( pdispRectangle );
+ pDescriptorVar[5] = CComVariant( 33 );
+ hr = PutPropertiesToIDisp( pdispWinDescr, sDescriptorMemberNames, pDescriptorVar, 6 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create XToolkit instance
+ CComPtr<IDispatch> pdispToolkit;
+ CComVariant aServiceName( L"com.sun.star.awt.Toolkit" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispToolkit );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create window with toolkit
+ CComVariant aWinDescr( pdispWinDescr );
+ hr = GetIDispByFunc( pdispToolkit, L"createWindow", &aWinDescr, 1, mpDispWin );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create frame
+ aServiceName = CComVariant( L"com.sun.star.frame.Task" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
+ if( !SUCCEEDED( hr ) || !mpDispFrame )
+ {
+ // the interface com.sun.star.frame.Task is removed in 6.1
+ // but the interface com.sun.star.frame.Frame has some bugs in 6.0
+ aServiceName = CComVariant( L"com.sun.star.frame.Frame" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpDispFrame );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ // initialize frame
+ CComVariant dummyResult;
+ CComVariant aDispWin( mpDispWin );
+ hr = ExecuteFunc( mpDispFrame, L"initialize", &aDispWin, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // set some properties to the layout manager, ignore errors for now
+ SetLayoutManagerProps();
+
+ // create desktop
+ CComPtr<IDispatch> pdispDesktop;
+ aServiceName = CComVariant( L"com.sun.star.frame.Desktop" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, pdispDesktop );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create tree of frames
+ CComPtr<IDispatch> pdispChildren;
+ hr = GetIDispByFunc( pdispDesktop, L"getFrames", NULL, 0, pdispChildren );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // insert new frame into desctop hierarchy
+ CComVariant aDispFrame( mpDispFrame );
+ hr = ExecuteFunc( pdispChildren, L"append", &aDispFrame, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // initialize window
+ CComVariant aTransparent( (long)0xFFFFFFFF );
+ hr = ExecuteFunc( mpDispWin, L"setBackground", &aTransparent, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aTrue( TRUE );
+ hr = ExecuteFunc( mpDispWin, L"setVisible", &aTrue, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aPosArgs[5];
+ aPosArgs[4] = CComVariant( 0 );
+ aPosArgs[3] = CComVariant( 0 );
+ aPosArgs[2] = CComVariant( width );
+ aPosArgs[1] = CComVariant( height );
+ aPosArgs[0] = CComVariant( 12 );
+ hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ // create frame locker if there is such service
+ aServiceName = CComVariant( L"com.sun.star.embed.InstanceLocker" );
+ hr = GetIDispByFunc( mpDispFactory, L"createInstance", &aServiceName, 1, mpInstanceLocker );
+ if( SUCCEEDED( hr ) && mpInstanceLocker )
+ {
+ SAFEARRAY FAR* pInitVals = SafeArrayCreateVector( VT_VARIANT, 0, 3 );
+
+ // the first sequence element
+ long nInitInd = 0;
+ CComVariant pFrameVariant( mpDispFrame );
+ SafeArrayPutElement( pInitVals, &nInitInd, &pFrameVariant );
+
+ // the second sequence element
+ nInitInd = 1;
+ CComVariant pStrArr( 1L );
+ SafeArrayPutElement( pInitVals, &nInitInd, &pStrArr );
+
+ // the third sequence element
+ nInitInd = 2;
+ CComPtr<IDispatch> pdispValueObj;
+ hr = GetIDispByFunc( mpDispFactory, L"Bridge_GetValueObject", NULL, 0, pdispValueObj );
+ if( !SUCCEEDED( hr ) || !pdispValueObj ) return hr;
+
+ CComVariant aValueArgs[2];
+ aValueArgs[1] = CComVariant( L"com.sun.star.embed.XActionsApproval" );
+ CComPtr< CComObject< SOActionsApproval > > pApproval( new CComObject<SOActionsApproval>() );
+ aValueArgs[0] = CComVariant ( pApproval );
+
+ hr = ExecuteFunc( pdispValueObj, L"Set", aValueArgs, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aValueObj( pdispValueObj );
+ SafeArrayPutElement( pInitVals, &nInitInd, &aValueObj );
+
+ // execute initialize()
+ CComVariant aVarInitVals;
+ aVarInitVals.vt = VT_ARRAY | VT_VARIANT; aVarInitVals.parray = pInitVals;
+ hr = ExecuteFunc( mpInstanceLocker, L"initialize", &aVarInitVals, 1, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal )
+{
+ SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, 1 );
+ long ix = 0;
+ CComPtr<IDispatch> pdispPropVal;
+ HRESULT hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pPropVar[2];
+ pPropVar[0] = CComVariant( sArgName );
+ pPropVar[1].vt = VT_BOOL; pPropVar[1].boolVal = sArgVal ? VARIANT_TRUE : VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
+
+ CComVariant aDispArgs[4];
+ aDispArgs[3] = CComVariant( sUrl );
+ aDispArgs[2] = CComVariant( L"_self" );
+ aDispArgs[1] = CComVariant( 0 );
+ // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
+ aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
+
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispFrame, L"loadComponentFromURL", aDispArgs, 4, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::CallDispatchMethod( OLECHAR* sUrl,
+ CComVariant* aArgNames,
+ CComVariant* aArgVals,
+ unsigned int count )
+{
+ CComPtr<IDispatch> pdispURL;
+ HRESULT hr = GetUrlStruct( sUrl, pdispURL );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComPtr<IDispatch> pdispXDispatch;
+ CComVariant aArgs[3];
+ aArgs[2] = CComVariant( pdispURL );
+ aArgs[1] = CComVariant( L"" );
+ aArgs[0] = CComVariant( (int)0 );
+ hr = GetIDispByFunc( mpDispFrame,
+ L"queryDispatch",
+ aArgs,
+ 3,
+ pdispXDispatch );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SAFEARRAY FAR* pPropVals = SafeArrayCreateVector( VT_DISPATCH, 0, count );
+ for( long ix = 0; ix < (long)count; ix ++ )
+ {
+ CComPtr<IDispatch> pdispPropVal;
+ hr = GetUnoStruct( L"com.sun.star.beans.PropertyValue", pdispPropVal );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ OLECHAR* sPropMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pPropVar[2];
+ pPropVar[0] = aArgNames[ix];
+ pPropVar[1] = aArgVals[ix];
+ hr = PutPropertiesToIDisp( pdispPropVal, sPropMemberNames, pPropVar, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ SafeArrayPutElement( pPropVals, &ix, pdispPropVal );
+ }
+
+ CComVariant aDispArgs[2];
+ aDispArgs[1] = CComVariant( pdispURL );
+ // aDispArgs[0] = CComVariant( pPropVals ); such constructor is not defined ??!
+ aDispArgs[0].vt = VT_ARRAY | VT_DISPATCH; aDispArgs[0].parray = pPropVals;
+
+ CComVariant dummyResult;
+ hr = ExecuteFunc( pdispXDispatch, L"dispatch", aDispArgs, 2, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+void CSOActiveX::CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* /*pbsc*/, BYTE* pBytes, DWORD dwSize )
+{
+ if ( mbReadyForActivation )
+ return;
+
+ BOOL bSuccess = FALSE;
+ BOOL bFinishDownload = FALSE;
+ if ( !pBytes )
+ {
+ // means the download is finished, dwSize contains hresult
+ bFinishDownload = TRUE;
+ if ( SUCCEEDED( dwSize ) )
+ bSuccess = TRUE;
+ }
+ else
+ {
+ HRESULT hr = S_OK;
+
+ if ( !mpDispTempFile )
+ {
+ CComVariant aServiceName( L"com.sun.star.io.TempFile" );
+ hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ mpDispTempFile );
+ }
+
+ if( SUCCEEDED( hr ) && mpDispTempFile )
+ {
+ SAFEARRAY FAR* pDataArray = SafeArrayCreateVector( VT_I1, 0, dwSize );
+
+ if ( pDataArray )
+ {
+ hr = SafeArrayLock( pDataArray );
+ if ( SUCCEEDED( hr ) )
+ {
+ for( DWORD ix = 0; ix < dwSize; ix++ )
+ ((BYTE*)(pDataArray->pvData))[ix] = pBytes[ix];
+ hr = SafeArrayUnlock( pDataArray );
+ if ( SUCCEEDED( hr ) )
+ {
+ CComVariant aArgs[1];
+ aArgs[0].vt = VT_ARRAY | VT_I1; aArgs[0].parray = pDataArray;
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispTempFile, L"writeBytes", aArgs, 1, &dummyResult );
+ if( SUCCEEDED( hr ) )
+ bSuccess = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !bSuccess )
+ {
+ // the download failed, let StarOffice download
+ bFinishDownload = TRUE;
+ mpDispTempFile = CComPtr< IDispatch >();
+ }
+
+ if ( bFinishDownload )
+ {
+ // trigger the loading now
+ mbLoad = TRUE;
+ mbReadyForActivation = TRUE;
+
+ Invalidate();
+ UpdateWindow();
+ }
+}
+
+HRESULT CSOActiveX::LoadURLToFrame( )
+{
+ CComVariant aArgNames[4] = { L"ReadOnly", L"ViewOnly", L"AsTemplate", L"InputStream" };
+ CComVariant aArgVals[4];
+ unsigned int nCount = 3; // the 4-th argument is used only if the stream can be retrieved
+
+ aArgVals[0].vt = VT_BOOL; aArgVals[0].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
+ aArgVals[1].vt = VT_BOOL; aArgVals[1].boolVal = mbViewOnly ? VARIANT_TRUE : VARIANT_FALSE;
+ aArgVals[2].vt = VT_BOOL; aArgVals[2].boolVal = VARIANT_FALSE;
+
+ if ( mpDispTempFile )
+ {
+ aArgVals[3] = CComVariant( mpDispTempFile );
+ nCount = 4;
+ }
+
+ HRESULT hr = CallDispatchMethod( mCurFileUrl, aArgNames, aArgVals, nCount );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ CComVariant aBarName( L"MenuBarVisible" );
+ CComVariant aBarVis;
+ aBarVis.vt = VT_BOOL; aBarVis.boolVal = VARIANT_FALSE;
+ hr = CallDispatchMethod( L"slot:6661", &aBarName, &aBarVis, 1 );
+ // does not work for some documents, but it is no error
+ // if( !SUCCEEDED( hr ) ) return hr;
+
+ // try to get the model and set the presetation specific property, the setting will fail for other document formats
+ CComPtr<IDispatch> pdispController;
+ hr = GetIDispByFunc( mpDispFrame, L"getController", NULL, 0, pdispController );
+ if ( SUCCEEDED( hr ) && pdispController )
+ {
+ CComPtr<IDispatch> pdispModel;
+ hr = GetIDispByFunc( pdispController, L"getModel", NULL, 0, pdispModel );
+ if ( SUCCEEDED( hr ) && pdispModel )
+ {
+ CComPtr<IDispatch> pdispPres;
+ hr = GetIDispByFunc( pdispModel, L"getPresentation", NULL, 0, pdispPres );
+ if ( SUCCEEDED( hr ) && pdispPres )
+ {
+ // this is a presentation
+ // let the slide show be shown in the document window
+ OLECHAR* pPropName = L"IsFullScreen";
+ CComVariant pPresProp;
+ pPresProp.vt = VT_BOOL; pPresProp.boolVal = VARIANT_FALSE ;
+ hr = PutPropertiesToIDisp( pdispPres, &pPropName, &pPresProp, 1 );
+
+ // start the slide show
+ if ( SUCCEEDED( hr ) )
+ {
+ CComVariant dummyResult;
+ ExecuteFunc( pdispPres, L"Start", NULL, 0, &dummyResult );
+ }
+ }
+ }
+ }
+
+ // create dispatch interceptor
+ mpDispatchInterceptor = new CComObject< SODispatchInterceptor >();
+ mpDispatchInterceptor->AddRef();
+ mpDispatchInterceptor->SetParent( this );
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDispDispInter( mpDispatchInterceptor );
+
+ // register dispatch interceptor in the frame
+ CComVariant aDispVariant( pIDispDispInter );
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispFrame,
+ L"registerDispatchProviderInterceptor",
+ &aDispVariant,
+ 1,
+ &dummyResult );
+
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ return S_OK;
+}
+
+SOVersion CSOActiveX::GetVersionConnected()
+{
+ SOVersion bResult = SO_NOT_DETECTED;
+ if( mpDispFactory )
+ {
+ // create ConfigurationProvider instance
+ CComPtr<IDispatch> pdispConfProv;
+ CComVariant aServiceName( L"com.sun.star.configuration.ConfigurationProvider" );
+ HRESULT hr = GetIDispByFunc( mpDispFactory,
+ L"createInstance",
+ &aServiceName,
+ 1,
+ pdispConfProv );
+
+ if( SUCCEEDED( hr ) && pdispConfProv )
+ {
+ CComPtr<IDispatch> pdispConfAccess;
+
+ SAFEARRAY* pInitParams = SafeArrayCreateVector( VT_VARIANT, 0, 1 );
+
+ if( pInitParams )
+ {
+ long ix = 0;
+ CComVariant aConfPath( L"org.openoffice.Setup" );
+ SafeArrayPutElement( pInitParams, &ix, &aConfPath );
+
+ CComVariant aArgs[2];
+ aArgs[1] = CComVariant( L"com.sun.star.configuration.ConfigurationAccess" );
+ aArgs[0].vt = VT_ARRAY | VT_VARIANT; aArgs[0].parray = pInitParams;
+
+ hr = GetIDispByFunc( pdispConfProv,
+ L"createInstanceWithArguments",
+ aArgs,
+ 2,
+ pdispConfAccess );
+
+ if( SUCCEEDED( hr ) && pdispConfAccess )
+ {
+ CComVariant aOfficeName;
+
+ CComVariant aProductName( L"Product/ooName" );
+ hr = ExecuteFunc( pdispConfAccess,
+ L"getByHierarchicalName",
+ &aProductName,
+ 1,
+ &aOfficeName );
+
+ if( SUCCEEDED( hr ) && aOfficeName.vt == VT_BSTR )
+ {
+ CComVariant aOfficeVersion;
+
+ CComVariant aProductVersion( L"Product/ooSetupVersion" );
+ hr = ExecuteFunc( pdispConfAccess,
+ L"getByHierarchicalName",
+ &aProductVersion,
+ 1,
+ &aOfficeVersion );
+
+ if( SUCCEEDED( hr ) && aOfficeVersion.vt == VT_BSTR )
+ {
+ USES_CONVERSION;
+ if( !strcmp( OLE2T( aOfficeName.bstrVal ), "StarOffice" ) )
+ {
+ if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.1", 3 ) )
+ bResult = SO_61;
+ else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "6.0", 3 ) )
+ bResult = SO_60;
+ else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "5.2", 3 ) )
+ bResult = SO_52;
+ else
+ bResult = SO_UNKNOWN;
+ }
+ else // OpenOffice
+ {
+ if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.1", 3 ) )
+ bResult = OO_11;
+ else if( !strncmp( OLE2T( aOfficeVersion.bstrVal ), "1.0", 3 ) )
+ bResult = OO_10;
+ else
+ bResult = OO_UNKNOWN;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+class LockingGuard
+{
+ BOOL& mbLocked;
+public:
+ LockingGuard( BOOL& bLocked )
+ : mbLocked( bLocked )
+ {
+ mbLocked = TRUE;
+ }
+
+ ~LockingGuard()
+ {
+ mbLocked = FALSE;
+ }
+};
+
+HRESULT CSOActiveX::OnDrawAdvanced( ATL_DRAWINFO& di )
+{
+ // This method is called only in main thread, no need to lock it
+
+ // Get read of reentrance problems
+ if ( mbDrawLocked )
+ return S_OK;
+ LockingGuard aGuard( mbDrawLocked );
+
+ if( m_spInPlaceSite && mCurFileUrl && mbReadyForActivation )
+ {
+ HWND hwnd;
+ HRESULT hr = m_spInPlaceSite->GetWindow( &hwnd );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( mParentWin != hwnd || !mOffWin )
+ {
+ if( mpDispFrame )
+ {
+ CComVariant dummyResult;
+ CComVariant aPropVar;
+ aPropVar.vt = VT_BOOL; aPropVar.boolVal = VARIANT_FALSE;
+ HRESULT hr = ExecuteFunc( mpDispFrame, L"close", &aPropVar, 1, &dummyResult );
+ (void)hr;
+ mpDispFrame = CComPtr<IDispatch>();
+ }
+
+ mParentWin = hwnd;
+ mOffWin = CreateWindow(
+ STAROFFICE_WINDOWCLASS,
+ "OfficeContainer",
+ WS_CHILD | WS_CLIPCHILDREN | WS_BORDER,
+ di.prcBounds->left,
+ di.prcBounds->top,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top,
+ mParentWin,
+ NULL,
+ NULL,
+ NULL );
+
+ ::ShowWindow( mOffWin, SW_SHOW );
+ }
+ else
+ {
+ RECT aRect;
+ ::GetWindowRect( mOffWin, &aRect );
+
+ if( aRect.left != di.prcBounds->left || aRect.top != di.prcBounds->top
+ || aRect.right != di.prcBounds->right || aRect.bottom != di.prcBounds->bottom )
+ {
+ // on this state the office window should exist already
+ ::SetWindowPos( mOffWin,
+ HWND_TOP,
+ di.prcBounds->left,
+ di.prcBounds->top,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top,
+ SWP_NOZORDER );
+
+ CComVariant aPosArgs[5];
+ aPosArgs[4] = CComVariant( 0 );
+ aPosArgs[3] = CComVariant( 0 );
+ aPosArgs[2] = CComVariant( int(di.prcBounds->right - di.prcBounds->left) );
+ aPosArgs[1] = CComVariant( int(di.prcBounds->bottom - di.prcBounds->top) );
+ aPosArgs[0] = CComVariant( 12 );
+ CComVariant dummyResult;
+ hr = ExecuteFunc( mpDispWin, L"setPosSize", aPosArgs, 5, &dummyResult );
+ if( !SUCCEEDED( hr ) ) return hr;
+ }
+ }
+
+ if( !mnVersion )
+ {
+ OutputError_Impl( mOffWin, CS_E_INVALID_VERSION );
+ return E_FAIL;
+ }
+
+ if( ! mpDispFrame )
+ {
+ hr = CreateFrameOldWay( mOffWin,
+ di.prcBounds->right - di.prcBounds->left,
+ di.prcBounds->bottom - di.prcBounds->top );
+
+ if( !SUCCEEDED( hr ) )
+ {
+ // if the frame can not be opened do not try any more
+ mbReadyForActivation = FALSE;
+ OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
+ return hr;
+ }
+ }
+
+ if( mbLoad )
+ {
+ hr = LoadURLToFrame();
+ mbLoad = FALSE;
+
+ if( !SUCCEEDED( hr ) )
+ {
+ // if the document can not be opened do not try any more
+ mbReadyForActivation = FALSE;
+
+ OutputError_Impl( mOffWin, STG_E_ABNORMALAPIEXIT );
+
+ return hr;
+ }
+ }
+ }
+ else
+ {
+ // activate the fallback
+ CComControl<CSOActiveX>::OnDrawAdvanced( di );
+ }
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::OnDraw( ATL_DRAWINFO& di )
+{
+ // fallback that is activated by the parent class
+ if ( di.hdcDraw )
+ FillRect( di.hdcDraw, (RECT*)di.prcBounds, (HBRUSH)COLOR_BACKGROUND );
+
+ return S_OK;
+}
+
+STDMETHODIMP CSOActiveX::SetClientSite( IOleClientSite* aClientSite )
+{
+ HRESULT hr = IOleObjectImpl<CSOActiveX>::SetClientSite( aClientSite );
+
+ if( !aClientSite )
+ {
+ //ATLASSERT( mWebBrowser2 );
+ if( mWebBrowser2 )
+ AtlUnadvise( mWebBrowser2, DIID_DWebBrowserEvents2, mCookie );
+ return hr;
+ }
+
+ CComPtr<IOleContainer> aContainer;
+ m_spClientSite->GetContainer( &aContainer );
+// ATLASSERT( aContainer );
+
+ if( SUCCEEDED( hr ) && aContainer )
+ {
+ CComQIPtr<IServiceProvider, &IID_IServiceProvider> aServiceProvider( aContainer );
+ //ATLASSERT( aServiceProvider );
+
+ if( aServiceProvider )
+ {
+ aServiceProvider->QueryService( SID_SInternetExplorer,
+ IID_IWebBrowser,
+ (void**)&mWebBrowser2 );
+// ATLASSERT( mWebBrowser2 );
+ if( mWebBrowser2 )
+ AtlAdvise( mWebBrowser2, GetUnknown(), DIID_DWebBrowserEvents2, &mCookie );
+ }
+ }
+
+ return hr;
+}
+
+STDMETHODIMP CSOActiveX::Invoke(DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pvarResult,
+ EXCEPINFO* pExcepInfo,
+ UINT* puArgErr)
+{
+ if (riid != IID_NULL)
+ return DISP_E_UNKNOWNINTERFACE;
+
+ if (!pDispParams)
+ return DISP_E_PARAMNOTOPTIONAL;
+
+ if ( dispidMember == DISPID_ONQUIT )
+ Cleanup();
+
+ IDispatchImpl<ISOActiveX, &IID_ISOActiveX,
+ &LIBID_SO_ACTIVEXLib>::Invoke(
+ dispidMember, riid, lcid, wFlags, pDispParams,
+ pvarResult, pExcepInfo, puArgErr);
+
+ return S_OK;
+}
+
+HRESULT CSOActiveX::GetURL( const OLECHAR* url,
+ const OLECHAR* target )
+{
+ CComVariant aEmpty1, aEmpty2, aEmpty3;
+ CComVariant aUrl( url );
+ CComVariant aTarget;
+ if ( target )
+ aTarget = CComVariant( target );
+
+ return mWebBrowser2->Navigate2( &aUrl,
+ &aEmpty1,
+ &aTarget,
+ &aEmpty2,
+ &aEmpty3 );
+}
+
+
+// ---------------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOActiveX.h b/extensions/source/activex/main/SOActiveX.h
new file mode 100644
index 000000000000..fea95d09c9b9
--- /dev/null
+++ b/extensions/source/activex/main/SOActiveX.h
@@ -0,0 +1,178 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOActiveX.h : Declaration of the CSOActiveX
+
+#ifndef __SOACTIVEX_H_
+#define __SOACTIVEX_H_
+
+#include "resource.h" // main symbols
+
+#pragma warning (disable:4505)
+ // permanently suppress "unreferenced local function has been removed" warning
+
+#pragma warning (push,1)
+#pragma warning (disable:4265)
+
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlctl.h>
+
+#include "so_activex.h"
+
+#pragma warning (pop)
+
+class SODispatchInterceptor;
+
+enum SOVersion {
+ SO_NOT_DETECTED = 0,
+ SO_52,
+ SO_60,
+ SO_61,
+ SO_UNKNOWN,
+ OO_10,
+ OO_11,
+ OO_UNKNOWN
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CSOActiveX
+class ATL_NO_VTABLE CSOActiveX :
+ public CComObjectRootEx<CComSingleThreadModel>,
+ public IDispatchImpl<ISOActiveX, &IID_ISOActiveX, &LIBID_SO_ACTIVEXLib>,
+ public CComControl<CSOActiveX>,
+ public IPersistStreamInitImpl<CSOActiveX>,
+ public IOleControlImpl<CSOActiveX>,
+ public IOleObjectImpl<CSOActiveX>,
+ public IOleInPlaceActiveObjectImpl<CSOActiveX>,
+ public IViewObjectExImpl<CSOActiveX>,
+ public IOleInPlaceObjectWindowlessImpl<CSOActiveX>,
+// public IConnectionPointContainerImpl<CSOActiveX>,
+ public CComCoClass<CSOActiveX, &CLSID_SOActiveX>,
+// public CProxy_ItryPluginEvents< CSOActiveX >,
+ public IPersistPropertyBagImpl< CSOActiveX >,
+ public IProvideClassInfo2Impl< &CLSID_SOActiveX,
+ &DIID__ISOActiveXEvents,
+ &LIBID_SO_ACTIVEXLib >,
+ public IObjectSafetyImpl< CSOActiveX,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA >
+{
+protected:
+ CComPtr<IWebBrowser2> mWebBrowser2;
+ DWORD mCookie;
+
+ CComPtr<IDispatch> mpDispFactory;
+ CComPtr<IDispatch> mpDispFrame;
+ CComPtr<IDispatch> mpInstanceLocker;
+ CComPtr<IDispatch> mpDispWin;
+ OLECHAR* mCurFileUrl;
+ BOOL mbLoad;
+ BOOL mbViewOnly;
+ WNDCLASS mPWinClass;
+ HWND mParentWin;
+ HWND mOffWin;
+
+ SODispatchInterceptor* mpDispatchInterceptor;
+ SOVersion mnVersion;
+
+ BOOL mbReadyForActivation;
+ CComPtr<IDispatch> mpDispTempFile;
+
+ BOOL mbDrawLocked;
+
+public:
+ CSOActiveX();
+ ~CSOActiveX();
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SOACTIVEX)
+
+DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+BEGIN_COM_MAP(CSOActiveX)
+ COM_INTERFACE_ENTRY(ISOActiveX)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(IViewObjectEx)
+ COM_INTERFACE_ENTRY(IViewObject2)
+ COM_INTERFACE_ENTRY(IViewObject)
+ COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceObject)
+ COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
+ COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
+ COM_INTERFACE_ENTRY(IOleControl)
+ COM_INTERFACE_ENTRY(IOleObject)
+ COM_INTERFACE_ENTRY(IPersistStreamInit)
+ COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
+// COM_INTERFACE_ENTRY(IConnectionPointContainer)
+ COM_INTERFACE_ENTRY(IProvideClassInfo)
+ COM_INTERFACE_ENTRY(IProvideClassInfo2)
+ COM_INTERFACE_ENTRY(IPersistPropertyBag)
+ COM_INTERFACE_ENTRY(IObjectSafety)
+END_COM_MAP()
+
+BEGIN_PROP_MAP(CSOActiveX)
+ PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
+ PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
+ // Example entries
+ // PROP_ENTRY("Property Description", dispid, clsid)
+ // PROP_PAGE(CLSID_StockColorPage)
+END_PROP_MAP()
+
+BEGIN_CONNECTION_POINT_MAP(CSOActiveX)
+END_CONNECTION_POINT_MAP()
+
+BEGIN_MSG_MAP(CSOActiveX)
+ CHAIN_MSG_MAP(CComControl<CSOActiveX>)
+ DEFAULT_REFLECTION_HANDLER()
+END_MSG_MAP()
+// Handler prototypes:
+// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
+// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
+
+
+
+// IViewObjectEx
+ DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
+
+// ISOActiveX
+public:
+
+ STDMETHOD(SetClientSite)( IOleClientSite* aClientSite );
+ STDMETHOD(Invoke)( DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pvarResult,
+ EXCEPINFO* pExcepInfo,
+ UINT* puArgErr);
+ STDMETHOD(Load) ( LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog );
+ STDMETHOD(Load) ( LPSTREAM pStm );
+ STDMETHOD(InitNew) ();
+ HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
+ HRESULT OnDraw(ATL_DRAWINFO& di);
+
+ HRESULT SetLayoutManagerProps();
+ HRESULT CreateFrameOldWay( HWND hwnd, int width, int height );
+ HRESULT GetUnoStruct( OLECHAR* sStructName, CComPtr<IDispatch>& pdispResult );
+ HRESULT LoadURLToFrame();
+ HRESULT CallDispatchMethod( OLECHAR* sUrl, CComVariant* sArgNames, CComVariant* sArgVal, unsigned int count );
+ HRESULT CallLoadComponentFromURL1PBool( OLECHAR* sUrl, OLECHAR* sArgName, BOOL sArgVal );
+ HRESULT GetUrlStruct( OLECHAR* sUrl, CComPtr<IDispatch>& pdispUrl );
+ HRESULT Cleanup();
+ HRESULT TerminateOffice();
+ HRESULT GetURL( const OLECHAR* url,
+ const OLECHAR* target );
+
+ void CallbackCreateXInputStream( CBindStatusCallback<CSOActiveX>* pbsc, BYTE* pBytes, DWORD dwSize );
+
+
+ SOVersion GetVersionConnected();
+};
+
+#endif //__SOACTIVEX_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOActiveX.rgs b/extensions/source/activex/main/SOActiveX.rgs
new file mode 100644
index 000000000000..d3814df3b241
--- /dev/null
+++ b/extensions/source/activex/main/SOActiveX.rgs
@@ -0,0 +1,33 @@
+HKCR
+{
+ so_activex.SOActiveX.1 = s 'SOActiveX Class'
+ {
+ CLSID = s '{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}'
+ }
+ so_activex.SOActiveX = s 'SOActiveX Class'
+ {
+ CLSID = s '{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}'
+ CurVer = s 'so_activex.SOActiveX.1'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {67F2A879-82D5-4A6D-8CC5-FFB3C114B69D} = s 'SOActiveX Class'
+ {
+ ProgID = s 'so_activex.SOActiveX.1'
+ VersionIndependentProgID = s 'so_activex.SOActiveX'
+ ForceRemove 'Programmable'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ ForceRemove 'Control'
+ ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 101'
+ 'MiscStatus' = s '0'
+ {
+ '1' = s '131473'
+ }
+ 'TypeLib' = s '{61FA3F13-8061-4796-B055-3697ED28CB38}'
+ 'Version' = s '1.0'
+ }
+ }
+}
diff --git a/extensions/source/activex/main/SOComWindowPeer.cpp b/extensions/source/activex/main/SOComWindowPeer.cpp
new file mode 100644
index 000000000000..7fb56dbdfd32
--- /dev/null
+++ b/extensions/source/activex/main/SOComWindowPeer.cpp
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOComWindowPeer.cpp : Implementation of CHelpApp and DLL registration.
+
+#include "stdafx2.h"
+#include "so_activex.h"
+#include "SOComWindowPeer.h"
+#include <sal/macros.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+STDMETHODIMP SOComWindowPeer::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] =
+ {
+ &IID_ISOComWindowPeer,
+ };
+
+ for (int i=0;i<SAL_N_ELEMENTS(arr);i++)
+ {
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+ if (InlineIsEqualGUID(*arr[i],riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i],riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOComWindowPeer.h b/extensions/source/activex/main/SOComWindowPeer.h
new file mode 100644
index 000000000000..c819e17a81ea
--- /dev/null
+++ b/extensions/source/activex/main/SOComWindowPeer.h
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SOComWindowPeer.h: Definition of the SOComWindowPeer class
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined __SOCOMWINDOWPEER_H_
+#define __SOCOMWINDOWPEER_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h" // main symbols
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlctl.h>
+
+#include "so_activex.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// SOComWindowPeer
+
+class SOComWindowPeer :
+ public IDispatchImpl<ISOComWindowPeer, &IID_ISOComWindowPeer, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SOComWindowPeer,&CLSID_SOComWindowPeer>
+{
+ HWND m_hwnd;
+public:
+ SOComWindowPeer() : m_hwnd( NULL ) {}
+ virtual ~SOComWindowPeer() { }
+
+BEGIN_COM_MAP(SOComWindowPeer)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISOComWindowPeer)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+END_COM_MAP()
+DECLARE_NOT_AGGREGATABLE(SOComWindowPeer)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SOCOMWINDOWPEER)
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
+
+// ISOComWindowPeer
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getWindowHandle(
+ /* [in] */ SAFEARRAY __RPC_FAR * /*procId*/,
+ /* [in] */ short /*s*/,
+ /* [retval][out] */ long __RPC_FAR *ret)
+ {
+ *ret = HandleToLong( m_hwnd );
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getToolkit(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal)
+ {
+ *retVal = NULL;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setPointer(
+ /* [in] */ IDispatch __RPC_FAR* /*xPointer*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setBackground(
+ /* [in] */ int /*nColor*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE invalidate(
+ /* [in] */ short /*__MIDL_0015*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE invalidateRect(
+ /* [in] */ IDispatch __RPC_FAR* /*aRect*/,
+ /* [in] */ short /*nFlags*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE dispose( void)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE addEventListener(
+ /* [in] */ IDispatch __RPC_FAR* /*xListener*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE removeEventListener(
+ /* [in] */ IDispatch __RPC_FAR* /*xListener*/)
+ {
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal)
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 2 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ long ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.awt.XSystemDependentWindowPeer" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 1;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.awt.XWindowPeer" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+
+ void SetHWNDInternally( HWND hwnd ) { m_hwnd = hwnd; }
+};
+
+#endif // __SOCOMWINDOWPEER_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SOComWindowPeer.rgs b/extensions/source/activex/main/SOComWindowPeer.rgs
new file mode 100644
index 000000000000..42e985a31a1b
--- /dev/null
+++ b/extensions/source/activex/main/SOComWindowPeer.rgs
@@ -0,0 +1,23 @@
+HKCR
+{
+ so_activex.SOComWindowPeer.1 = s 'SOComWindowPeer Class'
+ {
+ CLSID = s '{EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D}'
+ }
+ so_activex.SOComWindowPeer = s 'SOComWindowPeer Class'
+ {
+ CLSID = s '{EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {EE51BD3E-8BB6-4FB8-B319-F65B1BE3B21D} = s 'SOComWindowPeer Class'
+ {
+ ProgID = s 'so_activex.SOComWindowPeer.1'
+ VersionIndependentProgID = s 'so_activex.SOComWindowPeer'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/main/SODispatchInterceptor.cpp b/extensions/source/activex/main/SODispatchInterceptor.cpp
new file mode 100644
index 000000000000..dcddf0d86b0c
--- /dev/null
+++ b/extensions/source/activex/main/SODispatchInterceptor.cpp
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SODispatchInterceptor.cpp : Implementation of CHelpApp and DLL registration.
+
+#include "stdio.h"
+#include "stdafx2.h"
+#include "so_activex.h"
+#include "SOActiveX.h"
+#include "SODispatchInterceptor.h"
+#include "com_uno_helper.h"
+#include <sal/macros.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+STDMETHODIMP SODispatchInterceptor::InterfaceSupportsErrorInfo(REFIID riid)
+{
+ static const IID* arr[] =
+ {
+ &IID_ISODispatchInterceptor,
+ };
+
+ for (int i=0;i<SAL_N_ELEMENTS(arr);i++)
+ {
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+ if (InlineIsEqualGUID(*arr[i],riid))
+#else
+ if (::ATL::InlineIsEqualGUID(*arr[i],riid))
+#endif
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+STDMETHODIMP SODispatchInterceptor::queryDispatch( IDispatch FAR* aURL,
+ BSTR aTargetFrameName,
+ long nSearchFlags,
+ IDispatch FAR* FAR* retVal )
+{
+ if ( !aURL || !retVal ) return E_FAIL;
+
+ CComVariant aTargetUrl;
+ OLECHAR* sURLMemberName = L"Complete";
+ DISPID nURLID;
+ HRESULT hr = aURL->GetIDsOfNames( IID_NULL, &sURLMemberName, 1, LOCALE_USER_DEFAULT, &nURLID );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = CComDispatchDriver::GetProperty( aURL, nURLID, &aTargetUrl );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( aTargetUrl.vt != VT_BSTR ) return E_FAIL;
+
+ USES_CONVERSION;
+ if( !strncmp( OLE2T( aTargetUrl.bstrVal ), ".uno:OpenHyperlink", 18 ) )
+ {
+ CComQIPtr< IDispatch, &IID_IDispatch > pIDisp( this );
+ if( pIDisp )
+ {
+ this->AddRef();
+ *retVal = pIDisp;
+ }
+ }
+ else
+ {
+ if( !m_xSlave )
+ {
+ *retVal = NULL;
+ return S_OK;
+ }
+
+ CComVariant aResult;
+ CComVariant aArgs[3];
+ aArgs[0] = CComVariant( nSearchFlags );
+ aArgs[1] = CComVariant( aTargetFrameName );
+ aArgs[2] = CComVariant( aURL );
+
+ hr = ExecuteFunc( m_xSlave, L"queryDispatch", aArgs, 3, &aResult );
+ if( !SUCCEEDED( hr ) || aResult.vt != VT_DISPATCH || aResult.pdispVal == NULL )
+ {
+ *retVal = NULL;
+ return S_OK;
+ }
+
+ *retVal = aResult.pdispVal;
+
+ CComQIPtr< IUnknown, &IID_IUnknown > pIUnk( *retVal );
+ if( pIUnk )
+ (*retVal)->AddRef();
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::queryDispatches( SAFEARRAY FAR* aDescripts, SAFEARRAY FAR* FAR* retVal)
+{
+ if ( !aDescripts || !retVal || SafeArrayGetDim( aDescripts ) != 1 )
+ return E_FAIL;
+
+ long nLB, nUB;
+
+ HRESULT hr = SafeArrayGetLBound( aDescripts, 1, &nLB );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = SafeArrayGetUBound( aDescripts, 1, &nUB );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( nUB < nLB ) return E_FAIL;
+
+ *retVal = SafeArrayCreateVector( VT_DISPATCH, 0, nUB - nLB );
+
+ for ( long ind = nLB; ind <= nUB; ind ++ )
+ {
+ CComPtr<IDispatch> pElem;
+ SafeArrayGetElement( aDescripts, &ind, pElem );
+ if( pElem )
+ {
+ OLECHAR* pMemberNames[3] = { L"FeatureURL", L"FrameName", L"SearchFlags" };
+ CComVariant pValues[3];
+ hr = GetPropertiesFromIDisp( pElem, pMemberNames, pValues, 3 );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( pValues[0].vt != VT_DISPATCH || pValues[0].pdispVal == NULL
+ || pValues[1].vt != VT_BSTR || pValues[2].vt != VT_I4 )
+ return E_FAIL;
+
+ CComPtr<IDispatch> aRes;
+ hr = queryDispatch( pValues[0].pdispVal, pValues[1].bstrVal, pValues[2].lVal, &aRes );
+ SafeArrayPutElement( *retVal, &ind, aRes );
+ }
+ }
+
+ return S_OK;
+}
+
+
+STDMETHODIMP SODispatchInterceptor::dispatch( IDispatch FAR* aURL, SAFEARRAY FAR* aArgs)
+{
+ // get url from aURL
+ OLECHAR* pUrlName = L"Complete";
+ CComVariant pValue;
+ HRESULT hr = GetPropertiesFromIDisp( aURL, &pUrlName, &pValue, 1 );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( pValue.vt != VT_BSTR || pValue.bstrVal == NULL )
+ return E_FAIL;
+
+ USES_CONVERSION;
+ if( !strncmp( OLE2T( pValue.bstrVal ), ".uno:OpenHyperlink", 18 ) )
+ {
+ long nLB = 0, nUB = 0;
+ // long nDim = SafeArrayGetDim( aArgs );
+
+ hr = SafeArrayGetLBound( aArgs, 1, &nLB );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ hr = SafeArrayGetUBound( aArgs, 1, &nUB );
+ if( !SUCCEEDED( hr ) ) return hr;
+ if( nUB < nLB ) return E_FAIL;
+
+ for ( long ind = nLB; ind <= nUB; ind ++ )
+ {
+ CComVariant pVarElem;
+ SafeArrayGetElement( aArgs, &ind, &pVarElem );
+ if( pVarElem.vt == VT_DISPATCH && pVarElem.pdispVal != NULL )
+ {
+ OLECHAR* pMemberNames[2] = { L"Name", L"Value" };
+ CComVariant pValues[2];
+ hr = GetPropertiesFromIDisp( pVarElem.pdispVal, pMemberNames, pValues, 2 );
+ if( !SUCCEEDED( hr ) ) return hr;
+
+ if( pValues[0].vt == VT_BSTR && pValues[1].vt == VT_BSTR )
+ {
+ USES_CONVERSION;
+ if( !strncmp( OLE2T( pValues[0].bstrVal ), "URL", 3 ) )
+ {
+ EnterCriticalSection( &mMutex );
+ if( m_xParentControl )
+ {
+ // call GetUrl to the browser instance
+ m_xParentControl->GetURL( pValues[1].bstrVal, L"_self" );
+ }
+ LeaveCriticalSection( &mMutex );
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::addStatusListener( IDispatch FAR* /*xControl*/, IDispatch FAR* /*aURL*/)
+{
+ // not implemented
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::removeStatusListener( IDispatch FAR* /*xControl*/, IDispatch FAR* /*aURL*/)
+{
+ // not implemented
+ return S_OK;
+}
+
+STDMETHODIMP SODispatchInterceptor::getInterceptedURLs( SAFEARRAY FAR* FAR* pVal )
+{
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 3 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ long ix = 0;
+ CComBSTR aPattern( OLESTR( "ftp://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ ix = 1;
+ aPattern = CComBSTR( OLESTR( "http://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ ix = 2;
+ aPattern = CComBSTR( OLESTR( "file://*" ) );
+ SafeArrayPutElement( *pVal, &ix, aPattern );
+
+ return S_OK;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SODispatchInterceptor.h b/extensions/source/activex/main/SODispatchInterceptor.h
new file mode 100644
index 000000000000..538b12f24d2e
--- /dev/null
+++ b/extensions/source/activex/main/SODispatchInterceptor.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// SODispatchInterceptor.h: Definition of the SODispatchInterceptor class
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined __SODISPATCHINTERCEPTOR_H_
+#define __SODISPATCHINTERCEPTOR_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h" // main symbols
+#include <ExDispID.h>
+#include <ExDisp.h>
+#include <shlguid.h>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlctl.h>
+
+#include "so_activex.h"
+
+class CSOActiveX;
+
+/////////////////////////////////////////////////////////////////////////////
+// SODispatchInterceptor
+
+class SODispatchInterceptor :
+ public IDispatchImpl<ISODispatchInterceptor, &IID_ISODispatchInterceptor, &LIBID_SO_ACTIVEXLib>,
+ public ISupportErrorInfo,
+ public CComObjectRoot,
+ public CComCoClass<SODispatchInterceptor,&CLSID_SODispatchInterceptor>
+{
+ CComPtr<IDispatch> m_xMaster;
+ CComPtr<IDispatch> m_xSlave;
+ CSOActiveX* m_xParentControl;
+ CRITICAL_SECTION mMutex;
+public:
+ SODispatchInterceptor() : m_xParentControl( NULL ) { InitializeCriticalSection(&mMutex); }
+ virtual ~SODispatchInterceptor() { ATLASSERT( !m_xParentControl ); DeleteCriticalSection(&mMutex); }
+
+BEGIN_COM_MAP(SODispatchInterceptor)
+ COM_INTERFACE_ENTRY(IDispatch)
+ COM_INTERFACE_ENTRY(ISODispatchInterceptor)
+ COM_INTERFACE_ENTRY(ISupportErrorInfo)
+END_COM_MAP()
+DECLARE_NOT_AGGREGATABLE(SODispatchInterceptor)
+// Remove the comment from the line above if you don't want your object to
+// support aggregation.
+
+DECLARE_REGISTRY_RESOURCEID(IDR_SODISPATCHINTERCEPTOR)
+
+ void SetParent( CSOActiveX* pParent )
+ {
+ ATLASSERT( !m_xParentControl );
+ EnterCriticalSection( &mMutex );
+ m_xParentControl = pParent;
+ LeaveCriticalSection( &mMutex );
+ }
+
+ void ClearParent()
+ {
+ EnterCriticalSection( &mMutex );
+ m_xParentControl = NULL;
+ LeaveCriticalSection( &mMutex );
+ }
+
+// ISupportsErrorInfo
+ STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
+
+// ISODispatchInterceptor
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getSlaveDispatchProvider(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal)
+ {
+ *retVal = m_xSlave;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setSlaveDispatchProvider(
+ /* [in] */ IDispatch __RPC_FAR *xNewDispatchProvider)
+ {
+ m_xSlave = xNewDispatchProvider;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getMasterDispatchProvider(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal)
+ {
+ *retVal = m_xMaster;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE setMasterDispatchProvider(
+ /* [in] */ IDispatch __RPC_FAR *xNewSupplier)
+ {
+ m_xMaster = xNewSupplier;
+ return S_OK;
+ }
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE queryDispatch(
+ /* [in] */ IDispatch __RPC_FAR *aURL,
+ /* [in] */ BSTR aTargetFrameName,
+ /* [in] */ long nSearchFlags,
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *retVal);
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE queryDispatches(
+ /* [in] */ SAFEARRAY __RPC_FAR * aDescripts,
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *retVal);
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE dispatch(
+ /* [in] */ IDispatch __RPC_FAR *aURL,
+ /* [in] */ SAFEARRAY __RPC_FAR * aArgs);
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE addStatusListener(
+ /* [in] */ IDispatch __RPC_FAR *xControl,
+ /* [in] */ IDispatch __RPC_FAR *aURL);
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE removeStatusListener(
+ /* [in] */ IDispatch __RPC_FAR *xControl,
+ /* [in] */ IDispatch __RPC_FAR *aURL);
+
+ virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE getInterceptedURLs(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal);
+
+ virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Bridge_implementedInterfaces(
+ /* [retval][out] */ SAFEARRAY __RPC_FAR * __RPC_FAR *pVal)
+ {
+ *pVal = SafeArrayCreateVector( VT_BSTR, 0, 4 );
+
+ if( !*pVal )
+ return E_FAIL;
+
+ long ix = 0;
+ CComBSTR aInterface( OLESTR( "com.sun.star.frame.XDispatchProviderInterceptor" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 1;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XDispatchProvider" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 2;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XDispatch" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ ix = 3;
+ aInterface = CComBSTR( OLESTR( "com.sun.star.frame.XInterceptorInfo" ) );
+ SafeArrayPutElement( *pVal, &ix, aInterface );
+
+ return S_OK;
+ }
+};
+
+#endif // __SODISPATCHINTERCEPTOR_H_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/SODispatchInterceptor.rgs b/extensions/source/activex/main/SODispatchInterceptor.rgs
new file mode 100644
index 000000000000..19fe0b5f0e4c
--- /dev/null
+++ b/extensions/source/activex/main/SODispatchInterceptor.rgs
@@ -0,0 +1,23 @@
+HKCR
+{
+ so_activex.SODispatchInterceptor.1 = s 'SODispatchInterceptor Class'
+ {
+ CLSID = s '{C5D6D568-57DA-4D6C-819A-451CB565E682}'
+ }
+ so_activex.SODispatchInterceptor = s 'SODispatchInterceptor Class'
+ {
+ CLSID = s '{C5D6D568-57DA-4D6C-819A-451CB565E682}'
+ }
+ NoRemove CLSID
+ {
+ ForceRemove {C5D6D568-57DA-4D6C-819A-451CB565E682} = s 'SODispatchInterceptor Class'
+ {
+ ProgID = s 'so_activex.SODispatchInterceptor.1'
+ VersionIndependentProgID = s 'so_activex.SODispatchInterceptor'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'both'
+ }
+ }
+ }
+}
diff --git a/extensions/source/activex/main/StdAfx2.cpp b/extensions/source/activex/main/StdAfx2.cpp
new file mode 100644
index 000000000000..f1cf88d10d14
--- /dev/null
+++ b/extensions/source/activex/main/StdAfx2.cpp
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// stdafx1.cpp : source file that includes just the standard includes
+// stdafx1.pch will be the pre-compiled header
+// stdafx1.obj will contain the pre-compiled type information
+
+#ifdef __MINGW32__
+#define _INIT_ATL_COMMON_VARS
+#endif
+#include "stdafx2.h"
+
+#ifdef _ATL_STATIC_REGISTRY
+#include <statreg.h>
+#include <statreg.cpp>
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+#undef _DEBUG
+#endif
+#include <atlimpl.cpp>
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/StdAfx2.h b/extensions/source/activex/main/StdAfx2.h
new file mode 100644
index 000000000000..5c540b0ba329
--- /dev/null
+++ b/extensions/source/activex/main/StdAfx2.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// stdafx1.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#if !defined(AFX_STDAFX_H__C1799EA0_62CC_44DE_A2DD_C9F0410FF7F1__INCLUDED_)
+#define AFX_STDAFX_H__C1799EA0_62CC_44DE_A2DD_C9F0410FF7F1__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define STRICT
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+#define _ATL_APARTMENT_THREADED
+#define _ATL_STATIC_REGISTRY
+
+#pragma warning (disable:4505)
+ // globally disable "unreferenced local function has been removed"
+
+#pragma warning (push,1)
+#pragma warning (disable:4548)
+ // expression before comma has no effect; expected expression with side-effect
+#pragma warning (disable:4555)
+ // expression has no effect; expected expression with side-effect
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#include <atlbase.h>
+
+//You may derive a class from CComModule and use it if you want to override
+//something, but do not change the name of _Module
+extern CComModule _Module;
+#include <atlcom.h>
+#include <atlctl.h>
+
+#pragma warning (pop)
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__C1799EA0_62CC_44DE_A2DD_C9F0410FF7F1__INCLUDED)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/com_uno_helper.h b/extensions/source/activex/main/com_uno_helper.h
new file mode 100644
index 000000000000..230fc63a6e77
--- /dev/null
+++ b/extensions/source/activex/main/com_uno_helper.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#include "stdafx2.h"
+
+HRESULT ExecuteFunc( IDispatch* idispUnoObject,
+ OLECHAR* sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComVariant* pResult );
+
+HRESULT GetIDispByFunc( IDispatch* idispUnoObject,
+ OLECHAR* sFuncName,
+ CComVariant* params,
+ unsigned int count,
+ CComPtr<IDispatch>& pdispResult );
+
+HRESULT PutPropertiesToIDisp( IDispatch* pdispObject,
+ OLECHAR** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count );
+
+HRESULT GetPropertiesFromIDisp( IDispatch* pdispObject,
+ OLECHAR** sMemberNames,
+ CComVariant* pVariant,
+ unsigned int count );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/example.html b/extensions/source/activex/main/example.html
new file mode 100644
index 000000000000..3efee1f75a03
--- /dev/null
+++ b/extensions/source/activex/main/example.html
@@ -0,0 +1,26 @@
+<HTML>
+<HEAD>
+<TITLE>Document Title</TITLE>
+</HEAD>
+<BODY>
+
+<center>
+First you should edit the example.html file!!!
+</center>
+<center>
+<!-- Please edit CODEBASE parameter -->
+<!-- In case ActiveX control is already registered the parameter can be removed -->
+<OBJECT CLASSID="clsid:67F2A879-82D5-4A6D-8CC5-FFB3C114B69D" width="500" height="500"
+ CODEBASE="..\..\..\WINexample.out\bin\so_activex.dll">
+<!-- Full URL to a document
+ <PARAM NAME="src" VALUE="file:///d:/example.sxw">
+-->
+<!-- Just view the document, do not edit
+ <PARAM NAME="readonly" VALUE="true">
+-->
+</OBJECT>
+
+</center>
+
+</BODY>
+</HTML>
diff --git a/extensions/source/activex/main/makefile.mk b/extensions/source/activex/main/makefile.mk
new file mode 100644
index 000000000000..e4770180886c
--- /dev/null
+++ b/extensions/source/activex/main/makefile.mk
@@ -0,0 +1,155 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJNAME=extensions
+TARGET=so_activex
+
+use_shl_versions=
+
+# --- Settings ----------------------------------
+.IF "$(GUI)" == "WNT" && "$(DISABLE_ACTIVEX)"==""
+PROF_EDITION=TRUE
+.ENDIF
+
+.INCLUDE : settings.mk
+
+.IF "$(GUI)" == "WNT" && "$(DISABLE_ACTIVEX)"==""
+
+VERSIONOBJ=
+LIBTARGET=NO
+USE_DEFFILE=YES
+UWINAPILIB=
+
+.IF "$(BUILD_X64)"!=""
+USE_DEFFILE_X64=TRUE
+.ENDIF
+
+INCPRE+=$(foreach,i,$(ATL_INCLUDE) -I$(i)) \
+ -I$(MISC) \
+
+# --- Files -------------------------------------
+
+
+.IF "$(PRODUCT)"!=""
+RC+=-DPRODUCT
+.ENDIF
+
+RCFILES=\
+ $(TARGET).rc
+RCDEPN=$(MISC)$/envsettings.h
+
+SLOFILES=\
+ $(SLO)$/so_activex.obj \
+ $(SLO)$/SOActiveX.obj \
+ $(SLO)$/SOComWindowPeer.obj \
+ $(SLO)$/SODispatchInterceptor.obj \
+ $(SLO)$/SOActionsApproval.obj \
+ $(SLO)$/StdAfx2.obj
+
+SHL1TARGET=$(TARGET)
+SHL1STDLIBS=\
+ $(UUIDLIB) \
+ $(ADVAPI32LIB) \
+ $(OLE32LIB) \
+ $(OLEAUT32LIB) \
+ $(GDI32LIB) \
+ $(URLMONLIB) \
+ $(SHLWAPILIB)
+
+.IF "$(COM)"!="GCC"
+.IF "$(CCNUMVER)" > "001300000000"
+ SHL1STDLIBS+= $(ATL_LIB)$/atls.lib
+.ENDIF
+.ENDIF
+
+
+# $(KERNEL32LIB) \
+# rpcndr.lib \
+# rpcns4.lib \
+# rpcrt4.lib
+
+#$(KERNEL32LIB) rpcndr.lib rpcns4.lib rpcrt4.lib
+
+SHL1OBJS=$(SLOFILES)
+
+SHL1LIBS=
+SHL1DEF=$(TARGET).def
+SHL1RES=$(RES)$/$(TARGET).res
+
+.ENDIF
+
+.IF "$(BUILD_X64)"!=""
+# -------------------- x64 -----------------------
+
+CDEFS_X64+:=$(foreach,i,$(CDEFS) $(subst,-D_X86_=1, $i))
+LIBTARGET_X64=NO
+USE_DEFFILE_X64=YES
+UWINAPILIB_X64=
+
+SLOFILES_X64= \
+ $(SLO_X64)$/so_activex.obj \
+ $(SLO_X64)$/SOActiveX.obj \
+ $(SLO_X64)$/SOComWindowPeer.obj \
+ $(SLO_X64)$/SODispatchInterceptor.obj \
+ $(SLO_X64)$/SOActionsApproval.obj \
+ $(SLO_X64)$/StdAfx2.obj
+
+SHL1TARGET_X64=$(TARGET)
+
+SHL1STDLIBS_X64+=\
+ $(UUIDLIB_X64) \
+ $(ADVAPI32LIB_X64) \
+ $(OLE32LIB_X64) \
+ $(OLEAUT32LIB_X64) \
+ $(GDI32LIB_X64) \
+ $(URLMONLIB_X64) \
+ $(SHLWAPILIB_X64) \
+ $(KERNEL32LIB_X64) \
+ $(USER32LIB_X64) \
+ $(MSVCRT_X64) \
+ $(MSVCPRT_X64) \
+ $(OLDNAMESLIB_X64)
+
+SHL1OBJS_X64=$(SLOFILES_X64)
+SHL1DEF_X64=$(TARGET).def
+
+SHL1STDLIBS_X64+= $(ATL_LIB)$/amd64$/atls.lib
+
+.ENDIF # "$(BUILD_X64)"!=""
+
+# --- Targets ----------------------------------
+
+.INCLUDE : set_wntx64.mk
+VERSIONOBJ_X64=
+.INCLUDE : target.mk
+.INCLUDE : tg_wntx64.mk
+
+$(MISC)$/envsettings.h : makefile.mk
+ -$(RM) $@
+# it looks wrong; but rc likes it that way...
+ echo "#define MISC .\..\$(INPATH)\misc" > $@
diff --git a/extensions/source/activex/main/resource.h b/extensions/source/activex/main/resource.h
new file mode 100644
index 000000000000..fe74853c6d15
--- /dev/null
+++ b/extensions/source/activex/main/resource.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by so_activex.rc
+//
+#define IDS_PROJNAME 100
+#define IDB_SOACTIVEX 101
+#define IDR_SOACTIVEX 102
+#define IDB_SOCOMWINDOWPEER 103
+#define IDR_SOCOMWINDOWPEER 104
+#define IDB_SODISPATCHINTERCEPTOR 105
+#define IDR_SODISPATCHINTERCEPTOR 106
+#define IDB_SODOCUMENTEVENTLISTENER 107
+#define IDR_SODOCUMENTEVENTLISTENER 108
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 201
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 201
+#define _APS_NEXT_SYMED_VALUE 107
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/so_activex.cpp b/extensions/source/activex/main/so_activex.cpp
new file mode 100644
index 000000000000..43e49b6b3345
--- /dev/null
+++ b/extensions/source/activex/main/so_activex.cpp
@@ -0,0 +1,692 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// so_activex.cpp : Implementation of DLL Exports.
+
+
+// Note: Proxy/Stub Information
+// To build a separate proxy/stub DLL,
+// run nmake -f so_activexps.mk in the project directory.
+
+#include "stdio.h"
+#include "stdafx2.h"
+#include "resource.h"
+#include <initguid.h>
+#include "so_activex.h"
+
+#include "so_activex_i.c"
+#include "SOActiveX.h"
+
+#include <comphelper\documentconstants.hxx>
+
+// #define MY_DEBUG 1
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
+END_OBJECT_MAP()
+
+
+#define X64_LIB_NAME "so_activex_x64.dll"
+#define X32_LIB_NAME "so_activex.dll"
+
+// 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
+// in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
+// Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
+// extensions\source\activex\main\so_activex.cpp
+#ifndef KEY_WOW64_64KEY
+ #define KEY_WOW64_64KEY (0x0100)
+#endif
+#ifndef KEY_WOW64_32KEY
+ #define KEY_WOW64_32KEY (0x0200)
+#endif
+
+const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
+const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
+
+#ifdef _AMD64_
+const BOOL bX64 = TRUE;
+#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
+#else
+const BOOL bX64 = FALSE;
+#define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
+#endif
+
+// 10.11.2009 tkr: MinGW doesn't know anything about RegDeleteKeyExA if WINVER < 0x0502.
+extern "C" {
+WINADVAPI LONG WINAPI RegDeleteKeyExA(HKEY,LPCSTR,REGSAM,DWORD);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ _Module.Term();
+ return TRUE; // ok
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+{
+ return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+ return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllRegisterServer - Adds entries to the system registry
+
+// for now database component and chart are always installed
+#define SUPPORTED_EXT_NUM 30
+const char* aFileExt[] = { ".vor",
+ ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
+ ".stw", ".stc", ".sti", ".std",
+ ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
+ ".ott", ".otg", ".otp", ".ots", ".otf",
+ ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
+const char* aMimeType[] = {
+ "application/vnd.stardivision.writer",
+
+ "application/vnd.stardivision.chart",
+ "application/vnd.stardivision.draw",
+ "application/vnd.stardivision.impress",
+ "application/vnd.stardivision.impress-packed",
+ "application/vnd.stardivision.calc",
+ "application/vnd.stardivision.writer",
+ "application/vnd.stardivision.math",
+
+ MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII,
+ MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII,
+ MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII,
+ MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII,
+
+ MIMETYPE_VND_SUN_XML_WRITER_ASCII,
+ MIMETYPE_VND_SUN_XML_CALC_ASCII,
+ MIMETYPE_VND_SUN_XML_IMPRESS_ASCII,
+ MIMETYPE_VND_SUN_XML_DRAW_ASCII,
+ MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII,
+ MIMETYPE_VND_SUN_XML_MATH_ASCII,
+
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII,
+
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII,
+ MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII };
+
+const int nForModes[] = { 16,
+ 1, 2, 4, 4, 8, 16, 32,
+ 16, 8, 4, 2,
+ 16, 8, 4, 2, 16, 32,
+ 16, 2, 4, 8, 32,
+ 16, 16, 16, 2, 4, 8, 32 };
+
+const char* aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
+const char* aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
+
+// ISOComWindowPeer interface information
+const char* aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
+const char* aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
+
+// ISODispatchInterceptor interface information
+const char* aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
+const char* aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
+
+// ISOActionsApproval interface information
+const char* aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
+const char* aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
+
+// The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
+const char* aLocalPrefix = "Software\\Classes\\";
+
+BOOL createKey( HKEY hkey,
+ const char* aKeyToCreate,
+ REGSAM nKeyAccess,
+ const char* aValue = NULL,
+ const char* aChildName = NULL,
+ const char* aChildValue = NULL )
+{
+ HKEY hkey1;
+
+ return ( ERROR_SUCCESS == RegCreateKeyExA( hkey, aKeyToCreate, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
+ && ( !aValue || ERROR_SUCCESS == RegSetValueExA( hkey1,
+ "",
+ 0,
+ REG_SZ,
+ (const BYTE*)aValue,
+ strlen( aValue ) ) )
+ && ( !aChildName || ERROR_SUCCESS == RegSetValueExA( hkey1,
+ aChildName,
+ 0,
+ REG_SZ,
+ (const BYTE*)aChildValue,
+ strlen( aChildValue ) ) )
+ && ERROR_SUCCESS == RegCloseKey( hkey1 ) );
+
+}
+
+STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
+STDAPI DllRegisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess, const char* pProgramPath, const char* pLibName )
+{
+ BOOL aResult = FALSE;
+
+ HKEY hkey = NULL;
+ HKEY hkey1 = NULL;
+ HKEY hkey2 = NULL;
+ HKEY hkey3 = NULL;
+ HKEY hkey4 = NULL;
+ char aSubKey[513];
+ int ind;
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ char pActiveXPath[1124];
+ char pActiveXPath101[1124];
+
+
+ // In case SO7 is installed for this user he can have local registry entries that will prevent him from
+ // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
+ // Unfortunately it can be done only for the user who installs the office.
+ if ( bForAllUsers )
+ DllUnregisterServerNative( nMode, sal_False, sal_False );
+
+#ifdef MY_DEBUG
+ MessageBoxA(NULL, pProgramPath, "Library Path, ( from library )", MB_OK | MB_ICONINFORMATION);
+#endif
+
+ if ( pProgramPath && strlen( pProgramPath ) < 1024 )
+ {
+ sprintf( pActiveXPath, "%s\\%s", pProgramPath, pLibName );
+ sprintf( pActiveXPath101, "%s\\%s, 101", pProgramPath, pLibName );
+
+ {
+ wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
+ aResult =
+ ( ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
+ && ERROR_SUCCESS == RegSetValueExA( hkey, "", 0, REG_SZ, (const BYTE*)"SOActiveX Class", 17 )
+ && createKey( hkey, "Control", nKeyAccess )
+ && createKey( hkey, "EnableFullPage", nKeyAccess )
+ && createKey( hkey, "InprocServer32", nKeyAccess, pActiveXPath, "ThreadingModel", "Apartment" )
+ && createKey( hkey, "MiscStatus", nKeyAccess, "0" )
+ && createKey( hkey, "MiscStatus\\1", nKeyAccess, "131473" )
+ && createKey( hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1" )
+ && createKey( hkey, "Programmable", nKeyAccess )
+ && createKey( hkey, "ToolboxBitmap32", nKeyAccess, pActiveXPath101 )
+ && createKey( hkey, "TypeLib", nKeyAccess, aTypeLib )
+ && createKey( hkey, "Version", nKeyAccess, "1.0" )
+ && createKey( hkey, "VersionIndependentProgID", nKeyAccess, "so_activex.SOActiveX" )
+ && ERROR_SUCCESS == RegCloseKey( hkey )
+ && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aPrefix, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
+ && createKey( hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
+ && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
+ && createKey( hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1" )
+ && ERROR_SUCCESS == RegCloseKey( hkey1 )
+ && createKey( hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX.1", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
+ && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
+ && ERROR_SUCCESS == RegCloseKey( hkey1 )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey, "TypeLib", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aTypeLib, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
+ && createKey( hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey2, "1.0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey3 , NULL )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey3, "0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey4 , NULL )
+ && createKey( hkey4, "win32", nKeyAccess, pActiveXPath )
+ && ERROR_SUCCESS == RegCloseKey( hkey4 )
+ && createKey( hkey3, "FLAGS", nKeyAccess, "0" )
+ && createKey( hkey3, "HELPDIR", nKeyAccess, pProgramPath )
+ && ERROR_SUCCESS == RegCloseKey( hkey3 )
+ && ERROR_SUCCESS == RegCloseKey( hkey2 )
+ && ERROR_SUCCESS == RegCloseKey( hkey1 )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey, "Interface", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
+ && createKey( hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDWinPeer, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
+ && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer )
+ && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer )
+ && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
+ && ERROR_SUCCESS == RegCloseKey( hkey2 )
+ && createKey( hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDActApprove, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
+ && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove )
+ && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove )
+ && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
+ && ERROR_SUCCESS == RegCloseKey( hkey2 )
+ && createKey( hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor" )
+ && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDDispInt, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
+ && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt )
+ && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt )
+ && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
+ && ERROR_SUCCESS == RegCloseKey( hkey2 )
+ && ERROR_SUCCESS == RegCloseKey( hkey1 )
+ && ERROR_SUCCESS == RegCloseKey( hkey ) );
+
+ hkey = hkey1 = hkey2 = hkey3 = hkey4 = NULL;
+ }
+ }
+
+ for( ind = 0; ind < SUPPORTED_EXT_NUM && aResult; ind++ )
+ {
+ if( nForModes[ind] & nMode )
+ {
+ wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
+// || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
+// (const BYTE *)aFileExt[ind], strlen( aFileExt[ind] ) )
+ || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
+ (const BYTE *)aClassID, strlen(aClassID)) )
+ aResult = FALSE;
+
+ if( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+
+/*
+ wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
+ || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
+ (const BYTE *)aMimeType[ind], strlen( aMimeType[ind] ) ) )
+ aResult = FALSE;
+ if( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+*/
+ }
+ }
+
+ wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
+ if ( aResult && ERROR_SUCCESS == RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, nKeyAccess, &hkey) )
+ {
+ for( ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
+ {
+ wsprintfA( aSubKey, "EnableFullPage\\%s", aFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
+ aResult = FALSE;
+
+ if ( hkey1 )
+ RegCloseKey(hkey1),hkey1= NULL;
+ }
+ }
+ else
+ aResult = FALSE;
+
+ if ( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+
+ return aResult;
+}
+
+STDAPI DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const char* pProgramPath )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
+
+ return hr;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServer - Removes entries from the system registry
+HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
+{
+ HKEY hkey1 = NULL;
+
+ char pSubKeyName[256];
+ // first delete the subkeys
+ while( ERROR_SUCCESS == RegOpenKeyExA( hkey, pPath, 0, nKeyAccess, &hkey1)
+ && ERROR_SUCCESS == RegEnumKeyA( hkey1, 0, pSubKeyName, 256 )
+ && ERROR_SUCCESS == DeleteKeyTree( hkey1, pSubKeyName, nKeyAccess ) )
+ {
+ RegCloseKey( hkey1 ),hkey1= NULL;
+ }
+
+ if ( hkey1 )
+ RegCloseKey( hkey1 ),hkey1= NULL;
+
+ // delete the key itself
+ return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
+}
+
+STDAPI DllUnregisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
+{
+ HKEY hkey = NULL;
+ BOOL fErr = FALSE;
+ char aSubKey[513];
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
+ {
+ if( nForModes[ind] & nMode )
+ {
+ DWORD nSubKeys = 0, nValues = 0;
+ wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
+ fErr = TRUE;
+ else
+ {
+ if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
+ fErr = TRUE;
+
+ if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
+ &nSubKeys, NULL, NULL,
+ &nValues, NULL, NULL, NULL, NULL ) )
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ fErr = TRUE;
+ }
+ else
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ if ( !nSubKeys && !nValues )
+ DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
+ }
+ }
+
+ wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
+ fErr = TRUE;
+ else
+ {
+ if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
+ &nSubKeys, NULL, NULL,
+ &nValues, NULL, NULL, NULL, NULL ) )
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ fErr = TRUE;
+ }
+ else
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ if ( !nSubKeys && !nValues )
+ DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
+ }
+ }
+ }
+ }
+
+ wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%sso_activex.SOActiveX", aPrefix );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%sso_activex.SOActiveX.1", aPrefix );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove );
+ if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
+ fErr = TRUE;
+
+ return !fErr;
+}
+
+STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
+ if ( SUCCEEDED( hr ) && bFor64Bit )
+ hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ return hr;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// DllRegisterServerDoc - Adds entries to the system registry
+
+#define SUPPORTED_MSEXT_NUM 7
+const char* aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
+const char* aMSMimeType[] = { "application/msword",
+ "application/msword",
+ "application/msexcell",
+ "application/msexcell",
+ "application/mspowerpoint",
+ "application/mspowerpoint",
+ "application/mspowerpoint" };
+const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
+
+STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
+STDAPI DllRegisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
+{
+ BOOL aResult = TRUE;
+
+ HKEY hkey = NULL;
+ HKEY hkey1 = NULL;
+ char aSubKey[513];
+ int ind;
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ // In case SO7 is installed for this user he can have local registry entries that will prevent him from
+ // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
+ // Unfortunately it can be done only for the user who installs the office.
+ if ( bForAllUsers )
+ DllUnregisterServerDoc( nMode, sal_False, sal_False );
+
+ for( ind = 0; ind < SUPPORTED_MSEXT_NUM && aResult; ind++ )
+ {
+ if( nForMSModes[ind] & nMode )
+ {
+ wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
+ || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
+ (const BYTE *)aMSFileExt[ind], strlen( aMSFileExt[ind] ) )
+ || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
+ (const BYTE *)aClassID, strlen(aClassID)) )
+ aResult = FALSE;
+
+ if( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+
+ wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
+ || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
+ (const BYTE *)aMSMimeType[ind], strlen( aMSMimeType[ind] ) ) )
+ aResult = FALSE;
+
+ if( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+ }
+ }
+
+ wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
+ if ( aResult && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
+ && createKey( hkey, "EnableFullPage", nKeyAccess ) )
+ {
+ for( ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
+ {
+ if( nForMSModes[ind] & nMode )
+ {
+ wsprintfA( aSubKey, "EnableFullPage\\%s", aMSFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
+ aResult = FALSE;
+
+ if ( hkey1 )
+ RegCloseKey(hkey1),hkey1= NULL;
+ }
+ }
+ }
+ else
+ aResult = FALSE;
+
+ if ( hkey )
+ RegCloseKey(hkey),hkey= NULL;
+
+ return aResult;
+}
+
+STDAPI DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
+
+ return hr;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServerDoc - Removes entries from the system registry
+
+STDAPI DllUnregisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
+{
+ HKEY hkey = NULL;
+ BOOL fErr = FALSE;
+ char aSubKey[513];
+ const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
+
+ for( int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
+ {
+ if( nForMSModes[ind] & nMode )
+ {
+ DWORD nSubKeys = 0, nValues = 0;
+
+ wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
+ fErr = TRUE;
+ else
+ {
+ if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Extension" ) )
+ fErr = TRUE;
+
+ if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
+ fErr = TRUE;
+
+ if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
+ &nSubKeys, NULL, NULL,
+ &nValues, NULL, NULL, NULL, NULL ) )
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ fErr = TRUE;
+ }
+ else
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ if ( !nSubKeys && !nValues )
+ DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
+ }
+ }
+
+ wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
+ if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
+ fErr = TRUE;
+ else
+ {
+ if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Content Type" ) )
+ fErr = TRUE;
+
+ if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
+ &nSubKeys, NULL, NULL,
+ &nValues, NULL, NULL, NULL, NULL ) )
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ fErr = TRUE;
+ }
+ else
+ {
+ RegCloseKey( hkey ), hkey = NULL;
+ if ( !nSubKeys && !nValues )
+ DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
+ }
+ }
+ }
+ }
+
+ return !fErr;
+}
+
+STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
+{
+ HRESULT hr = S_OK;
+ if ( bFor64Bit )
+ hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
+
+ if ( SUCCEEDED( hr ) )
+ hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
+
+ return hr;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllRegisterServer - regsvr32 entry point
+
+STDAPI DllRegisterServer( void )
+{
+ char pProgramPath[1024];
+ HRESULT aResult = E_FAIL;
+
+ HMODULE aCurModule = GetModuleHandleA( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
+ DWORD nLen = 0;
+ DWORD nLibNameLen = strlen( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
+
+ if( aCurModule )
+ {
+ nLen = GetModuleFileNameA( aCurModule, pProgramPath, 1024 );
+ if ( nLen && nLen > nLibNameLen + 1 )
+ {
+ pProgramPath[ nLen - nLibNameLen - 1 ] = 0;
+ aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
+ if( SUCCEEDED( aResult ) )
+ aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
+ else
+ {
+ aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
+ if( SUCCEEDED( aResult ) )
+ aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
+ }
+ }
+ }
+
+ return aResult;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServer - regsvr32 entry point
+
+STDAPI DllUnregisterServer( void )
+{
+ DllUnregisterServerDoc( 63, FALSE, bX64 );
+ DllUnregisterServerNative( 63, FALSE, bX64 );
+ DllUnregisterServerDoc( 63, TRUE, bX64 );
+ return DllUnregisterServerNative( 63, TRUE, bX64 );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/extensions/source/activex/main/so_activex.def b/extensions/source/activex/main/so_activex.def
new file mode 100644
index 000000000000..e3d56b070dad
--- /dev/null
+++ b/extensions/source/activex/main/so_activex.def
@@ -0,0 +1,13 @@
+; iervp.def : Declares the module parameters.
+
+LIBRARY "so_activex.dll"
+
+EXPORTS
+ DllCanUnloadNow @1 PRIVATE
+ DllGetClassObject @2 PRIVATE
+ DllRegisterServer @3 PRIVATE
+ DllUnregisterServer @4 PRIVATE
+ DllRegisterServerNative @5 PRIVATE
+ DllRegisterServerDoc @6 PRIVATE
+ DllUnregisterServerNative @7 PRIVATE
+ DllUnregisterServerDoc @8 PRIVATE
diff --git a/extensions/source/activex/main/so_activex.rc b/extensions/source/activex/main/so_activex.rc
new file mode 100644
index 000000000000..2370a5162187
--- /dev/null
+++ b/extensions/source/activex/main/so_activex.rc
@@ -0,0 +1,113 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#if defined(_MSC_VER) && (_MSC_VER < 1500)
+#include "winres.h"
+#else
+#define WINVER 0x0500
+#include <winresrc.h>
+#define LB_ADDSTRING (WM_USER+1)
+#define CB_ADDSTRING (WM_USER+3)
+#define IDC_STATIC (-1)
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Russian resources
+
+//#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
+//#ifdef _WIN32
+//LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+//#pragma code_page(1251)
+//#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+//IDB_SOACTIVEX BITMAP DISCARDABLE "soacti.bmp"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REGISTRY
+//
+
+IDR_SOACTIVEX REGISTRY DISCARDABLE "SOActiveX.rgs"
+IDR_SOCOMWINDOWPEER REGISTRY DISCARDABLE "SOComWindowPeer.rgs"
+IDR_SODISPATCHINTERCEPTOR REGISTRY DISCARDABLE "SODispatchInterceptor.rgs"
+//#endif // Russian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "1 TYPELIB ""so_activex.tlb""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_PROJNAME "so_activex"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+#include "envsettings.h"
+
+1 TYPELIB MISC\so_activex.tlb
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+