Executing an OOoBasic macro with Cpp
A first example
Our goal is to execute an OOoBasic sub. We start with a Danny's interesting post apply macro from differents files : In the macros of OOo and module “Essai1” I put this sub :
'Listing 40 Our OOoBasic Sub REM ***** BASIC ***** Sub SaySomething( ) MsgBox "Hello from OOoBasic" End Sub
The OOoBasic code to only execute this sub would be :
'Listing 41 OOoBasic Code to execute the Sub REM ***** BASIC ***** Sub Main oDispatch = createUnoService( "com.sun.star.frame.DispatchHelper" ) oDispatch.executeDispatch( StarDesktop, "macro:///Standard.Essai1.SaySomething()", "", 0, Array() ) End Sub
Bear in mind we can call this sub directly by its name in OOoBasic but not in C++. Translating this code in C++ is easy : we give again the complete main listing using com.sun.star.frame.XDispatchHelper and com.sun.star.frame.XDispatchProvider interfaces and com.sun.star.frame.DispatchHelper service :
//Listing 42 Calling a OOoBasic Sub in C++ // C++ int main( ) { //retrieve an instance of the remote service manager Reference< XMultiServiceFactory > rOfficeServiceManager; rOfficeServiceManager = ooConnect(); if( rOfficeServiceManager.is() ){ printf( "Connected sucessfully to the office\n" ); } //get the desktop service using createInstance returns an XInterface type Reference< XInterface > Desktop = rOfficeServiceManager->createInstance( OUString::createFromAscii( "com.sun.star.frame.Desktop" )); //query for the XComponentLoader interface Reference< XComponentLoader > rComponentLoader (Desktop, UNO_QUERY); if( rComponentLoader.is() ){ printf( "XComponentloader successfully instanciated\n" ); } Reference< XDesktop > rDesktop(Desktop,UNO_QUERY); // Don't forget to add : #include <com/sun/star/frame/XDispatchHelper.hpp> // Don't forget to add "com.sun.star.frame.XDispatchHelper \" in the makefile // Query the XDispatcher Interface Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper > ( rOfficeServiceManager->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY ); // Don't forget to add : #include <com/sun/star/frame/XDispatchProvider.hpp> // Don't forget to add "com.sun.star.frame.XDispatchProvider \" in the makefile // Query the XDispatchProvider Interface Reference< XDispatchProvider > rDispatchProvider(rDesktop,UNO_QUERY); Any any=rDispatchHelper->executeDispatch(rDispatchProvider, OUString::createFromAscii("macro:///Standard.Essai1.SaySomething()"), OUString::createFromAscii(""), 0, Sequence < ::com::sun::star::beans::PropertyValue > ()); return 0; }
which prints out a message box with “Hello from OOoBasic” but return an error. This error is only because the program when terminating try to destruct the objects variable while OOoBasic is still running ! We have a completely asynchronous process.
XRay and C++
XRay (see Constructing Component) is a OOoBasic inspection tool. As in the previous example, we can naturally call the XRay tool from C++. Here is explained how to do that. First Write a OOoBasic sub :
'Listing 43 New OOoBasic sub to call REM ***** BASIC ***** Sub BernardXRay( x ) oBJ = createUnoService(x) XRAY.XRAY oBJ End Sub
in the module “Essai1”, and second write for instance :
//Listing 44 The C++ call // C++ ... Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper > ( rOfficeServiceManager->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY ); ... Any any=rDispatchHelper->executeDispatch(rDispatchProvider, OUString::createFromAscii( "macro:///Standard.Essai1.BernardXRay(com.sun.star.frame.DispatchHelper)"), OUString::createFromAscii(""), 0, Sequence < ::com::sun::star::beans::PropertyValue > ());
The way of doing that is very inefficient as an object explorer. The tie between C++ and OOoBasic is too weak. There is no tie between the C++ variable rDispatchHelper and the oBJ OOoBasic variable. One could be NULL and the second not. Other ways are presented in next chapter.
Going further
Note that Christian Junker has writen an example with the new OOo2.0 interface. This example allow returning value from OOoBasic, see : How to call macro along with getting its return value (C++)
See also
- C++ and UNO tutorial
- Bernard Marcelly's XRay tool description in this wiki.