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

Java, C++, C#, Delphi, ??? - Using the UNO bridges

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

Postby mangesh » Fri Feb 08, 2013 3:23 pm

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   Expand viewCollapse view
            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   Expand viewCollapse view
           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.
mangesh
 
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am

Re: Calling OOBasic macro from external C++ application

Postby Charlie Young » Fri Feb 08, 2013 8:42 pm

The dispatcher syntax for executing a macro looks like

Code: Select all   Expand viewCollapse view
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
Charlie Young
Volunteer
 
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Calling OOBasic macro from external C++ application

Postby Villeroy » Fri Feb 08, 2013 10:34 pm

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, no OpenOffice, LibreOffice 6.4
User avatar
Villeroy
Volunteer
 
Posts: 28431
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Calling OOBasic macro from external C++ application

Postby Charlie Young » Fri Feb 08, 2013 11:14 pm

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   Expand viewCollapse view
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   Expand viewCollapse view
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   Expand viewCollapse view
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
User avatar
Charlie Young
Volunteer
 
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Calling OOBasic macro from external C++ application

Postby mangesh » Sat Feb 09, 2013 11:09 am

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.
mangesh
 
Posts: 26
Joined: Tue Aug 21, 2012 10:48 am


Return to External Programs

Who is online

Users browsing this forum: No registered users and 1 guest