Executing an OOoBasic macro with Cpp

From Apache OpenOffice Wiki
Jump to: navigation, search

Edit-find-replace.png This article needs to be checked for accuracy and style.

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

Personal tools