FR/Documentation/Utilitaires C++

From Apache OpenOffice Wiki
Jump to: navigation, search

Jouer avec les fenêtres du toolkit

Explications de Danny Brewer

Il y a deux choses différentes ici. En réalité il y en a trois.

1. Les dialogues

2. AWT

3. Les formes

Les formes sont d'un plus haut niveau que les deux autres.

  • Sur les deux premiers, les dialogues utilisent le UnoDialogControl et ses modèles. Vous pouvez aussi créer des fenêtres AWT avec les commandes.
  • Les fenêtres AWT peuvent être modales ou non, et ne sont pas attachées à d'autres fenêtres.
  • Les fenêtres AWT ne sont pas comme les dialogues.

Généralement, les dialogues sont réalisés de façon modale en appelant la méthode execute() du dialogue. J'ai réussi à réaliser des boites de dialogue non modales.

Les fenêtres MessageBox

Le code initial est en gros le même que le précédent (examples/DevelopersGuide/ProfUNO/CppBinding/). Nous examinons aussi l'exemple de “<OpenOffice.org1.1_SDK>/examples/DevelopersGuide/Components/Addons/ProtocolHandlerAddon_cpp” où nous trouvons une fenêtre MessageBox. Le code correspondant est donné ici :

//Listing 1
// C++
// N'oubliez pas d'ajouter : #include <com/sun/star/awt/WindowDescriptor.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.WindowDescriptor \" dans le makefile
// N'oubliez pas d'ajouter : #include <com/sun/star/awt/WindowAttribute.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.WindowAttribute \" dans le makefile
// N'oubliez pas d'ajouter : #include <com/sun/star/awt/XWindowPeer.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.XWindowPeer \" dans le makefile
// N'oubliez pas d'ajouter : #include <com/sun/star/awt/XMessageBox.hpp>
// N'oubliez pas d'ajouter "com.sun.star.awt.XMessageBox \" dans le makefile
 
/**
  * Show a message box with the UNO based toolkit
  */
static void ShowMessageBox( const Reference< XToolkit >& rToolkit, const Reference< XFrame >& rFrame, const OUString& aTitle, const OUString& aMsgText )
{
    if ( rFrame.is() && rToolkit.is() )
    {
        // describe window properties.
        WindowDescriptor                aDescriptor;
        aDescriptor.Type              = WindowClass_MODALTOP;
        aDescriptor.WindowServiceName = OUString( RTL_CONSTASCII_USTRINGPARAM( "infobox" ));
        aDescriptor.ParentIndex       = -1;
        aDescriptor.Parent            = Reference< XWindowPeer >( rFrame->getContainerWindow(), UNO_QUERY );
        aDescriptor.Bounds            = Rectangle(0,0,300,200);
        aDescriptor.WindowAttributes  = WindowAttribute::BORDER | WindowAttribute::MOVEABLE | WindowAttribute::CLOSEABLE;
 
        Reference< XWindowPeer > xPeer = rToolkit->createWindow( aDescriptor );
        if ( xPeer.is() )
        {
            Reference< XMessageBox > xMsgBox( xPeer, UNO_QUERY );
            if ( xMsgBox.is() )
            {
                xMsgBox->setCaptionText( aTitle );
                xMsgBox->setMessageText( aMsgText );
                xMsgBox->execute();
            }
        }
    }
}

pour comprendre le WindowAttribute::BORDER et les autres constantes, jetons un oeil au fichier IDL “WindowAttribute.idl” décrivant les attributs de fenêtres :

//Listing 2
// IDL
module com {  module sun {  module star {  module awt {
constants WindowAttribute
{
	const long SHOW = 1; 
	const long FULLSIZE = 2; 
	const long OPTIMUMSIZE = 4; 
	const long MINSIZE = 8; 
	const long BORDER = 16; 
	const long SIZEABLE = 32; 
	const long MOVEABLE = 64; 
	const long CLOSEABLE = 128; 
	const long SYSTEMDEPENDENT = 256;  
};
}; }; }; };

Nous donnons maintenant le listing d'un programme principal complet pour nous apprendre à utiliser cette procédure :

//Listing 3
//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" );
    	}
 
// Don't forget to add : #include <com/sun/star/awt/XToolkit.hpp>
// Don't forget to add "com.sun.star.awt.XToolkit \" in the makefile
// Query the XTollkit Interface
	Reference< XToolkit >rToolkit = Reference< XToolkit >( rOfficeServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
 
	if (rToolkit.is()) {
	  printf ("OK...\n");
	} else printf("Toolkit Error\n");
 
	Reference< XDesktop > rDesktop(Desktop,UNO_QUERY);
	Reference< XFrame > rFrame=rDesktop->getCurrentFrame();
	if (rFrame.is()) printf("rFrame ... OK\n"); else printf("rFrame Error\n");
 
	ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Hello") ,
				OUString::createFromAscii("Your First Message\n OK ?")  );
 
    return 0;
}

Nous pouvons tirer trois choses importantes de ce code :

  • la manière que nous pouvons utiliser un tel fichier IDL (donné au-dessus) avec C++: ce n'est pas la première fois que nous rencontrons ce genre de fichier IDL,
  • la manière dont on peut accéder à une interface à travers un service avec createInstance et UNO_QUERY simultanément (voir comment nous obtenons rToolkit)
  • nous voyons aussi comment nous obtenons une fenêtre.

La boîte de dialogue d'obtention d'un fichier : « file picker dialog »

Nous voulons fournir une boîte de dialogue pour chercher un fichier par exploration et qui rende le nom du fichier choisi. Nous commençons par partir d'un exemple du livre de Bernard Marcelly. Quand nous travaillons avec la boîte de dialogue d'obtention d'un fichier, nous devons nous intéresser à trois fichiers IDL. Voici le premier :

//Listing 4 Le fichier XexecutableDialog.idl
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XFilePicker: com::sun::star::ui::dialogs::XExecutableDialog
{
	void setMultiSelectionMode( [in] boolean bMode );
	void setDefaultName( [in] string aName );
	void setDisplayDirectory( [in] string aDirectory )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	string getDisplayDirectory();
	sequence< string > getFiles();
};
}; }; }; }; };

Le début de ce fichier indique que nous nous inquiétons avec l'XExecutableDialog aussi :

//Listing 5 Le fichier XexecutableDialog.idl
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XExecutableDialog: com::sun::star::uno::XInterface
{
	void setTitle( [in] string aTitle );
	short execute();
};
}; }; }; }; };

et ce qui est plus difficile à voir et qui nous intéresses est un fichier définissant deux constantes :

//Listing 6 Le fichier ExecutableDialogResult
// IDL
module com { module sun { module star { module ui { module dialogs {
constants ExecutableDialogResults
{
	const short CANCEL = 0;
	const short OK     = 1;
};
}; }; }; }; };

La façon de faire peut être expliquée comme suit. Vous devez en premier obtenir une Interface XFilePicker. Après nous utilisons un setDisplayDirectory pour un exemple, ensuite nous exécutons la boîte du dialogue et finalement nous obtenons le premier des dossiers choisis. Voici le code correspondant :

//Listing 7
// LINUX C++ (Only the file path is LINUX-like)
// based on Bernard Marcelly's  Example (Book p512)
// Don't forget #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
				OUString::createFromAscii("/home/smoutou/"),sDocUrl);
 
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/XFilePicker \" in the makefile
// Query the XFilePicker interface
 
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                          OUString( RTL_CONSTASCII_USTRINGPARAM(
                          "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
	short result=rFilePicker->execute();
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

C'est possible de modifier le filtre nommé avec le XFilterManager. Voici le fichier IDL correspondant :

//Listing 8 Le fichier XfilterManager.idl
// IDL
module com { module sun { module star { module ui { module dialogs {
interface XFilterManager: com::sun::star::uno::XInterface
{
	void appendFilter( [in] string aTitle, [in] string aFilter )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	void setCurrentFilter( [in] string aTitle )
		raises( ::com::sun::star::lang::IllegalArgumentException );
	string getCurrentFilter( );
};
}; }; }; }; };

Et maintenant voici un exemple en C++ qui utilise cette interface :

// Listing 9
// LINUX C++
// N'oubliez pas #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/XFilePicker \" in the makefile
//	Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY);
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
                                 "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/XFilterManager \" in the makefile
	Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY);
	rFilterManager->appendFilter(OUString::createFromAscii("Texts"),
					OUString::createFromAscii("*.txt"));
	rFilterManager->appendFilter(OUString::createFromAscii("Docs OpenOffice"),
					OUString::createFromAscii("*.sxw;*.sxc"));
	rFilterManager->setCurrentFilter(OUString::createFromAscii("Docs OpenOffice"));
	short result=rFilePicker->execute();
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

Il est temps de montrer comment faire une sauvegarde avec une boîte de Dialogue.

Boîte de dialogue d'enregistrement

Nous partons encore d'un exemple de Bernard Marcelly. Notre problème est de traduire ces lignes OOoBasic :

'Listing 10
REM  *****  BASIC  *****
FP=CreateUnoService("com.sun.star.ui.dialogs.FilePicker")
Dim FPtype(0) As Integer
FPtype(0)=com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_SIMPLE
With FP
	.initialize(FPtype())
....
End With

en particulier celles du début.

Nous cherchons d'abord les constantes qui permettent de transformer la boîte de dialogue précédente. Elles sont définies dans le fichier TemplateDescription.idl  :

//Listing 11 Le fichier TemplateDescription.idl
// IDL
module com { module sun { module star { module ui { module dialogs {
constants TemplateDescription
{
	const short FILEOPEN_SIMPLE                                = 0;
	const short FILESAVE_SIMPLE                                = 1;
	const short FILESAVE_AUTOEXTENSION_PASSWORD                = 2;
	const short FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS  = 3;
	const short FILESAVE_AUTOEXTENSION_SELECTION               = 4;
	const short FILESAVE_AUTOEXTENSION_TEMPLATE                = 5;
	const short FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE           = 6;
	const short FILEOPEN_PLAY                                  = 7;
	const short FILEOPEN_READONLY_VERSION                      = 8;
	const short FILEOPEN_LINK_PREVIEW		           = 9;
	const short FILESAVE_AUTOEXTENSION	               = 10;
};
}; }; }; }; };

Pour initialiser nous cherchons dans le fichier FilePicker.idl :

//Listing 12 Description du service FilePicker
module com { module sun { module star { module ui { module dialogs {
interface XFilePicker;
interface XFilePickerNotifier;
interface XFilePickerControlAccess;
interface XFilterManager;
interface XFilePreview;
interface XFilterGroupManager;
 
service FilePicker
{
	[optional, property] string HelpURL;
	interface XFilePicker;
	interface XFilePickerNotifier;
	interface XFilterManager;
	[optional] interface XFilePreview;
	[optional] interface XFilePickerControlAccess;
	[optional] interface XFilterGroupManager;
	[optional] interface com::sun::star::lang::XInitialization;
	[optional] interface com::sun::star::util::XCancellable;
	interface com::sun::star::lang::XComponent;
	interface com::sun::star::lang::XServiceInfo;
	interface com::sun::star::lang::XTypeProvider;
};
}; }; }; }; };

où vous voyez une interface XInitialization. Nous donnons ensuite le fichier XInitialization.idl :

//Listing 13
module com {  module sun {  module star {  module lang {
interface XInitialization: com::sun::star::uno::XInterface
{ 
	void initialize( [in] sequence<any> aArguments ) 
			raises( com::sun::star::uno::Exception ); 
 
}; 
}; }; }; };

C'est bien, nous l'avons. Nous voyons que nous devons passer une séquence à la procédure d'initialisation. Il est temps d'écrire le code correspondant.

//Listing 14
	// LINUX C++
	// inspired by Bernard Marcelly's Example p515
// N'oubliez pas #include <osl/file.hxx>
	OUString sDocUrl;
	osl::FileBase::getFileURLFromSystemPath(
						OUString::createFromAscii("/home/smoutou/"),sDocUrl);
// N'oubliez pas d'ajouter : using namespace com::sun::star::ui::dialogs;
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilePicker.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/XFilePicker \" in the makefile
//	Reference< XFilePicker > rFilePicker(rDesktop,UNO_QUERY);
	Reference< XFilePicker > rFilePicker = Reference< XFilePicker >
					( rOfficeServiceManager->createInstance(
                               OUString( RTL_CONSTASCII_USTRINGPARAM(
                               "com.sun.star.ui.dialogs.FilePicker" ))), UNO_QUERY );
 
	rFilePicker->setDisplayDirectory( sDocUrl);
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.XFilterManager \" in the makefile
	Reference< XFilterManager > rFilterManager (rFilePicker, UNO_QUERY);
 
// N'oubliez pas d'ajouter : #include <com/sun/star/lang/XInitialization.hpp>
// N'oubliez pas d'ajouter "com.sun.star.lang.XInitialization \" in the makefile
	Reference< XInitialization > rInitialize (rFilePicker, UNO_QUERY);
	Sequence < Any > info(1);
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs.TemplateDescription \" in the makefile
	info[0] <<=  (short) TemplateDescription::FILESAVE_SIMPLE;
	rInitialize-> initialize(info);
 
	rFilterManager->appendFilter(OUString::createFromAscii("Texts"),
					OUString::createFromAscii("*.txt"));
	rFilterManager->appendFilter(OUString::createFromAscii("Docs OpenOffice"),
					OUString::createFromAscii("*.sxw;*.sxc"));
	rFilterManager->setCurrentFilter(OUString::createFromAscii("Docs OpenOffice"));
	short result=rFilePicker->execute();
 
// N'oubliez pas d'ajouter : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
// N'oubliez pas d'ajouter "com.sun.star.ui.dialogs/ExecutableDialogResults \" in the makefile
	if (result == ExecutableDialogResults::OK)
	  ShowMessageBox( rToolkit, rFrame,OUString::createFromAscii("Result") ,
			rFilePicker->getFiles()[0]  );

Nous sommes intéressés maintenant par la généralisation de tout ceci à une boîte de dialogue générale.

Boite de dialogue à l'exécution

Lire aussi le Developer's Guide.

Après les exemples précédents inspirés par le livre de Bernard Marcelly sur la programmation OOoBasic, il est grand temps de présenter un exemple qui s'inspire du livre d'Andrew Pitonyak. OOoBasic est particulièrement difficile à traduire dans cette situation. On choisit alors de s'inspirer d'un exemple Java dans le répertoire : <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs et le fichier SampleDialog.java correspondant.

Pour cet exemple nous utilisons l'aide de GAP donné ici. Nous reprenons maintenant le code complet :

//Listing 17 Our first Run Time Dialog Box
// C++ (GAP example)
#include "SimpleOOConnection.cpp"
...
// First an event listener for the Button
// Don't forget the #include <cppuhelper/implbase1.hxx>
typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper;
/** action listener
*/
class ActionListenerImpl : public ActionListenerHelper
{
private :
	int _nCounts;
	Reference< XControlContainer > _xControlCont;
	//XControlContainer _xControlCont;
 
public :
ActionListenerImpl(const Reference< XControlContainer >& xControlCont) {
	_xControlCont = xControlCont;
	_nCounts = 0;
}
 
// XEventListener
virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj )
                                            throw(::com::sun::star::uno::RuntimeException) {
//	_xControlCont = NULL;
	cout << "object listened to will be disposed"<<endl;
}
 
// XActionListener
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) 
                                                                   throw ( RuntimeException) {
// increase click counter
	_nCounts++;
	cout << "OK : " << _nCounts << endl;
 }
};
 
int main()
{
SimpleOOConnection sOOConnection1;
 
//instantiating connection to Remote Service Manager
	Reference< XMultiServiceFactory > xRemoteServiceManager=sOOConnection1.connect_ooffice
		("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
//checks whether getting Remote Service Manager or Not
	if(!xRemoteServiceManager.is())
	{
	cout<<"Error in connection"<<endl;
	return 1;
	}
 
// setting Desktop reference to desktop
	Reference< XInterface > desktop =xRemoteServiceManager->createInstance
		(OUString::createFromAscii("com.sun.star.frame.Desktop" ));
 
// Query for the XUnoUrlResolver interface for loading Desktop
	Reference< XComponentLoader > xComponentLoader( desktop, UNO_QUERY );
 
//////////////////////////////////////////////////////////////////////////////////////
	Any any;
	sal_Int32 value;
 
	Reference< XComponentContext > xComponentContext =
	defaultBootstrap_InitialComponentContext();
 
// retrieve the servicemanager from the context
	Reference< XMultiComponentFactory > xMultiComponentFactory =
	xComponentContext->getServiceManager();
/************************************************************************************
Reference<XInterface> dialogModel = xMultiComponentFactory->createInstanceWithContext(
                                      OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"),
                                      xComponentContext );
************************************************************************************/
/////////////////////////////////////////////////////////////////////////////////////////
 
	Reference<XInterface> dialogModel = xRemoteServiceManager->createInstance
		(OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));
	cout<<"hi"<<endl;
 
///////////////////////////////////////////////////////////////////////////////////////////
 
	Reference< XPropertySet >xPSetDialog(dialogModel,UNO_QUERY );
 
	value=150;
	any<<=value;
	xPSetDialog->setPropertyValue( OUString::createFromAscii("PositionX"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("PositionY"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Width"), any );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Height"), any );
	any<<=OUString::createFromAscii( "Runtime Dialog Demo" );
	xPSetDialog->setPropertyValue( OUString::createFromAscii("Title"), any );
 
	Reference<XMultiServiceFactory> xMultiServiceFactory(dialogModel,UNO_QUERY );
 
	Reference< XInterface > buttonModel = xMultiServiceFactory->createInstance
		(OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel") );
 
	Reference< XPropertySet >xPSetButton(buttonModel,UNO_QUERY );
 
	value=20;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("PositionX"), any );
 
	value=70;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("PositionY"), any );
	value=50;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("Width"), any );
	value=14;
	any<<=value;
	xPSetButton->setPropertyValue( OUString::createFromAscii("Height"), any );
	any<<=OUString::createFromAscii("Button1");
	xPSetButton->setPropertyValue( OUString::createFromAscii("Name"), any );
	value=1;
	any<<=value;
 
//xPSetButton->setPropertyValue( OUString::createFromAscii("TabIndex"), any );
	any<<=OUString::createFromAscii( "Click Me" );
 
	xPSetButton->setPropertyValue( OUString::createFromAscii("Label"), any );
 
// insert the control models into the dialog model
	Reference< XNameContainer >xNameCont(dialogModel,UNO_QUERY );
	any<<=buttonModel;
 
	xNameCont->insertByName( OUString::createFromAscii("Button1"), any );
 
// create the dialog control and set the model
	Reference<XInterface> dialog = xRemoteServiceManager->createInstance(
			OUString::createFromAscii("com.sun.star.awt.UnoControlDialog"));
 
	Reference<XControl> xControl(dialog,UNO_QUERY );
	Reference<XControlModel >xControlModel(dialogModel,UNO_QUERY );
	xControl->setModel( xControlModel );
 
 // add an action listener to the button control
	Reference< XControlContainer >xControlCont(dialog ,UNO_QUERY );
	Reference< XInterface > objectButton = xControlCont->getControl( 
							OUString::createFromAscii("Button1") );
	Reference< XButton >xButton(objectButton ,UNO_QUERY);
 
	ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont );
	Reference< XActionListener > xActionListener = 
			static_cast< XActionListener* > ( xListener );
 
	xButton->addActionListener( xActionListener );
 
// create a peer
	Reference<XInterface> toolkit = xRemoteServiceManager->createInstance(
	OUString::createFromAscii("com.sun.star.awt.ExtToolkit"));
	Reference< XToolkit >xToolkit(toolkit , UNO_QUERY );
 
 
	Reference< XWindow >xWindow(xControl , UNO_QUERY );
	xWindow->setVisible( true );
	xControl->createPeer( xToolkit,'\0' );//create instance of XWindowPeer
 
 
// execute the dialog
	Reference< XDialog >xDialog(dialog , UNO_QUERY );
	xDialog->execute();
 
// dispose the dialog
	Reference< XComponent > xComponent(dialog,UNO_QUERY );
	xComponent->dispose();
 
/////////////////////////////////////////////////////////////////////////////////////
 
	return 0;
}

Ce code affichera dans une boite DOS :

hi
OK : 1
OK : 2
OK : 3
OK : 4
OK : 5
OK : 6
OK : 7
OK : 8
object listened to will be disposed

En cliquant sur le bouton, une incrémentation est réalisée et la nouvelle valeur est affichée. On peut tirer un certain nombre d'indications de ce code pour gérer une boite de dialogue :

  1. créer un service "dialog model", avec la variable dialogModel dans le code ci-dessus
  2. demander une interface XPropertySet pour positionner les propriétés (positions x et y, taille, titre, ..)
  3. création de tous les contrôles avec les deux règles précédentes : demander un "control model" en premier, et ensuite demander une interface XPropertySet pour positionner les propriétés
  4. demander une interface XNameContainer en partant du "dialog model"
  5. insérer tous les modèles de contrôle dans le modèle de dialogue avec le conteneur
  6. crééer un controle dialogue et demander une interface XControl puis l'interface XControlModedl pour positionner correctement le modèlel
  7. ajouter des "action listener" si nécessaires
  8. après création d'un "peer" exécuter la boîte de dialogue

Traduction complète d'un exemple Java

Donnons maintenant une traduction complète du code Java SampleDialog.java. Vous pouvez le trouver dans <OpenOffice.org1.1_SDK>/examples/DevelopersGuide/BasicAndDialogs/CreatingDialogs C'est une boîte de dialogue avec un bouton “Click Me”. Quand vous cliquez sur ce bouton, un compteur est incrémenté et la nouvelle valeur est affichée dans la boîte de dialogie. J'ai réalisé cet exemple en quelques heures en partant du précédent. Sans l'aide précieuse de GAP (from India) cela aurait été probablement retardé de quelques mois.

Cet exemple est construit comme toujours, sans "helper" (en utilisant ce code toujours comme point de départ) Voici maintenant les listings : on commence par l'intercepteur d'événements :

//Listing 18 The Action performed Event Listener
// C++
typedef ::cppu::WeakImplHelper1< ::com::sun::star::awt::XActionListener > ActionListenerHelper;
/** action listener
*/
class ActionListenerImpl : public ActionListenerHelper
{
private :
	sal_Int32 _nCounts;
	Reference< XControlContainer > _xControlCont;
	//XControlContainer _xControlCont;
 
public :
ActionListenerImpl(const Reference< XControlContainer >& xControlCont) {
	_xControlCont = xControlCont;
	_nCounts = 0;
}
 
// XEventListener
 virtual void SAL_CALL disposing (const com::sun::star::lang::EventObject& aEventObj ) throw(::com::sun::star::uno::RuntimeException) {
//	_xControlCont = NULL;
	printf("object listened to will be disposed\n");
}
 
// XActionListener
virtual void SAL_CALL actionPerformed (const ::com::sun::star::awt::ActionEvent& rEvent ) throw ( RuntimeException) {
// increase click counter
	_nCounts++;
//	printf("OK :  %d\n",_nCounts); OLD listener
	OUString OUStr;
// set label text
	Reference< XControl > label = _xControlCont->getControl(OUString::createFromAscii("Label1"));
 
// Don't forget to add : #include <com/sun/star/awt/XFixedText.hpp>
// Don't forget to add "com.sun.star.awt.XFixedText \" in the makefile
	Reference< XFixedText > xLabel(label,UNO_QUERY);
	xLabel->setText (OUString::createFromAscii("Text1 ") + OUStr.valueOf((sal_Int32)_nCounts));
 }
};

Ce qui diffère du code précédent est seulement la méthode "action performed" dans laquelle nous remplaçons le vieux printf (or cout<<) avec un setText. On n'affiche plus dans la fenêtre de shell mais directement dans la boîte de dialogue. Un petit coup d'oeil sur le fichier IDL correspondant :

//Listing 19 XFixedText Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XFixedText: com::sun::star::uno::XInterface
{
	[oneway] void setText( [in] string Text );
	string getText();
	/** sets the alignment of the text in the control.
		<pre>
		0: left
		1: center
		2: right
	 */
	[oneway] void setAlignment( [in] short nAlign ); 
 	short getAlignment(); 
 
};
}; }; }; };

On est prêt à construire et utiliser la boîte de dialogue maintenant. Voici un listing dans lequel nous avons omis la procédure ooConnect() donnée déjà plusieurs fois dans ce document.

//Listing 20 The complete Code
// C++
main( ) {
//retrieve an instance of the remote service manager
	Reference< XMultiServiceFactory > xServiceManager;
    	xServiceManager = ooConnect();
    	if( xServiceManager.is() ){
        	printf( "Connected sucessfully to the office\n" );
    	}
 
//get the desktop service using createInstance returns an XInterface type
    	Reference< XInterface  > Desktop = xServiceManager->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< XInterface > xdialogModel =
	 xServiceManager->createInstance(
	 	OUString::createFromAscii("com.sun.star.awt.UnoControlDialogModel"));
	if (xdialogModel.is()) printf("OK XDialogModel\n"); else printf("Error ... XDialodModel\n");
 
	Any val;
	Reference< XPropertySet > xPSetDialog(xdialogModel,UNO_QUERY);
	if (xPSetDialog.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
	sal_Int32 value=100;
	val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	xPSetDialog->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=150;val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=100;val<<=value;
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Height"),val);
 
	val <<=OUString::createFromAscii("Runtime Dialog Demo");
	xPSetDialog->setPropertyValue(OUString::createFromAscii("Title"),val);
 
	Reference< XMultiServiceFactory > xMultiServiceFactory( xdialogModel,UNO_QUERY);
 
///*****************
//******** in the above line xMultiServiceFactory instead xServiceManager !!!!!!
//Reference< XInterface > xbuttonModel = xServiceManager>createInstance( ....
	Reference< XInterface > xbuttonModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));
	if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");
 
	Reference< XPropertySet > xPSetButton(xbuttonModel,UNO_QUERY);
	if (xPSetButton.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
 
	value=20; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=70; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=50; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetButton->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Button1");
	xPSetButton->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetButton->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)0));
	val <<=OUString::createFromAscii("Click Me");
	xPSetButton->setPropertyValue(OUString::createFromAscii("Label"),val);
 
// create the label model and set the properties
	Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlFixedTextModel"));
	if (xlabelModel.is()) printf("OK xlabelModel\n"); else printf("Error ... xlabelModel\n");
	Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY);
	if (xPSetLabel.is()) printf("OK XPropertySet2\n"); else printf("Error ... XPropertySet2\n");
	value=40; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=30; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=100; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Label1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));
	val <<=OUString::createFromAscii("Text1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Label"),val);
 
// insert all the control in container
	Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY);
	if (xNameCont.is()) printf("OK XNameContainer\n"); else printf("Error ... XNameContainer\n");
	val <<= xbuttonModel;
// We insert first the button
	xNameCont->insertByName(OUString::createFromAscii("Button1") ,val); printf("First\n");
// We insert now the text control
	val <<= xlabelModel;
	xNameCont->insertByName(OUString::createFromAscii("Label1") , val);
 
// create the dialog control and set the model
	Reference< XInterface >dialog = xServiceManager->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlDialog"));
	if (dialog.is()) printf("OK dialog\n"); else printf("Error ... dialog\n");
	Reference< XControl > xControl(dialog,UNO_QUERY);
	if (xControl.is()) printf("OK XControl\n"); else printf("Error ... XControl\n");
	Reference< XControlModel > xControlModel(xdialogModel,UNO_QUERY);
	if (xControlModel.is()) printf("OK xControlModel\n"); else printf("Error ... xControlModel\n");
	xControl->setModel(xControlModel);
 
// add an action listener to the button control
	Reference< XControlContainer > xControlCont(dialog,UNO_QUERY);
	if (xControlCont.is()) printf("OK xControlContainer\n"); else printf("Error ... xControlContainer\n");
	Reference< XInterface > objectButton=xControlCont->getControl(OUString::createFromAscii("Button1"));
	if (objectButton.is()) printf("OK objectButton\n"); else printf("Error ... objectButton\n");
	Reference< XButton > xButton(objectButton,UNO_QUERY);
	ActionListenerImpl *xListener = new ActionListenerImpl( xControlCont );
	Reference< XActionListener > xActionListener = static_cast< XActionListener* > ( xListener );
	xButton->addActionListener( xActionListener );
 
// create a peer
	Reference< XToolkit >xToolkit = Reference< XToolkit >( xServiceManager->createInstance(
                                        OUString( RTL_CONSTASCII_USTRINGPARAM(
                                            "com.sun.star.awt.Toolkit" ))), UNO_QUERY );
	if (xToolkit.is()) printf ("XToolkit OK...\n"); else printf("XToolkit Error\n");
 
	Reference< XWindow > xWindow(xControl,UNO_QUERY);
	xWindow->setVisible(true);
	xControl->createPeer(xToolkit,NULL);
	Reference< XDialog > xDialog(dialog,UNO_QUERY);
	xDialog->execute();
	Reference< XComponent > xComponent(dialog,UNO_QUERY);
	xComponent->dispose();
 
	return 0;
}

Ce qui est obtenu est présenté maintenant dans la figure ci-dessous :

The First Dialog Example

Boîte de dialogue avec un champ de texte

On veut maintenant construire la boite de dialogue montrée ci-dessous.

An example of dialog with edit control

On doit jeter un oeil dans les fichiers IDL correspondants. On commence par l'interface XtextComponent.

//Listing 21 XTextComponent Interface : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
interface XTextComponent: com::sun::star::uno::XInterface
{
	[oneway] void addTextListener( [in] com::sun::star::awt::XTextListener l );
	[oneway] void removeTextListener( [in] com::sun::star::awt::XTextListener l );
	[oneway] void setText( [in] string aText );
	[oneway] void insertText( [in] com::sun::star::awt::Selection Sel,
			 [in] string Text );
	string getText();
	string getSelectedText();
	[oneway] void setSelection( [in] com::sun::star::awt::Selection aSelection );
	com::sun::star::awt::Selection getSelection();
	boolean isEditable();
	[oneway] void setEditable( [in] boolean bEditable );
	[oneway] void setMaxTextLen( [in] short nLen );
	short getMaxTextLen();
};
}; }; }; };

Comme montré sur l'image cidessus, cet exemple comporte un défaut : le texte est ajouté en haut au lieu d'être ajouté à la suite ! Pour le moment, je ne sais pas résoudre ce problème : si j'utilise une méthode setText, j'obtiens toujours une seule ligne, si j'utilise la méthode insertText il me faut lui fournir une sélection. Je peux prendre cette sélection avec la méthode getSelection mais il n'y a rien de sélectionné et cette méthode retourne le début du texte. (Je pense avec du recul qu'il faut gérer un curseur ici)

Nous montrons maintenant le service UnoControlEditModel dans le fichier UnoControlEditModel.idl :

//Listing 22 UnoControlEditModel Service : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
service UnoControlEditModel
{
	service com::sun::star::awt::UnoControlModel;
	[property] short Align;
	[property] long BackgroundColor;
	[property] short Border; 
	[optional, property] short EchoChar; 
	[property] boolean Enabled; 
	[property] com::sun::star::awt::FontDescriptor FontDescriptor; 
	[property] short FontEmphasisMark;
	[property] short FontRelief;
	[property] boolean HScroll;
	[property] boolean HardLineBreaks;
	[property] string HelpText;
	[property] string HelpURL;
	[property] short MaxTextLen; 
	[property] boolean MultiLine; 
	[property] boolean Printable; 
	[property] boolean ReadOnly; 
	[property] boolean Tabstop; 
	[property] string Text; 
	[property] long TextColor; 
	[property] long TextLineColor;
	[property] boolean VScroll;    
}; 
}; }; }; };

We use any of these properties in the example above. To construct it, I modify first the event listener of the previous example like the listing above :

//Listing 23 We first remplace XFixedText with XTextComponent interface
// C++
....
// Don't forget to add : #include <com/sun/star/awt/XTextComponent.hpp>
// Don't forget to add "com.sun.star.awt.XTextComponent \" in the makefile
//	Reference< XFixedText > xLabel(label,UNO_QUERY); //OLD
	Reference< XTextComponent > xLabel(label,UNO_QUERY);
	xLabel->insertText (xLabel->getSelection(),
		OUString::createFromAscii("Text1 ") + OUStr.valueOf((sal_Int32)_nCounts)+
		OUString::createFromAscii("\n"));
....

and then I replace the “com.sun.star.awt.UnoControlFixedTextModel” control with "com.sun.star.awt.UnoControlEditModel". This is done with code :

//Listing 24 The UnoControlEditModel : an Example
// C++
	Reference< XInterface > xlabelModel = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlEditModel"));
	Reference< XPropertySet > xPSetLabel(xlabelModel,UNO_QUERY);
	value=20; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=10; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=110; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=50; val <<= value;
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Height"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("HScroll"),makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("VScroll"),makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("MultiLine"),
		makeAny((sal_Bool)true));
	xPSetLabel->setPropertyValue(OUString::createFromAscii("HardLineBreaks"),
		makeAny((sal_Bool)true));
	val <<=OUString::createFromAscii("Label1");
	xPSetLabel->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetLabel->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));

We will construct helper to simplify the task of writing such a code later on. But at first we have to speak on an other kind of button : OK button. The property to change is "PushButtonType". Values taken by this property are given by a IDL file as usual :

Listing 25 PushButtonType enumeration : IDL File 
// IDL
module com {  module sun {  module star {  module awt {
enum PushButtonType
{
	STANDARD,
	OK, 
	CANCEL, 
	HELP  
}; 
}; }; }; };

The values are given by an enum type. We have already encounter such a problem and then know how to resolve it. I give here the code to add if you want an OK button :

//Listing 26 adding a second “OK” button
// C++
// second button : OK button
// we need a second button modedl
	Reference< XInterface > xbuttonModel2 = xMultiServiceFactory->createInstance(
		OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel"));
	if (xbuttonModel.is()) printf("OK UnoControlButtonModel\n"); else printf("Error ... UnoControlButtonModel\n");
 
	Reference< XPropertySet > xPSetButton2(xbuttonModel2,UNO_QUERY);
	if (xPSetButton2.is()) printf("OK XPropertySet\n"); else printf("Error ... XPropertySet\n");
	// *** The following property is not position-independant !!!!!
	// Don't forget to add : #include <com/sun/star/awt/PushButtonType.hpp>
	// Don't forget to add "com.sun.star.awt.PushButtonType \" in the makefile
	// short is found with Inspector
	val <<= (short)PushButtonType_OK;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PushButtonType"),val);
 
	value=80; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionX"),val);
	value=70; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("PositionY"),val);
	value=50; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Width"),val);
	value=14; val <<= value;
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Height"),val);
	val <<=OUString::createFromAscii("Button2");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Name"),val);
	xPSetButton2->setPropertyValue(OUString::createFromAscii("TabIndex"),makeAny((short)1));
	val <<=OUString::createFromAscii("OK");
	xPSetButton2->setPropertyValue(OUString::createFromAscii("Label"),val);

And then we have to add it and then to modify the insert listing's part like that :

//Listing 27 Inserting all control in container
// C++
// insert all the control in container
	Reference< XNameContainer > xNameCont(xdialogModel,UNO_QUERY);
	if (xNameCont.is()) printf("OK XNameContainer\n"); else printf("Error ... XNameContainer\n");
	val <<= xbuttonModel;
// We insert first the button
	xNameCont->insertByName(OUString::createFromAscii("Button1") ,val); printf("First\n");
	val <<= xbuttonModel2;
	xNameCont->insertByName(OUString::createFromAscii("Button2") ,val); //printf("First\n");
// We insert now the text control
	val <<= xlabelModel;
	xNameCont->insertByName(OUString::createFromAscii("Label1") , val);


Exécuter une macro OOoBasic

Un premier exemple

Notre but est d'exécuter un sous-programme OOoBasic à partir du C++. Nous commençons par le message intéressant posté par Danny Brewer (http://www.oooforum.org/forum/viewtopic.php?p=20890#20890) : Dans le module Essai1 des macros OOo, je place ce sous-programme :

'Listing 133
REM  *****  BASIC  *****
Sub SaySomething( ) 
	MsgBox "Hello from OOoBasic" 
End Sub

Le code correspondant en OooBasic pour seulement exécuter ce sous-programme devrait être :

'Listing 134
REM  *****  BASIC  *****
Sub Main 
	oDispatch = createUnoService( "com.sun.star.frame.DispatchHelper" ) 
	oDispatch.executeDispatch( StarDesktop, "macro:///Standard.Module1.SaySomething()", 
		"", 0, Array() ) 
End Sub

Nous pouvons appeler directement ce sous-programme par son nom dans OOoBasic mais pas dans C++. Traduire ce code dans C++ est facile: nous donnons encore le listing complet :

//Listing 135
// 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;
}

lequel affiche un message “Bonjour d'OOoBasic” mais retourne une erreur. Cette erreur est là seulement parce que le programme une fois terminé essaie de détruire les variables objets pendant qu'OOoBasic est toujours en marche ! Nous avons un processus complètement asynchrone.

XRay et C++

XRay est un outil d'inspection d'objets écrit en OOoBasic pour OOoBasic.Voir ici

Comme dans l'exemple précédent, nous pouvons naturellement appeler l'outil XRay depuis le C++. Ici nous expliquons comment faire cela. En premier il faut écrire un sub OOoBasic :

'Listing 136
REM  *****  BASIC  *****
Sub BernardXRay( x ) 
	oBJ = createUnoService(x)
	XRAY.XRAY oBJ
End Sub

dans le module “Essai1”, et en deuxième il faut écrire par exemple :

//Listing 137
// 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 > ());

La façon de faire cela est très inefficace comme explorateur d'objet. La liaison entre C++ et OOoBasic est trop lâche. Il n'y a aucune liaison entre la variable C++ rDispatchHelper et la variable oBJ OOoBasic. Une pourrait très bien être NULLE et pas la seconde. J'explorerai plus tard une autre façon avec un add-on pour faire une liaison entre OOoBasic et C++.

Une autre manière en C++ pourrait être :

//Listing 138
// C++
void LittleXRay(OUString OUStr,Reference< XMultiServiceFactory > rOServiceManager) {
// Don't forget to add : using namespace com::sun::star::reflection;
// Don't forget to add : #include <com/sun/star/reflection/XIdlReflection.hpp>
// Don't forget to add "com.sun.star.reflection.XIdlReflection \" in the makefile
	Reference< XIdlReflection >rIDLReflection = Reference< XIdlReflection >
					( rOServiceManager->createInstance(
                                      OUString( RTL_CONSTASCII_USTRINGPARAM(
                                          "com.sun.star.reflection.CoreReflection" ))), UNO_QUERY );
	if (! rIDLReflection.is()) printf("Error XIDLRflection\n");
	Reference< XIdlClass > rIDLClass=rIDLReflection->forName(OUStr);
//			OUString::createFromAscii("com.sun.star.frame.XDesktop"));
 
 
	Sequence< Reference< XIdlClass > > SeqIdlClass = rIDLClass->getSuperclasses();
	printf("******** superClasses :(%d)\n",SeqIdlClass.getLength());
	for (int i=0;i<SeqIdlClass.getLength();i++){
		OString o = OUStringToOString( SeqIdlClass[i]->getName(),RTL_TEXTENCODING_ASCII_US );
    		printf("%s\n", o.pData->buffer );
	}
	Sequence< Reference< XIdlMethod > > SeqIdlMethods = rIDLClass->getMethods();
	printf("******** methods : (%d)\n",SeqIdlMethods.getLength());
	for (int i=0;i<SeqIdlMethods.getLength();i++){
		OString o = OUStringToOString( SeqIdlMethods[i]->getName(),RTL_TEXTENCODING_ASCII_US );
    		printf("%s\n", o.pData->buffer );
	}
	Sequence< Reference< XIdlField > > SeqIdlFields = rIDLClass->getFields();
	printf("******* Fields : (%d)\n",SeqIdlFields.getLength());
	for (int i=0;i<SeqIdlFields.getLength();i++){
		OString o = OUStringToOString( SeqIdlFields[i]->getName(),RTL_TEXTENCODING_ASCII_US );
    		printf("%s\n", o.pData->buffer );
	}
}

laquelle pourrait être appelée :

//Listing 139
// C++
  LittleXRay(OUString::createFromAscii("com.sun.star.frame.XDesktop"),rOfficeServiceManager);

Nous préférons utiliser la méthode utilisée par l'exemple Java Inspector qui inspecte l'objet réel. Vous pouvez trouver alors par exemple des valeurs des propriétés. (<OpenOffice.org1.1_SDK>/examples/java/Inspector)

//Listing 140
// C++
// N'oubliez pas d'ajouter : #include <com/sun/star/reflection/ParamMode.hpp>
// N'oubliez pas d'ajouter "com.sun.star.reflection.ParamMode \" in the makefile
OString getParamMode(ParamMode paramMode) {
// comes from <OpenOffice1.1_SDK>/examples/java/Inspector
  OString toReturn;
  toReturn = "";
  if (paramMode == ParamMode_IN) toReturn = "IN"; else
    if (paramMode == ParamMode_OUT) toReturn = "OUT"; else
      if (paramMode == ParamMode_INOUT) toReturn = "INOUT";
  return toReturn;
}
 
void smallXRay(Any any,Reference< XMultiServiceFactory > rOServiceManager) {
// comes from <OpenOffice1.1_SDK>/examples/java/Inspector
 
// N'oubliez pas d'ajouter : using namespace com::sun::star::beans;
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/XIntrospection.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.XIntrospection \" in the makefile
	Reference< XIntrospection >xIntrospection = Reference< XIntrospection >
					( rOServiceManager->createInstance(
                                  OUString( RTL_CONSTASCII_USTRINGPARAM(
                                  "com.sun.star.beans.Introspection" ))), UNO_QUERY );
 
// ********* get all methods for the given object *********************
 
// N'oubliez pas d'ajouter : #include <com/sun/star/lang/XServiceInfo.hpp>
// N'oubliez pas d'ajouter "com.sun.star.lang.XServiceInfo \" in the makefile
	Reference< XServiceInfo > rServiceInfo(any,UNO_QUERY);
 
	Reference< XIntrospectionAccess > xIntrospec = xIntrospection->inspect(any);
 
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/MethodConcept.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.MethodConcept \" in the makefile
	Sequence< Reference < XIdlMethod > > mMethods = xIntrospec -> 
												getMethods(MethodConcept::ALL);
	printf("******** methods : (%d)\n",mMethods.getLength());
	for (int i=0;i<mMethods.getLength();i++){
		OString params;
		params="";
		Sequence< ParamInfo > ParamInfos = mMethods[i]->getParameterInfos();
		if (ParamInfos.getLength() > 0) {
			for (int j=0;j<ParamInfos.getLength();j++){
				Reference< XIdlClass > xIdlClass = ParamInfos[j].aType;
				if (j == 0)
				// first parameter has no leading comma
				params += "[" + getParamMode(ParamInfos[j].aMode)+
				"]" + OUStringToOString(xIdlClass->getName(),RTL_TEXTENCODING_ASCII_US );
				else
				params += ",[" + getParamMode(ParamInfos[j].aMode)+
				"]"+OUStringToOString(xIdlClass->getName(),RTL_TEXTENCODING_ASCII_US );
			}
		}
		OString o = OUStringToOString( mMethods[i]->getName(),RTL_TEXTENCODING_ASCII_US )
						+ "(" + params + ")";
    		printf("%s\n", o.pData->buffer);
	}
 
// ********** get all Interfaces for the given object *********************
 
// N'oubliez pas d'ajouter : #include <com/sun/star/lang/XTypeProvider.hpp>
// N'oubliez pas d'ajouter "com.sun.star.lang.XTypeProvider \" in the makefile
	Reference< XTypeProvider > rTypeProvider(any,UNO_QUERY);
// N'oubliez pas d'ajouter : #include <com/sun/star/uno/Type.hxx>
// But nothing in MakeFile : this hxx file is provided by SDK
	Sequence< Type > types = rTypeProvider->getTypes();
	printf("******** interfaces : (%d)\n",types.getLength());
	for (int i=0;i<types.getLength();i++){
		OString o = OUStringToOString( types[i].getTypeName(),RTL_TEXTENCODING_ASCII_US );
    		printf("%s\n", o.pData->buffer );
	}
 
// ********** get all properties for the given object *********************
 
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/PropertyConcept.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.PropertyConcept \" in the makefile
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/Property.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.Property \" in the makefile
// N'oubliez pas d'ajouter : #include <com/sun/star/beans/XPropertySet.hpp>
// N'oubliez pas d'ajouter "com.sun.star.beans.XPropertySet \" in the makefile
 
	Sequence< Property > Properties = xIntrospec -> getProperties(PropertyConcept::ALL);
	printf("******** properties : (%d)\n",Properties.getLength());
	for (int i=0;i<Properties.getLength();i++){
	//	Reference< XPropertySet > rPropertySet(any,UNO_QUERY);
	//	Any object;
	//	OUString ou;
	//	object <<= rPropertySet->getPropertyValue(Properties[i].Name);
	//	if (object.hasValue()) printf("Valeur trouvee : ");
	//	object >>= ou;
		OString o = OUStringToOString( Properties[i].Name,RTL_TEXTENCODING_ASCII_US ) +
		" = (" + 
		OUStringToOString(Properties[i].Type.getTypeName(),RTL_TEXTENCODING_ASCII_US ) + ") ";
    	printf("%s\n", o.pData->buffer );
	}
 
}

lequel est appelé par :

//Listing 141
// C++
	Any toInspect;
	toInspect <<= rDesktop;
	smallXRay(toInspect,rOfficeServiceManager);
Personal tools