[Solved] Calling OOBasic macro from external C++ application

Java, C++, C#, Delphi... - Using the UNO bridges
Post Reply
mangesh
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

[Solved] Calling OOBasic macro from external C++ application

Post by mangesh »

Hi,
I created a "Test" SUB/macro using the OOBasic IDE in OOoCalc. I created the Sub in a new library "MyOOolib" inside "Module1". When called it will show a dialog "hello World" . I now wish to call it from an external application. I wrote the following code in my external application to invoke the script from my application

Approach 1:

Code: Select all

            rComponentContext = defaultBootstrap_InitialComponentContext();
            Reference< XMultiComponentFactory > xMultiComponentFactoryClient = rComponentContext->getServiceManager();
            

            // Get the rOfficeServiceManager using ooConnect() from the SdK samples.

            // Query the XDispatcher Interface
            Reference< XDispatchHelper > rDispatchHelper = Reference< XDispatchHelper > ( rOfficeServiceManager->createInstance(
                                                                                          OUString( RTL_CONSTASCII_USTRINGPARAM(
                                                                                          "com.sun.star.frame.DispatchHelper" ))), UNO_QUERY );

            // Query the XDispatchProvider Interface
            Reference< XDispatchProvider > rDispatchProvider(rDesktop,UNO_QUERY);
        
            rDispatchHelper->executeDispatch(rDispatchProvider, 
                                         OUString::createFromAscii("vnd.sun.star.script:MyOOoLib.Module1.Test?language=Basic&location=document"),
                                         OUString::createFromAscii(""),
                                         0,
                                         Sequence < ::com::sun::star::beans::PropertyValue > ());
Using this approach , nothing happens at the end of the rDispatchHelper->executeDispatch() call. I am not sure whats wrong.

Second approach:
In the second approach I use the XScriptProviderFactory to invoke the script.

Code: Select all

           Reference< XScriptProvider > xScriptProvider;

            Reference< XScriptProviderFactory > xFactory(rComponentContext->getValueByName(
                          ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory" ) ), 
                          UNO_QUERY );

            if ( xFactory.is() )
            {
                Any aCtx;
                aCtx <<= ::rtl::OUString::createFromAscii( "user" );  // I am not sure if this correct.
                xScriptProvider.set( xFactory->createScriptProvider( aCtx ), UNO_QUERY );               
            }

            if ( !xScriptProvider.is() )
            {
                printf("ExecuteOOoBasicCommand() Failed to create msp");
                return 1;
            }
            
            Sequence< Any > inArgs( 0 );
            Sequence< Any > outArgs( 0 );
            Sequence< sal_Int16 > outIndex;



            Reference< XScript > xScript = xScriptProvider->getScript(::rtl::OUString::createFromAscii
                        ( "vnd.sun.star.script:MyOOoLib.Module1.Test?language=Basic&location=application" ));

            if ( !xScript.is() )
            {
                printf("ExecuteOOoBasicCommand() Failed to obtain XScript");
                return 1;
            }

            Any result = xScript->invoke( inArgs, outIndex, outArgs );
With this approach, I am not able to get the reference to the XScriptProviderFactory. So the script cannot be invoked.

I am not sure which is the right approach.
I am looking for some help to get this sorted.
Thanks
Mangesh
Last edited by mangesh on Sat Feb 09, 2013 11:09 am, edited 1 time in total.
OpenOffice3.4.0 Win7 x64.
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Calling OOBasic macro from external C++ application

Post by Charlie Young »

The dispatcher syntax for executing a macro looks like

Code: Select all

rDispatchHelper->executeDispatch(rDispatchProvider,
			OUString::createFromAscii("macro://DocumentName/MyOOoLib.Module1.Test"),
			OUString::createFromAscii(""),
			0,
			Sequence < ::com::sun::star::beans::PropertyValue > ());

Where "DocumentName" is entered without the extension.

I generally prefer the ScriptProvider approach, and I hope to have a working example for this case shortly, but from your post it looks like you are trying to execute a macro at the application level, whereas you originally indicated that the macro was in the document. I'm a bit confused.
Apache OpenOffice 4.1.1
Windows XP
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Calling OOBasic macro from external C++ application

Post by Villeroy »

Create uno service "com.sun.star.script.provider.MasterScriptProviderFactory"
Call method .createScriptProvider("") from that master service.
From that script provide you can call .getScript("vnd.sun.star.script:blah...")
The script has an .invoke method.

http://www.openoffice.org/api/docs/comm ... vider.html
http://www.openoffice.org/api/docs/comm ... vider.html
http://www.openoffice.org/api/docs/comm ... cript.html
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Calling OOBasic macro from external C++ application

Post by Charlie Young »

I see Villeroy has chimed in, and he certainly knows what he is talking about, but since I have examples now I'll post them as well.

If your macro is in the document, you don't need the MasterScriptProviderFactory, it's just

Code: Select all

Reference<XScriptProviderSupplier> xSupplier(ThisComponent,UNO_QUERY);
Reference<XScriptProvider> xProvider = xSupplier->getScriptProvider();
Reference<XScript> xScript = xProvider->getScript(OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:MyOOoLib.Module1.Test?language=Basic&location=document")));
xScript->invoke(inArgs,outIndex,outArgs);
ThisComponent is the Reference<XComponent> to the document, the Reference< XSpreadsheetDocument > or whatever will also work.

I'm not sure what you're trying to do with the singleton (I'll look at that), but if the macro in My Macros, I get a MasterScriptProvider with the ServiceManager (essentially createUnoService), and yes, aCtx should be a null string.

Code: Select all

Any aCtx;
aCtx <<= OUString();
Reference <XInterface> iFactory = rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                        "com.sun.star.script.provider.MasterScriptProviderFactory" )));

Reference< XScriptProviderFactory > xFactory(iFactory, UNO_QUERY );
Reference<XScriptProvider> xProvider = xFactory->createScriptProvider(aCtx);
Reference<XScript> xScript = xProvider->getScript(OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:Standard.Module1.Test?language=Basic&location=application")));
xScript->invoke(inArgs,outIndex,outArgs);
The reference to "user" comes in if you want to get Python or JavaScript from My Macros, for example

Code: Select all

Reference<XScript> xScript = xProvider->getScript(OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:Test.py$Test?language=Python&location=user")));
 Edit: The singleton business works for me just fine, so aCtx is probably your problem. 
Apache OpenOffice 4.1.1
Windows XP
mangesh
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

Re: Calling OOBasic macro from external C++ application

Post by mangesh »

Hi Charlie, Hi Villeroy,
Thanks for the quick response. It cleared a lot of doubts for me. First of all, I am writing an application level macro. So I took the second approach of using the ScriptProvider rather than using the Dispatch framework. The "/singletons" string does not work for me. I picked it from http://ooo.googlecode.com/svn-history/r ... entatt.cxx example.

But rest of the changes work for me as suggested in the last post from Charlie.

Thanks a bunch,
Mangesh
OpenOffice3.4.0 Win7 x64.
Post Reply