Difference between revisions of "FR/Documentation/Fichiers IDL et C++"
SergeMoutou (talk | contribs) |
|||
(19 intermediate revisions by 3 users not shown) | |||
Line 14: | Line 14: | ||
− | Pour répondre à cette question, nous choisissons OOoBasic : | + | Pour répondre à cette question, nous choisissons le langage OOoBasic : |
<source lang="oobas"> | <source lang="oobas"> | ||
'Listing 1 | 'Listing 1 | ||
Line 31: | Line 31: | ||
Les règles de Danny Brewer | Les règles de Danny Brewer | ||
+ | |||
Les services sont similaires aux objets en java. | Les services sont similaires aux objets en java. | ||
Line 49: | Line 50: | ||
Nous avons suffisamment programmé l'API UNO pour en déduire un certain nombre de règles pour le langage C++. | Nous avons suffisamment programmé l'API UNO pour en déduire un certain nombre de règles pour le langage C++. | ||
− | '''Règle 1''' : le langace C++ nous permet de "naviguer" d'une interface à une autre. Nous aborderons | + | '''Règle 1''' : le langace C++ nous permet de "naviguer" d'une interface à une autre. Nous aborderons le problème de l'obtention de ces interfaces [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Obtention_d.27une_interface_avec_la_macro_UNO_QUERY| plus loin]]. |
− | {{ | + | {{Note|'''Note''' : cette règle n'est vrai que pour le langage C++ et à ma connaissance pour le langage Java. Mais le langage OOoBasic permet quant à lui d'utiliser des variables pour stocker des services. C'est beaucoup plus pratique et donne des programmes beaucoup plus lisibles.}} |
'''Règle 2''' : si pour une raison ou une autre on est obligé de manipuler un service, il faudra le faire dans une variable de type <idl>com.sun.star.uno.XInterface</idl>. Ce type est une interface puisque son nom commence par un X, et mettre une variable d'un type dans une variable d'un autre type s'appelle transtyper. Nous aborderons [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Quand_pour_obtenir_une_interface_il_faut_passer_par_un_service_et_par_XMultiServiceFactory|plus loin]] le problème de l'obtention de ces services en C++. | '''Règle 2''' : si pour une raison ou une autre on est obligé de manipuler un service, il faudra le faire dans une variable de type <idl>com.sun.star.uno.XInterface</idl>. Ce type est une interface puisque son nom commence par un X, et mettre une variable d'un type dans une variable d'un autre type s'appelle transtyper. Nous aborderons [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Quand_pour_obtenir_une_interface_il_faut_passer_par_un_service_et_par_XMultiServiceFactory|plus loin]] le problème de l'obtention de ces services en C++. | ||
− | Nous pouvons déduire de ces deux règles que le | + | Nous pouvons déduire de ces deux règles que le programmeur C++ devra, d'une manière ou d'une autre, retrouver des chemins pour aller d'une interface vers une autre. Si je pars d'une interface XTruc, vous pouvez appeler toutes ses méthodes ou chercher d'autres interfaces me conduisant à utiliser d'autres méthodes. Toutes les possibilités à partir de l'interface XTruc peuvent être représentées par un arbre : c'est cela que j'appelle arbre-IDL. Mon travail de programmeur va consister à trouver un chemin dans cet arbre et ce n'est pas toujours facile. J'ai déjà présenté les arbres-IDL (ou plus exactement les chemins dans cet arbre) dans ce document sous plusieurs formes : |
#[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_textuelle_d.27un_arbre_IDL|Représentation textuelle d'un arbre IDL]]. | #[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_textuelle_d.27un_arbre_IDL|Représentation textuelle d'un arbre IDL]]. | ||
#[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_de_type_Introspection_d.27un_arbre_IDL|Représentation avec un outil d'introspection]] d'un arbre IDL. | #[[FR/Documentation/OpenOffice_Writer#Repr.C3.A9sentation_de_type_Introspection_d.27un_arbre_IDL|Représentation avec un outil d'introspection]] d'un arbre IDL. | ||
Line 62: | Line 63: | ||
=Specification IDL= | =Specification IDL= | ||
− | Les interfaces | + | Les interfaces sont spécifiées à l'aide d'un langage spécial, le langage IDL. UNO utilise UNO-IDL comme le langage de définition de l'interface. Le Langage de définition de l'Interface (IDL) est un langage descriptif (et non un langage de programmation) décrivant l'existence des interfaces qui seront rendues effectives par les objets. Avec IDL, vous définissez le nom de l'interface, les noms de chacun des attributs et méthodes. Une fois que vous avez créé les fichiers IDL, vous pouvez utiliser un compilateur IDL pour générer les fichiers d'en-tête dans le langage de programmation C++. |
− | La façon de spécifier des modules simples avec IDL est si claire que nous choisissons de commencer en premier seulement des exemples. | + | La façon de spécifier des modules simples avec IDL est si claire que nous choisissons de commencer en premier seulement par des exemples. |
==Specifier une interface== | ==Specifier une interface== | ||
− | Nous prenons comme exemple, l'interface XdrivingDirection de la Figure | + | Nous prenons comme exemple, l'interface XdrivingDirection de la Figure ci-dessous. |
+ | |||
+ | [[Image:Service&Interface.png]] | ||
+ | |||
<source lang="idl"> | <source lang="idl"> | ||
//Listing 2 Interface imaginaire XDrivingDirection | //Listing 2 Interface imaginaire XDrivingDirection | ||
Line 77: | Line 81: | ||
==Spécifier un service== | ==Spécifier un service== | ||
− | L'exemple de la Figure | + | L'exemple de la Figure ci-dessus est toujours utilisé, voici la spécification IDL correspondante : |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 3 Spécification d'un service « car » | //Listing 3 Spécification d'un service « car » | ||
Line 294: | Line 298: | ||
=Collecter de l'information UNO avec les fichiers IDL= | =Collecter de l'information UNO avec les fichiers IDL= | ||
Il y a plusieurs possibilités pour trouver de l'information sur UNO. | Il y a plusieurs possibilités pour trouver de l'information sur UNO. | ||
− | La première est d'utiliser OOoBasic et l'outil XRay de Bernard Marcelly | + | La première est d'utiliser OOoBasic et l'outil XRay de Bernard Marcelly, [http://www.openoffice.org/fr/Documentation/Basic/ voir les Tutoriels Basic]. Point négatif : OOoBasic ne montre pas les propriétés et les méthodes exactes, quelques unes sont rajoutées parce qu'elles sont disponibles en OooBasic. |
L'autre possibilité est d'aller à l'adresse internet suivante : http://api.openoffice.org/docs/common/ref/index-files/index-1.html | L'autre possibilité est d'aller à l'adresse internet suivante : http://api.openoffice.org/docs/common/ref/index-files/index-1.html | ||
− | qui fournit la même information mais probablement de manière plus lisible. Nous avons fourni des exemples dans les chapitres antérieurs (en particulier chapitre | + | qui fournit la même information mais probablement de manière plus lisible. Nous avons fourni des exemples dans les chapitres antérieurs (en particulier [[FR/Documentation/OpenOffice Writer|chapitre 7...]]) et normalement le lecteur a des compétences sur le sujet. |
==Le point de vue de Danny Brewer == | ==Le point de vue de Danny Brewer == | ||
Néanmoins, il est important de comprendre le concept d'un "service" dans les documents sur l'API. Un service est juste une façon de grouper... | Néanmoins, il est important de comprendre le concept d'un "service" dans les documents sur l'API. Un service est juste une façon de grouper... | ||
Line 406: | Line 410: | ||
==Services et C++, c'est pas simple== | ==Services et C++, c'est pas simple== | ||
− | {{ | + | {{Tip| |
Si vous voulez bien comprendre le titre de cette section, lisez-là en vous posant systématiquement la question de savoir à tout moment quels sont les services disponibles.}} | Si vous voulez bien comprendre le titre de cette section, lisez-là en vous posant systématiquement la question de savoir à tout moment quels sont les services disponibles.}} | ||
Line 464: | Line 468: | ||
}; }; }; }; | }; }; }; }; | ||
</source> | </source> | ||
− | Mais si vous regardez plus en détail dans ce fichier IDL, vous | + | Mais si vous regardez plus en détail dans ce fichier IDL, vous verrez que <idl>com.sun.star.text.XText</idl> hérite de <idl>com.sun.star.text.XSimpleText</idl>. Est-ce que la méthode createTextCursor est ici ? Oui, comme vous pouvez le voir. |
<source lang="idl"> | <source lang="idl"> | ||
//Listing 13 XSimpleText Interface IDL file | //Listing 13 XSimpleText Interface IDL file | ||
Line 484: | Line 488: | ||
}; }; }; }; | }; }; }; }; | ||
</source> | </source> | ||
− | {{ | + | {{Tip|Si avant de lire la suite vous savez répondre à la question : quels sont les services disponibles dans la variable xTextCursor du listing 11, alors Bravo.}} |
− | Quels sont les services disponibles ici ? J'ai utilisé un outil d'introspection qui me donne : | + | Quels sont les services disponibles ici ? J'ai utilisé un outil d'introspection pour la réponse, qui me donne : |
<pre> | <pre> | ||
******** Services : 8 | ******** Services : 8 | ||
Line 500: | Line 504: | ||
Vous pouvez probablement trouver chacun d'entre eux via internet mais ce sera une tâche longue et fastidieuse : de bonnes raisons d'expliquer les services d'introspection [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Le_service_de_Core_reflection_et_son_interface_XIdlReflection|plus loin dans ce chapitre]]. | Vous pouvez probablement trouver chacun d'entre eux via internet mais ce sera une tâche longue et fastidieuse : de bonnes raisons d'expliquer les services d'introspection [[Documentation/FR/Fichiers_IDL_et_C%2B%2B#Le_service_de_Core_reflection_et_son_interface_XIdlReflection|plus loin dans ce chapitre]]. | ||
− | {{ | + | {{Note|A noter que c'est l'utilisation des méthodes retournant un type donné qui sont absolument difficiles à déchiffrer. Trouver les services accessibles est alors très difficile et, personnellement, je ne m'y aventure pas sans outil d'instrospection (voir [[FR/Documentation/Base_de_registres#Interfaces_et_services_du_defaultBootstrap_InitialComponentContext.28.29|un exemple ici]]). Bonne nouvelle quand même, il y a quand même une exception avec les méthodes <code>createInstance</code> et <code>createInstanceWithContext</code> pour lesquelles le service retourné est complètement déterminé.}} |
Oui, voila décrit très superficiellement le travail du programmeur. Vous devez parcourir de tels chemins dans l'arbre IDL, pour trouver quoi faire en programmant. Heureusement il y a plus court en utilisant les exemples du SDK. Mais la plupart d'entre eux sont en Java, mais je dois avouer avoir trouvé beaucoup d'inspiration dans ces exemples même si je ne suis pas un programmeur Java. | Oui, voila décrit très superficiellement le travail du programmeur. Vous devez parcourir de tels chemins dans l'arbre IDL, pour trouver quoi faire en programmant. Heureusement il y a plus court en utilisant les exemples du SDK. Mais la plupart d'entre eux sont en Java, mais je dois avouer avoir trouvé beaucoup d'inspiration dans ces exemples même si je ne suis pas un programmeur Java. | ||
Line 548: | Line 552: | ||
Reference< XStorable > oToStore (OfDoc, UNO_QUERY); | Reference< XStorable > oToStore (OfDoc, UNO_QUERY); | ||
</source> | </source> | ||
+ | Il s'agit d'une déclaration de variable avec initialisation. Si la variable est déjà déclarée, utilisez alors une version un peu différente : | ||
+ | <source lang="cpp"> | ||
+ | // C++ | ||
+ | // query from com::sun::star::frame::XStorable interface | ||
+ | oToStore = Reference< XStorable > (OfDoc, UNO_QUERY); | ||
+ | </source> | ||
2) Ajouter à l'aide d'une directive d'inclusion les fichiers hpp correspondants. Il faut ajouter aussi les espaces de nommage correspondants. L'inclusion est faite par : | 2) Ajouter à l'aide d'une directive d'inclusion les fichiers hpp correspondants. Il faut ajouter aussi les espaces de nommage correspondants. L'inclusion est faite par : | ||
<source lang="cpp"> | <source lang="cpp"> | ||
Line 572: | Line 582: | ||
com.sun.star.container.XHierarchicalNameAccess | com.sun.star.container.XHierarchicalNameAccess | ||
</pre> | </pre> | ||
− | {{ | + | {{Note| |
Apprendre à réaliser ces trois étapes est essentiel pour une programmation en C++ : il vous sera impossible de réaliser un programme sans demander à un moment donné une interface (ou un service, comme traité plus loin).}} | Apprendre à réaliser ces trois étapes est essentiel pour une programmation en C++ : il vous sera impossible de réaliser un programme sans demander à un moment donné une interface (ou un service, comme traité plus loin).}} | ||
Line 670: | Line 680: | ||
Ce code se compile mais donne une erreur d'exécution. Cela signifie que l'on ne peut pas utiliser n'importe quelle interface <idl>com.sun.star.lang.XMultiServiceFactory</idl> pour obtenir n'importe quelle autre Interface. | Ce code se compile mais donne une erreur d'exécution. Cela signifie que l'on ne peut pas utiliser n'importe quelle interface <idl>com.sun.star.lang.XMultiServiceFactory</idl> pour obtenir n'importe quelle autre Interface. | ||
− | {{ | + | {{Warn|Si vous travaillez avec un document demandez son interface <code>XMultiServiceFactory</code> correspondante avant d'envisager l'obtention d'un service particulier pour ce document.}} |
====Un autre exemple déjà présenté==== | ====Un autre exemple déjà présenté==== | ||
Line 695: | Line 705: | ||
Voici en résumé de manière schématique, le chemin dans l'arbre IDL correspondant au code ci-dessus : | Voici en résumé de manière schématique, le chemin dans l'arbre IDL correspondant au code ci-dessus : | ||
[[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtention de l'interface XComponentLoader]] | [[Image:ch4fig2Componentloader.png|center|thumb|600px|Obtention de l'interface XComponentLoader]] | ||
− | {{ | + | {{Note| |
Je ferai l'effort, dans la suite du document, de systématiquement montrer le changement de type du service en interface <idl>com.sun.star.uno.XInterface</idl> dans mes schémas. Il n'y a aucune autre raison de trouver cette interface dans un arbre IDL, et cela rendra plus facile le repérage de cette opération.}} | Je ferai l'effort, dans la suite du document, de systématiquement montrer le changement de type du service en interface <idl>com.sun.star.uno.XInterface</idl> dans mes schémas. Il n'y a aucune autre raison de trouver cette interface dans un arbre IDL, et cela rendra plus facile le repérage de cette opération.}} | ||
Line 780: | Line 790: | ||
==L'introspection et OOoBasic== | ==L'introspection et OOoBasic== | ||
− | {{ | + | {{Warn|Cette section n'a pas pour vocation de remplacer l'inestimable outil de Bernard Marcelly, a savoir, XRay. Voir pour cela une description [[Extensions_development_basic#Xray_tool|dans ce wiki]].}} |
OooBasic permet beaucoup de choses et en particulier l'introspection. Le code de Danny Brewer présenté ici : http://www.oooforum.org/forum/viewtopic.php?t=8737 nous montre comment ? Examinons un peu plus en détail ce code : | OooBasic permet beaucoup de choses et en particulier l'introspection. Le code de Danny Brewer présenté ici : http://www.oooforum.org/forum/viewtopic.php?t=8737 nous montre comment ? Examinons un peu plus en détail ce code : | ||
Line 891: | Line 901: | ||
Pour aller plus loin en C++ voyez la section suivante sur l'interface XdlRefection. | Pour aller plus loin en C++ voyez la section suivante sur l'interface XdlRefection. | ||
− | {{ | + | {{Note| |
Vous pouvez modifier la base de registre d'Openoffice sans écrire aucun code. Pour cela vous avez besoin d'un fichier IDL et son fichier rdb correspondant. Ajouter le fichier rdb dans le répertoire Unix “<Ooo>/program/unorc” ou le répertoire windows “<Ooo>/program/uno.ini”.}} | Vous pouvez modifier la base de registre d'Openoffice sans écrire aucun code. Pour cela vous avez besoin d'un fichier IDL et son fichier rdb correspondant. Ajouter le fichier rdb dans le répertoire Unix “<Ooo>/program/unorc” ou le répertoire windows “<Ooo>/program/uno.ini”.}} | ||
Line 922: | Line 932: | ||
End Sub | End Sub | ||
</source> | </source> | ||
− | {{ | + | {{Note| |
Pour une utilisation du Java Inspector plus récent, voir [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]]}}. | Pour une utilisation du Java Inspector plus récent, voir [[Object_Inspector#Calling_from_a_Basic_Macro|Calling from a Basic Macro]]}}. | ||
Si Java n'est pas correctement intallé l'exécution de ce programme déclenchera l'ouverture d'une boîte de dialogue qui vous permettra de définir votre machine virtuelle JRE à condition de savoir où elle se trouve. | Si Java n'est pas correctement intallé l'exécution de ce programme déclenchera l'ouverture d'une boîte de dialogue qui vous permettra de définir votre machine virtuelle JRE à condition de savoir où elle se trouve. | ||
Line 1,039: | Line 1,049: | ||
</pre> | </pre> | ||
− | {{ | + | {{Note|'''Note 1''' : [[Object Inspector|The New Object Inspector]] apparaît dans le SDK après la version 2.0. Il est plus complexe et capable de générer du code Java, C++ ou OOoBasic. Je n'ai pas testé le code ci-dessus avec [[Object Inspector|the new object inspector]] mais ne vois pas pourquoi cela ne fonctionnerait pas correctement.}} |
− | {{ | + | {{Note|'''Note 2''' : [[Documentation/FR/OpenOffice_Writer#Aller_plus_loin_avec_l.27Inspector_Java|Un petit exemple]] avec [[Object Inspector|the new object inspector]] peut être trouvé dans ce document.}} |
− | {{ | + | {{Warn|Je pense qu'il y a bien plus simple pour utiliser l'inspecteur Java, en particulier qu'il n'y a pas lieu de modifier le makefile (sauf pour l'interface org.OpenOffice.XInstanceInspector). Il doit en effet pouvoir s'utiliser comme n'importe quel autre service et ne nécessite donc pas la céation d'un fichier URD à partir d'un fichier IDL. Je pense avoir manqué de recul sur ce coup là et qu'il me faudra un jour ou l'autre reprendre ce problème à zéro.}} |
=Traduire des programmes OooBasic en C++= | =Traduire des programmes OooBasic en C++= | ||
Line 1,227: | Line 1,237: | ||
Voir [[FR/Documentation/BASIC_Guide/API_Intro| Introduction à l'API StarOffice]] pour plus d'informations. | Voir [[FR/Documentation/BASIC_Guide/API_Intro| Introduction à l'API StarOffice]] pour plus d'informations. | ||
+ | |||
+ | J'ai eu aussi l'occasion de traduire des programmes OOoBasic dans les chapitres [[FR/Documentation/Composants_et_boite_de_dialogue|Composants et boîte de dialogue]] | ||
+ | et [[FR/Documentation/Plus_loin_avec_Composants_et_boites_de_dialogue|Plus loin avec les composants et les boîtes de dialogue]]. | ||
= Retour à la page d'accueil= | = Retour à la page d'accueil= | ||
Line 1,243: | Line 1,256: | ||
* [[Extensions_introspection|Extensions Introspection]] | * [[Extensions_introspection|Extensions Introspection]] | ||
* [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]] | * [[BASIC/UNO_Object_Browser|BASIC UNO Object Browser]] | ||
+ | |||
+ | [[Category:FR/Cpp_Guide]] |
Latest revision as of 21:14, 14 July 2018
(Cette introduction est faite avec l'aide de :http://udk.openoffice.org/cpp/man/component_tutorial.html ) Vous devez commencer à être habitué si vous êtes parvenus jusqu'ici en lisant tous les chapitres précédents à la terminologie service/interface qui prévaut pour la programmation UNO. Cette terminologie n'étant pas universelle, je me permet d'en rappeler quelques éléments.
Services et Interfaces
Introduction
Voir Introduction à l'API StarOffice pour une introduction à UNO (ou Introducing the OpenOffice.org API). Dans l'API OpenOffice, un "service" est un concept abstrait qui fournit certaines interfaces et propriétés/attributs. Comme le souligne le Guide du développeur : “les propriétés sont des données dans un objet qui sont triées par nom sur une interface générique pour un accès de la propriété”. Il serait mieux de distinguer attribut et propriété. Mais nous ne le faisons pas pour le moment.
Un service possède plusieurs propriétés et une interface correspond à plusieurs méthodes qui trouvent un moyen de changer les propriétés. Prenons une voiture pour illustrer ces concepts. La voiture fournit deux interfaces concrètes : XAccelerationControl et XDrivingDirection. Deux méthodes d'exportation d'interface, la première pour accélérer et ralentir, la seconde pour faire tourner la voiture à droite ou à gauche (voir Figure 9). Pourquoi deux (ou plusieurs) interfaces ? C'est seulement pour réunir des fonctionnalités caractéristiques. Pensez à une vraie voiture où ces interfaces sont séparées (le volant d'un côté et les pédales de l'autre) et ce qui se passerait si seulement les pieds dirigeaient ces deux interfaces ?
Dans l'API OpenOffice, les modules groupent des services, des interfaces, des types, des énumérations et autres structures données (voir Figure 10). C'est impossible de comprendre un tel dessin sans se poser un certain nombre de questions et, en particulier, comment est-ce que nous voyons ce module quand il est utilisé dans un programme ?
Pour répondre à cette question, nous choisissons le langage OOoBasic :
'Listing 1
REM ***** BASIC *****
'en premier, créez le service
oSimpleComponent = CreateUnoService( "my_module.MyService1" )
'call the unique method
oSimpleComponent.methodOne()
....
'first create the service
oSimpleComponent2 = CreateUnoService( "my_module.MyService2" )
'call one of both method
oSimpleComponent.methodTwo()
...
Les règles de Danny Brewer
Les services sont similaires aux objets en java.
- Un service peut hériter de rien ou d'un autre service. (auquel on peut appliquer récursivement cette règle)
- Un service peut inclure zéro ou plusieurs services. (auxquels on peut appliquer récursivement ces règles)
- Un service peut exporter des interfaces.
- Un service peut avoir des propriétés.
- Une interface peut hériter d'aucune ou d'une autre interface (à laquelle on peut appliquer récursivement cette règle).
- Une interface peut inclure zéro ou plusieurs interfaces (auxquelles on peut appliquer récursivement ces règles).
- Une interface peut exécuter des méthodes.
- Une interface est toujours nommées par un nom commençant par un X.
De ces règles vous pouvez déduire que les méthodes sont TOUJOURS trouvées dans des interfaces, et les propriétés sont TOUJOURS trouvées dans des services.
Arbres IDL et programmation UNO
J'ai déjà eu l'occasion d'aborder la notion d'arbre IDL dans un chapitre précédent (voir Aller plus loin avec l'inspector Java). Ce chapitre me semble toutefois l'endroit tout indiqué pour aller plus loin dans les explications.
Nous avons suffisamment programmé l'API UNO pour en déduire un certain nombre de règles pour le langage C++.
Règle 1 : le langace C++ nous permet de "naviguer" d'une interface à une autre. Nous aborderons le problème de l'obtention de ces interfaces plus loin.
Règle 2 : si pour une raison ou une autre on est obligé de manipuler un service, il faudra le faire dans une variable de type com.sun.star.uno.XInterface. Ce type est une interface puisque son nom commence par un X, et mettre une variable d'un type dans une variable d'un autre type s'appelle transtyper. Nous aborderons plus loin le problème de l'obtention de ces services en C++.
Nous pouvons déduire de ces deux règles que le programmeur C++ devra, d'une manière ou d'une autre, retrouver des chemins pour aller d'une interface vers une autre. Si je pars d'une interface XTruc, vous pouvez appeler toutes ses méthodes ou chercher d'autres interfaces me conduisant à utiliser d'autres méthodes. Toutes les possibilités à partir de l'interface XTruc peuvent être représentées par un arbre : c'est cela que j'appelle arbre-IDL. Mon travail de programmeur va consister à trouver un chemin dans cet arbre et ce n'est pas toujours facile. J'ai déjà présenté les arbres-IDL (ou plus exactement les chemins dans cet arbre) dans ce document sous plusieurs formes :
- Représentation textuelle d'un arbre IDL.
- Représentation avec un outil d'introspection d'un arbre IDL.
- Représentation schématique d'un arbre IDL.
Avant d'aborder la manière dont on réalise les chemins au travers des arbres en C++ on va déjà revenir sur les fichiers IDL permettant de spécifier des modules, des interfaces et des services.
Specification IDL
Les interfaces sont spécifiées à l'aide d'un langage spécial, le langage IDL. UNO utilise UNO-IDL comme le langage de définition de l'interface. Le Langage de définition de l'Interface (IDL) est un langage descriptif (et non un langage de programmation) décrivant l'existence des interfaces qui seront rendues effectives par les objets. Avec IDL, vous définissez le nom de l'interface, les noms de chacun des attributs et méthodes. Une fois que vous avez créé les fichiers IDL, vous pouvez utiliser un compilateur IDL pour générer les fichiers d'en-tête dans le langage de programmation C++. La façon de spécifier des modules simples avec IDL est si claire que nous choisissons de commencer en premier seulement par des exemples.
Specifier une interface
Nous prenons comme exemple, l'interface XdrivingDirection de la Figure ci-dessous.
//Listing 2 Interface imaginaire XDrivingDirection
// IDL
interface XDrivingDirection
{
void turnLeft();
void turnRight();
};
Spécifier un service
L'exemple de la Figure ci-dessus est toujours utilisé, voici la spécification IDL correspondante :
//Listing 3 Spécification d'un service « car »
// IDL
interface XDrivingDirection
{
void turnLeft();
void turnRight();
};
interface XaccelerationControl
{
void speedUp();
void slowDown();
};
service car
{
// exported interfaces:
interface XdrivingDirection;
interface XaccelerationControl;
[attribute] float speed;
[attribute] float angle;
};
Nous voyons apparaître un type float et nous donnons d'autres types IDL plus loin.
Spécifier un module
Les modules sont un moyen de regrouper des services. Cette notion correspond plutôt à une bibliothèque et n'a que peu d'importance pour le programmeur C++ (sauf s'il désire réaliser des extensions composants ou addin par exemple). Nous donnons quand même ici la spécification IDL correspondant à un module :
//Listing 4 Spécification IDL du module my_module
// IDL
module my_module
{
interface Xsomething
{
void methodone();
};
service my_service1
{
// exported interfaces:
interface Xsomething;
};
interface XsomethingElse
{
void methodTwo();
void methodThree();
};
service my_service2
{
// exported interfaces:
interface XsomethingElse;
};
};
Plus loin avec IDL
Les types IDL sont décrits dans le tableau ci-dessous :
char |
16-bit unicode character type |
boolean |
boolean type; true and false |
byte |
8-bit ordinal integer type |
short |
signed 16-bit ordinal integer type |
unsigned short |
unsigned 16-bit ordinal integer type |
long |
signed 32-bit ordinal integer type |
unsigned long |
unsigned 32-bit integer type |
hyper |
signed 64-bit ordinal integer type |
unsigned hyper |
unsigned 64-bit ordinal integer type |
float |
processor dependent float |
double |
processor dependent double |
string |
string of 16-bit unicode characters |
any |
universal type, takes every fundamental or compound UNO type, similar to Variant in other environments or Object in Java |
void |
Indicates that a method does not provide a return value |
Les méthodes peuvent avoir des arguments. Chaque argument dans la liste des arguments doit commencer avec un des drapeaux de direction [in], [out] ou [inout] avant qu'un type connu et identificateur pour l'argument soit donné. Nous donnons un exemple que nous rencontrerons souvent dans ce document , un compteur :
//Listing 5 Module IDL décrivant un compteur
// IDL
module my_module
{
interface XSomething
{
long getCount();
void setCount( [in] long nCount );
long increment();
long decrement();
};
service MyService
{
interface XSomething;
};
};
Une interface peut être dérivée à partir d'une interface de base. Une interface dérivée peut déclarer ses propres attributs et ses méthodes. Les attributs et méthodes hérités ne peuvent pas être redéfinies dans l'interface dérivée. Un exemple d'héritage de l'interface :
//Listing 6 Héritage dog de annimal
//IDL
interface animal {
attribute long age;
};
interface dog : animal {
attribute short leg;
}
L'héritage multiple est aussi possible
interface dog : animal, friend {
L'héritage dans le service est présenté dans le prochain chapitre. Dans la terminologie objet OOo, il y a une différence entre attribut et propriété, différence qui se manifeste par leurs façons respectives d'y accéder. On accède aux propriétés avec setPropertyValue(PropertyName,Any) alors qu'on accède aux attributs avec la méthode set/get(AttributeName). Nous avons déjà rencontré la manipulation des propriétés lors de l'examen des formes.
Collecter de l'information UNO avec les fichiers IDL
Il y a plusieurs possibilités pour trouver de l'information sur UNO. La première est d'utiliser OOoBasic et l'outil XRay de Bernard Marcelly, voir les Tutoriels Basic. Point négatif : OOoBasic ne montre pas les propriétés et les méthodes exactes, quelques unes sont rajoutées parce qu'elles sont disponibles en OooBasic. L'autre possibilité est d'aller à l'adresse internet suivante : http://api.openoffice.org/docs/common/ref/index-files/index-1.html qui fournit la même information mais probablement de manière plus lisible. Nous avons fourni des exemples dans les chapitres antérieurs (en particulier chapitre 7...) et normalement le lecteur a des compétences sur le sujet.
Le point de vue de Danny Brewer
Néanmoins, il est important de comprendre le concept d'un "service" dans les documents sur l'API. Un service est juste une façon de grouper...
- d'autres services encore
- des interfaces
La partie (1) “d'autres services encore”, signifie bien sûr, qu'il y a même plus d'interfaces disponibles au service original. Laissez moi vous montrer différents exemples.
com.sun.star.sheet.SpreadsheetDocument est un service.
SpreadsheetDocument
contient le service com.sun.star.document.OfficeDocument et l'interface com.sun.star.sheet.XSpreadsheetDocument
comme le montre le fichier IDL ci-dessous :
//Listing 7 Interface Specification
//IDL
service SpreadsheetDocument
{
//-------------------------------------------------------------------------
/** common service for all types of documents.
*/
service com::sun::star::document::OfficeDocument;
..........
//-------------------------------------------------------------------------
/** provides access to the collection of spreadsheets.
*/
interface com::sun::star::sheet::XSpreadsheetDocument;
//-------------------------------------------------------------------------
Par conséquent, l'ensemble combiné d'interfaces de com.sun.star.sheet.SpreadsheetDocument et com.sun.star.document.OfficeDocument est accessible à un document de la Feuille de calcul (qui est bien sûr un com.sun.star.sheet.SpreadsheetDocument).
Donc, bien que le composant chargé depuis l'URL retourne une interface, cette interface représente un service sous-jacent qui est un SpreadsheetDocument
. En regardant les documents de l'API, vous pouvez dire quelles interfaces valides vous pouvez mettre en oeuvre.
SpreadsheetDocument
possède une interface com.sun.star.sheet.XSpreadsheetDocument.
Le service com.sun.star.document.OfficeDocument possède les interfaces com.sun.star.view.XPrintable et com.sun.star.frame.XStorable.
Comme SpreadsheetDocument
hérite de OfficeDocument
, il est aussi valide de demander soit l'interface com.sun.star.view.XPrintable soit l'interface com.sun.star.frame.XStorable à partir de ce service com.sun.star.sheet.SpreadsheetDocument.
Maintenant, remplaçons dans le paragraphe précédent, les documents tableurs par les documents textes et tout le discours précédent est encore valide. Comment expliquer ce qu'est un service sous-jacent ?
Il n'y a pas de formules magique pour cela. En principe, c'est évident. Si vous démarrez un tableur, par exemple, alors vous avez le service com.sun.star.sheet.SpreadsheetDocument.
De la même façon, si je crée un objet par son nom de service.....
' obtention d'un service en OOoBasic
oShape = oDoc.createUnoService( "com.sun.star.drawing.EllipseShape" )
alors je sais quel service c'est, parce que j'ai donné le nom du service dans l'instruction.
Oui, vous pouvez toujours dire quelles interfaces sont disponibles si vous savez le nom du service, et ce, seulement en regardant la documentation de l'API. Aucune hypothèse. Aucun besoin de XRay. C'est une science absolue. Les multiples interfaces valides sont les interfaces du service lui-même, et de tous les services qui seront hérités de ce service.
Dans certains cas, il est évident de savoir quels services vous avez.
Si vous appelez getCellRangeByName(), alors vous obtenez un service com.sun.star.sheet.SheetCellRange. Si vous appelez getCellByPosition(), alors vous avez un service com.sun.star.sheet.SheetCell. Beaucoup de choses identiques sont disponibles dans ces deux services com.sun.star.sheet.SheetCell et com.sun.star.sheet.SheetCellRange, mais ils sont de nature différents. Le service com.sun.star.sheet.SheetCellRange représente un groupe rectangulaire de cellules tandis que le service com.sun.star.sheet.SheetCell concerne une cellule unique. Il y a évidemment des choses que l'on peut faire avec une cellule unique mais pas avec un groupe de cellule.
Il y a aussi d'autres possibilités. Si vous obtenez un service com.sun.star.table.CellRange à partir d'une table sous OOoWriter ce sera différent que si vous l'obtenez depuis une feuille de calcul, puisque ce sera un com.sun.star.sheet.SheetCellRange. Le service SheetCellRange
est une version étendue du service CellRange
. Lequel des deux services est obtenu dépend donc si votre demande getCellRangeByName() est réalisée à partir d'une table ou à partir d'une feuille de calcul.
Parfois, spécialement pour l'application OooWriter, seul le guide du développeur est une aide précieuse, donnant des informations sur les services obtenus à partir d'autres services et des appels API. Mais il est toujours vrai que lorsque l'on connaît le service que l'on a, on peut en déduire directement, seulement à partir de la documentation de l'API toutes les interfaces qu'il est possible de demander. Pas d'essais inutiles, c'est une science exacte.
Un autre exemple concret
Les fichiers IDL sont disponibles dans le dossier <OpenOffice.org1.1_SDK>/idl/. Évidemment, le problème avec cette solution est que nous voyons uniquement l'API UNO du SDK installé, lequel peut être légèrement différent de notre Openoffice.org. Cependant, nous expliquerons cette possibilité après avoir mentionné juste une autre solution : l'exploration de la base de registres.
On veut maintenant montrer un exemple. On commence à partir d'un
- com::sun::star::document::OfficeDocument et du nom du service, on en déduit sa position dans l'arborescence <OpenOffice.org1.1_SDK>/idl/com/sun/star/document/OfficeDocument.idl
Ce fichier est présenté ci-dessous, en ayant pris soin de retirer les commentaires (voir com.sun.star.document.OfficeDocument) :
//Listing 7
//IDL
service OfficeDocument
{
interface com::sun::star::frame::XModel;
interface com::sun::star::util::XModifiable;
interface com::sun::star::frame::XStorable;
interface com::sun::star::view::XPrintable;
[optional] interface XEventBroadcaster;
[optional] interface XEventsSupplier;
[optional] interface XDocumentInfoSupplier;
[optional] interface XViewDataSupplier;
[optional] interface com::sun::star::view::XPrintJobBroadcaster;
[property, optional] boolean AutomaticControlFocus;
[property, optional] boolean ApplyFormDesignMode;
};
Si on examine maintenant le service "com.sun.star.text.TextDocument" on trouve dans <OpenOffice.org1.1_SDK>/idl/com/sun/star/text/TextDocument.idl
//Listing 8
service TextDocument
{
service com::sun::star::document::OfficeDocument;
interface com::sun::star::text::XTextDocument;
interface com::sun::star::util::XSearchable;
interface com::sun::star::util::XRefreshable;
....
};
Comme on peut voir, ce service com.sun.star.text.TextDocument contient le service com.sun.star.document.OfficeDocument. Cette dépendance est en fait un héritage. La représentation complète UML de cet exemple peut être trouvée dans le guide de développeur :
Tout paraît simple jusqu'ici parce qu'on est resté très vague et que l'on ne s'est pas déplacé très profondément dans l'arbre IDL. Voyons ces complications d'un peu plus près.
Services et C++, c'est pas simple
Si vous voulez bien comprendre le titre de cette section, lisez-là en vous posant systématiquement la question de savoir à tout moment quels sont les services disponibles. |
Il est grand temps maintenant d'aller plus loin dans notre exemple et de fournir du code avec commentaires. Pour cela nous allons prendre du code déjà abordé (voir le code correspondant pour OOoWriter).
//Listing 9 Writer Example
//C++
OUString sDocUrl;
osl::FileBase::getFileURLFromSystemPath(
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);
Reference< XComponent > xWriterComponent =
rComponentLoader->loadComponentFromURL(
sDocUrl,
OUString::createFromAscii("_blank"),
0,
Sequence < ::com::sun::star::beans::PropertyValue >());
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
Le code nous montre que la variable xWriterComponent est de type com.sun.star.lang.XComponent, c'est une interface qui nous donne le service com.sun.star.text.TextDocument et ainsi aussi le service com.sun.star.document.OfficeDocument comme déjà expliqué.
com.sun.star.text.XTextDocument est une Interface du service TextDocument
, cela est une chose facile à retenir parce que les deux noms ne diffèrent que par la lettre X. Mais allons encore plus loin.
Le fichier IDL com.sun.star.text.XTextDocument nous montre la méthode getText mais nous ne savons pas quels sont les nouveaux services disponibles dans la variable retournée par getText. Si l'on veut le savoir, il y a deux moyens :
- Internet XText interface nous donne la réponse : le service est com.sun.star.text.Text.
- L'autre manière est d'utiliser un outil d'introspection comme décrit plus tard dans cette section.
A partir de
//Listing 10 Writer Example (continuation)
//C++
Reference< XText > xText = xTextDocument->getText();
on essaie d'obtenir l'interface com.sun.star.text.XTextCursor
//Listing 11 Writer Example (continuation)
//C++
Reference< XTextCursor> xTextCursor = xText->createTextCursor();
Mais comment expliquer ce code ? Cherchant dans le fichier com.sun.star.text.XText nous trouvons seulement deux méthodes :
//Listing 12 XText Interface IDL file
// IDL
module com { module sun { module star { module text {
interface XText: com::sun::star::text::XSimpleText
{
void insertTextContent( [in] com::sun::star::text::XTextRange xRange,
[in] com::sun::star::text::XTextContent xContent,
[in] boolean bAbsorb )
raises( com::sun::star::lang::IllegalArgumentException );
void removeTextContent( [in] com::sun::star::text::XTextContent xContent )
raises( com::sun::star::container::NoSuchElementException );
};
}; }; }; };
Mais si vous regardez plus en détail dans ce fichier IDL, vous verrez que com.sun.star.text.XText hérite de com.sun.star.text.XSimpleText. Est-ce que la méthode createTextCursor est ici ? Oui, comme vous pouvez le voir.
//Listing 13 XSimpleText Interface IDL file
// IDL
module com { module sun { module star { module text {
interface XSimpleText: com::sun::star::text::XTextRange
{
com::sun::star::text::XTextCursor createTextCursor();
com::sun::star::text::XTextCursor createTextCursorByRange( [in] com::sun::star::text::XTextRange aTextPosition );
[oneway] void insertString( [in] com::sun::star::text::XTextRange xRange,
[in] string aString,
[in] boolean bAbsorb );
void insertControlCharacter( [in] com::sun::star::text::XTextRange xRange,
[in] short nControlCharacter,
[in] boolean bAbsorb )
raises( com::sun::star::lang::IllegalArgumentException );
};
}; }; }; };
Si avant de lire la suite vous savez répondre à la question : quels sont les services disponibles dans la variable xTextCursor du listing 11, alors Bravo. |
Quels sont les services disponibles ici ? J'ai utilisé un outil d'introspection pour la réponse, qui me donne :
******** Services : 8 com.sun.star.text.TextSortable com.sun.star.style.ParagraphPropertiesComplex com.sun.star.style.ParagraphPropertiesAsian com.sun.star.style.ParagraphProperties com.sun.star.style.CharacterPropertiesComplex com.sun.star.style.CharacterPropertiesAsian com.sun.star.style.CharacterProperties com.sun.star.text.TextCursor
Vous pouvez probablement trouver chacun d'entre eux via internet mais ce sera une tâche longue et fastidieuse : de bonnes raisons d'expliquer les services d'introspection plus loin dans ce chapitre.
A noter que c'est l'utilisation des méthodes retournant un type donné qui sont absolument difficiles à déchiffrer. Trouver les services accessibles est alors très difficile et, personnellement, je ne m'y aventure pas sans outil d'instrospection (voir un exemple ici). Bonne nouvelle quand même, il y a quand même une exception avec les méthodes createInstance et createInstanceWithContext pour lesquelles le service retourné est complètement déterminé.
|
Oui, voila décrit très superficiellement le travail du programmeur. Vous devez parcourir de tels chemins dans l'arbre IDL, pour trouver quoi faire en programmant. Heureusement il y a plus court en utilisant les exemples du SDK. Mais la plupart d'entre eux sont en Java, mais je dois avouer avoir trouvé beaucoup d'inspiration dans ces exemples même si je ne suis pas un programmeur Java.
IDL et C++
Ce problème est développé dans le guide du développeur ici.
Obtention d'une interface en C++
En C++, vous avez seulement des variables de type interface. Un des problèmes les plus souvent rencontrés met en oeuvre une interface. Ce problème se produit très rarement dans OooBasic mais très souvent dans C++/Java. On peut trouver des exemples divers à partir du chapitre 3 régulièrement jusqu'à ce chapitre.
Obtention d'une interface avec une fonction de la librairie
L'obtention d'une interface par une fonction de la librairie a déjà été rencontrée dans le code de démarrage. Nous le présentons ici sous forme schématique.
On part de nulle part mais utilisons une fonction toute prête, ici c'est defaultBootstrap_IntitialComponentContext()
qui nous permet d'obtenir une interface de type com.sun.star.uno.XComponentContext.
Obtention d'une interface avec la macro UNO_QUERY
Comme exemple, on suppose qu'on a obtenu une interface com.sun.star.text.XTextDocument. En général, c'est fait par quelque chose comme :
//Listing 14
//C++
// Impossible à faire en C++ comme cela : il faut transtyper OfDoc en Interface
Reference<com::sun::star::text::XTextDocument> OfDoc = something_to_get_this_interface();
ou
//Listing 15
//C++
using namespace com::sun::star::text;
....
Reference<XTextDocument> OfDoc = something_to_get_this_interface();
et nous voulons mettre en oeuvre l'interface com.sun.star.frame.XStorable pour sauver notre document. La figure ci-dessous nous montre toutes les interfaces que l'on peut obtenir à partir de com.sun.star.text.XTextDocument.
Il s'agit des interfaces com.sun.star.util.XRefreshable, com.sun.star.util.XSearchable, com.sun.star.frame.XModel, com.sun.star.util.XModifiable, com.sun.star.frame.XStorable et com.sun.star.view.XPrintable même si l'on n'a pas représenté les flèches rouges correspondantes sur le dessin.
Les trois étapes pour l'obtention d'une interface
Trois étapes sont impliquées pour l'obtention d'une de ses interfaces :
1) Ajoutez la ligne de votre code pour la demande de l'interface
// C++
// query from com::sun::star::frame::XStorable interface
Reference< XStorable > oToStore (OfDoc, UNO_QUERY);
Il s'agit d'une déclaration de variable avec initialisation. Si la variable est déjà déclarée, utilisez alors une version un peu différente :
// C++
// query from com::sun::star::frame::XStorable interface
oToStore = Reference< XStorable > (OfDoc, UNO_QUERY);
2) Ajouter à l'aide d'une directive d'inclusion les fichiers hpp correspondants. Il faut ajouter aussi les espaces de nommage correspondants. L'inclusion est faite par :
//C++
#include <com/sun/star/frame/XStorable.hpp>
et la gestion des espaces de nommage par :
//C++
using namespace com::sun::star::frame;
3) Ajouter les types correspondants dans le makefile comme montré ci-dessous dans la ligne com.sun.star.frame.XStorable \ qui est ajoutée
# Listing 16 Makefile # makefile # added com.sun.star.frame.XStorable TYPES := \ com.sun.star.uno.XNamingService \ .... com.sun.star.uno.XAggregation \ com.sun.star.frame.XStorable \ com.sun.star.lang.XMain \ ... com.sun.star.container.XHierarchicalNameAccess
Exemple concret
Appliquons les trois étapes sur un exemple concret. On peut schématiser tout cela simplement comme un chemin simple dans un arbre IDL :
Et voici un exemple de code correspondant.
//Listing 19 Simple UNO_QUERY call
// C++
OUString sDocUrl;
osl::FileBase::getFileURLFromSystemPath(
OUString::createFromAscii("/home/smoutou/Documents/demo.sxw"),sDocUrl);
Reference< XComponent > xWriterComponent = rComponentLoader->loadComponentFromURL(
sDocUrl,
OUString::createFromAscii("_blank"),
0,
Sequence < ::com::sun::star::beans::PropertyValue >());
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
// Ne pas oublier la direcive : #include <com/sun/star/frame/XStorable.hpp>
// ligne suivante correspond au schéma ci-dessus
Reference < XStorable > xStorable (xTextDocument,UNO_QUERY);
xStorable->store();
qui utilise les interfaces com.sun.star.text.XTextDocument et com.sun.star.frame.XStorable.
Quand pour obtenir une interface il faut passer par un service et par XMultiServiceFactory
On a déjà rencontré cela plusieurs fois, ainsi cela doit vous être familier. Mais, puisque nous n'avons pas discuté toutes les étapes en détail, je vais maintenant m'y consacrer et montrer comment cela fonctionne.
Le problème
Comment pouvez-vous obtenir une interface si le service correspondant n'est pas directement disponible ? Schématiquement le problème peut se représenter par :
où les deux services com.sun.star.text.TextDocument et com.sun.star.text.TextTable n'ont pas de dépendance soit par héritage, soit par inclusion (un des deux services contient l'autre).
Les solutions
Premier cas : une méthode de votre interface vous permet d'obtenir directement la nouvelle interface. C'était le cas du Listing 11 de ce chapitre. Dans ce cas le fichier hdl correpondant n'est pas requis et je n'ai pas trouvé de moyen simple pour trouver les nouveaux services disponibles sans outil d'introspection ! Voici comment ceci sera noté schématiquement dans les chemins des arbres IDL :
Règle 3 : lorsque vous obtenez une interface à partir d'une fonction membre vous ne devez pas construire les fichiers hdl en partant des fichiers IDL comme on doit le faire dans la méthode en trois étapes.
Second cas : aucune méthode de votre interface ne peut vous aider. Il vous faut demander un service avant d'obtenir l'interface. Cela peut être fait en deux ou trois instructions. J'ai déjà utilisé ces deux styles. Regardez dans le listing :
//Listing 20 Getting an Interface with XMultiServiceFacory
// C++
Reference < XTextDocument > xTextDocument (xWriterComponent,UNO_QUERY);
// deux instructions à partir d'ici
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);
// Ne pas oublier la directive d'inclusion : #include <com/sun/star/text/XTextTable.hpp>
Reference <XTextTable> xTable (oDocMSF->createInstance(
OUString::createFromAscii("com.sun.star.text.TextTable")),UNO_QUERY);
qui utilise le style "deux instructions" et les interfaces com.sun.star.text.XTextDocument et com.sun.star.text.XTextTable. Avec le style "trois instructions", on obtient l'interface comme présenté ci-dessous :
//Listing 21 Inserting a Table in a OOoWriter Document
// C++
Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);
Reference< XInterface > textTable = oDocMSF->createInstance(
OUString::createFromAscii("com.sun.star.text.TextTable") );
// Ne pas oublier la directive d'inclusion : #include <com/sun/star/text/XTextTable.hpp>
Reference< XTextTable > xTable(textTable, UNO_QUERY);
Notez que ces deux méthodes nécessitent une directive d'inclusion (et donc la construction) du fichier hpp correspondant (ici XtextTable.hpp) en travaillant comme pour l'obtention d'une interface en trois étapes. Mais le service ne nécessite pas de fichier d'inclusion car il est obtenu par une méthode (nommée «createInstance» dans ce cas) et de toute façon il est transtypé dans une com.sun.star.uno.XInterface (voir la règle 3 ci-dessus).
Nous donnons un schéma du chemin dans l'arbre IDL pour résumer ce dont nous venons de parler. Remarquez que dans ce chemin on repère très vite la situation par la présence de l'interface com.sun.star.uno.XInterface qui n'aurait aucune autre raison d'être présente.
Dernière question : est-il possible de partir de l'interface XMultiServiceFactory pour obtenir n'importe quelle interface ? La réponse est non. Regardez le code ci-dessous où j'ai pris rOfficeServiceManager au lieu de oDocMSF parceque c'est une interface XmultiServiceFactory aussi.
//Listing 22 Wrong code
// C++
// Reference<XMultiServiceFactory> oDocMSF (xTextDocument,UNO_QUERY);
// using rOfficeServiceManager instead oDocMSF
Reference< XInterface > textTable = rOfficeServiceManager->createInstance(
OUString::createFromAscii("com.sun.star.text.TextTable") );
Reference< XTextTable > xTable(textTable, UNO_QUERY);
if (!xTable.is()) {
printf("Erreur creation XTextTable interface !\n");
return 1;
}
Ce code se compile mais donne une erreur d'exécution. Cela signifie que l'on ne peut pas utiliser n'importe quelle interface com.sun.star.lang.XMultiServiceFactory pour obtenir n'importe quelle autre Interface.
Si vous travaillez avec un document demandez son interface XMultiServiceFactory correspondante avant d'envisager l'obtention d'un service particulier pour ce document.
|
Un autre exemple déjà présenté
Avant d'aller plus en avant, notez qu'un code utilisé plusieurs fois jusqu'ici, peut trouver des explications même si l'interface XMultiServiceFactory n'est pas encore associée à un document à ce stade du code :
//Listing 23 code de démarrage (bootstrap)
// C++
int main( ) {
//retrieve an instance of the remote service manager
Reference< XMultiServiceFactory > rOfficeServiceManager;
rOfficeServiceManager = ooConnect();
//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);
Facile de retrouver le style "trois instructions" pou obtenir l'interface com.sun.star.frame.XComponentLoader en passant par le service com.sun.star.frame.Desktop n'est-ce pas ?
Voici en résumé de manière schématique, le chemin dans l'arbre IDL correspondant au code ci-dessus :
Je ferai l'effort, dans la suite du document, de systématiquement montrer le changement de type du service en interface com.sun.star.uno.XInterface dans mes schémas. Il n'y a aucune autre raison de trouver cette interface dans un arbre IDL, et cela rendra plus facile le repérage de cette opération. |
Correspondances pour les modules et interfaces
On aborde très simplement, sans entrer dans les détails, la correspondance entre fichier IDL et le code C++ généré. Ce problème a été partiellement traité dans des cas très particuliers :
Voir le Developer's Guide pour un traitement plus complet.
Continuons donc par d'autres exemples :
//Listing 153
// IDL
module M
{ struct E { long L;
};
};
est compilé en C++ comme
//Listing 154
// C++
namespace M
{ struct E
{ Long L; };
}
et on peut faire référence à E en dehors de M par M::E. D'autre part une instruction de nommage peut être utilisée pour référer cette structure simplement comme E :
//Listing 155
// C++
using namespace M;
E e;
e.L = 3;
Une autre alternative est d'employer la directive de nommage seulement pour M::E :
//Listing 156
// C++
using M::E;
E e;
e.L = 3;
Une interface est réalisée à l'aide d'une classe C++ qui contient les définitions des types, constantes et exceptions définies dans l'interface. L'exemple ci-dessous montre le comportement de cette correspondance pour une interface :
//Listing 157
// IDL
interface A{
struct S {
short field;
};
};
est compilée en :
//Listing 158
// C++
class SAL_NO_VTABLE A {
struct S {
short fiel;
};
}; //A
On peut utiliser aussi :
//Listing 159
// Conformant uses
A::S s; // declare a struct variable
s.field = 3; // field access
// Non-conformant uses:
// one cannot declare an instance of an interface class...
A a; // ...nor declare a pointer to an interface class...
A *p; // ...nor declare a reference to an interface class.
void f(A &r);
Le service de Core reflection et son interface XIdlReflection
Beaucoup de points d'entrée pour l'introspection sont décrits dans le Developer's Guide. On en donne quelques uns et montrons le moyen d'en utiliser en C++.
Avant d'aborder le problème technique, rappelons l'intérêt des outils d'introspection. Nous avons sans cesse répété dans ce chapitre que la grande difficulté de la programmation UNO est de savoir à tout moment, quels sont les services et interfaces disponibles. Cette information est contenue dans les fichiers IDL, mais, de mon point de vue, partiellement seulement. C'est pour cela qu'un outil d'introspection est intéressant : il peut à tout moment vous fournir l'information tant convoitée.
L'introspection et OOoBasic
Cette section n'a pas pour vocation de remplacer l'inestimable outil de Bernard Marcelly, a savoir, XRay. Voir pour cela une description dans ce wiki. |
OooBasic permet beaucoup de choses et en particulier l'introspection. Le code de Danny Brewer présenté ici : http://www.oooforum.org/forum/viewtopic.php?t=8737 nous montre comment ? Examinons un peu plus en détail ce code :
'Listing 160 Code d'exploration de la base de registre en OOoBasic
REM ***** BASIC *****
Sub Main
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )
oInfo = oReflection.forName( "nom.dannybrewer.test.XDannysCalcFunctions1" )
aMethods = oInfo.getMethods()
For i = 0 To UBound( aMethods )
oMethod = aMethods( i )
Print oMethod.getName()
Next
End Sub
puis nous créons un fichier IDL :
//Listing 161 Fichier IDL d'exemple
// IDL
#include <com/sun/star/uno/XInterface.idl>
#include <com/sun/star/lang/XInitialization.idl>
module my_module
{
interface XSomething : com::sun::star::uno::XInterface
{
long getCount();
void setCount( [in] long nCount );
long increment();
long decrement();
};
service MyService
{
interface XSomething;
};
};
Avec ce fichier IDL il nous est possible de créer un fichier rdb et de l'enregistrer dans la base de registre. Maintenant OpenOffice.org fonctionne comme si nous avions une interface supplémentaire même si l'on n'a pas encore écrit le code correspondant. Evidemment, il nous est impossible d'utiliser ce service puis qu'il n'y a pas de code correspondant, mais on peut le voir. Pour cela on modifie légèrement le code de Danny :
'Listing 162
REM ***** BASIC *****
'From Danny : http://www.oooforum.org/forum/viewtopic.php?t=8737
Sub Main
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )
oInfo = oReflection.forName( "my_module.XSomething" )
aMethods = oInfo.getMethods()
'XRay.XRay oInfo
print UBound( aMethods )+1 & " methods : ****"
For i = 0 To UBound( aMethods )
oMethod = aMethods( i )
Print oMethod.getName()
Next
aTypes = oInfo.getTypes()
print UBound( aTypes )+1 & " types : ****"
For i = 0 To UBound( aTypes )
oType = aTypes( i )
Print "Types : " + oType.getName()
Next
aInterfaces = oInfo.getInterfaces()
print UBound( aInterfaces )+1 & " interfaces : ****"
For i = 0 To UBound( aInterfaces )
oInterface = aInterfaces( i )
Print "Interfaces : " + oInterface.getName()
Next
End Sub
qui lancé, produit l'affichage suivant :
7 methods : **** queryInterface acquire release getCount setCount increment decrement 3 types : **** Types : com.sun.star.reflection.XIdlClass Types : com.sun.star.lang.XTypeProvider Types : com.sun.star.uno.XWeak 0 Interfaces : ****
où l'on peut voir parmi d'autres choses les quatre méthodes données dans le fichier IDL.
Il est possible de retrouver un peu plus d'information sur les méthodes par exemple. Si vous voulez retrouver tout ce que vous avez dans les fichiers IDL, y compris le nom et type des paramètres, l'extrait de code OOoBasic suivant fait l'affaire :
For i = LBound( oMethods ) To UBound( oMethods )
oMethod = oMethods( i )
' Check the method's interface to see if
' these aren't the droids you're looking for.
sString = oMethod.getReturnType().getName() & " " & oMethod.getName() & "("
parametersInfo = oMethod.getParameterInfos()
if UBound(parametersInfo) > 0 then
for ii=0 to UBound(parametersInfo)
if parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.IN Then
stringType = "IN "
elseif parametersInfo(ii).aMode = com.sun.star.reflection.ParamMode.OUT Then
stringType = "OUT "
else
stringType = "INOUT "
end if
sString = sString & stringType & ParametersInfo(ii).aType.getName() & " " & parametersInfo(ii).aName
if ii < UBound(parametersInfo) Then sString = sString & ", "
Next
end if
sString = sString & ")"
' Faire quelquechose avec sString ici, par exemple l'afficher
Next
Pour aller plus loin en C++ voyez la section suivante sur l'interface XdlRefection.
L'interface XIdlReflection
L'interface com.sun.star.reflection.XIdlReflection est décrite dans la section CoreReflection Service in Developer's Guide. Cette interface est aussi décrite ici et en français et avec en prime du code C++.
The XIntrospection Interface
Cette interface com.sun.star.beans.XIntrospection est décrite ici avec des exemples de code. Un autre exemple de code est donné dans la section Utilitaires C++. Voir aussi Introducing the OpenOffice.org_API et OOoBasic Introspection et Developer's Guide.
Utilisation de l'Inspecteur Java
Pour une introduction de la programmation en Java pour OOo, voir Java and Eclipse tutorial. Ce point n'est pas abordé dans ce tutorial : nous sommes seulement intéressé ici dans l'utilisation d'un composant Java à partir d'un programme C++.
Il est possible, en principe, d'utiliser l'Inspector Java à partir de n'importe quel langaga parcequ'il s'agit justement d'un composant. La méthode d'utilisation est très simple :
1°) Compiler l'exemple Java dans <OpenOffice.org_SDK>/examples/java/Inspector après ajout de SDK_AUTO_DEPLOYMENT = YES au début du makefile.
2°) Créer un exemple OOoBasic, par exemple (OOo1.1.X) :
'Listing 17 Simple OOoBasic example to call the Java Inspector
REM ***** BASIC *****
Sub JavaInspector
o = createUnoService("org.OpenOffice.InstanceInspector")
'XRay o
oReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )
o.inspect(oReflection)
End Sub
Pour une utilisation du Java Inspector plus récent, voir Calling from a Basic Macro |
.
Si Java n'est pas correctement intallé l'exécution de ce programme déclenchera l'ouverture d'une boîte de dialogue qui vous permettra de définir votre machine virtuelle JRE à condition de savoir où elle se trouve.
Nous voyons ci-dessous le résultat de l'exécution de ce programme.
Notre problème est d'utiliser l'Inspecteur java à partir du C++. J'ai rencontré plusieurs problème pour faire cela et je présente la voie que j'ai choisie :
- construction d'un fichier urd à partir du fichier IDL (dans le makefile)
- Ne pas oublier d'enregistrer le fichier urd dans la base de registres (avec le makefile)
- ajouter org.OpenOffice.XInstanceInspector dans les TYPES du makefile
- copie du fichier IDL de <OpenOffice.org1.1_SDK>/examples/java/Inspector/XInstanceInspector.idl vers <OpenOffice.org1.1_SDK>/idl/org/OpenOffice/ XInstanceInspector.idl
- ajout de l'inclusion #include <org/OpenOffice/XInstanceInspector.hpp> et de l'espace de nommage namespace org::OpenOffice;
- ajout de ce code
// C++
Any toInspect;
toInspect <<= rDesktop;
Reference< XInstanceInspector > xinspect (rOfficeServiceManager->createInstance(
OUString::createFromAscii( "org.OpenOffice.InstanceInspector" )),UNO_QUERY);
xinspect->inspect(toInspect);
Et cela fonctionne comme en OOoBasic. Le makefile correspondant pour Linix est :
#Listing 18 Simple Makefile to compile a Java Inspector C++ call # very simple makefile HELPER = ReflectionHelper CXXFILE = office_connect.cxx OBJFILE = office_connect.o OUTBIN = office_connect OUT_COMP_INC = ../../../../LINUXexample.out/inc OUT_COMP_OBJ = ../../../../LINUXexample.out/obj OUT_COMP_BIN = ../../../../LINUXexample.out/bin # added for Inspector OUT_COMP_URD = $(OUT_COMP_BIN) # end added COMPONENT_RDB = $(OUT_COMP_BIN)/office_connect.rdb CC_FLAGS = -c -O -fpic -fno-rtti CC_DEFINES = -DUNX -DGCC -DLINUX -DCPPU_ENV=gcc3 PS = / TYPES := \ com.sun.star.uno.XNamingService \ .... com.sun.star.container.XHierarchicalNameAccess \ org.OpenOffice.XInstanceInspector # last line added TYPESLIST = $(foreach t,$(TYPES),-T$(t)) GENHPPFILES = $(foreach t,$(TYPES),$(OUT_COMP_INC)/$(subst .,/,$(t)).hpp) ALL : \ ProUNOCppBindingExample # added for Inspector #building urd file $(OUT_COMP_URD)/XInstanceInspector.urd : ../../../../idl/org/OpenOffice/XInstanceInspector.idl -mkdir -p $(OUT_COMP_URD) idlc -I. -I../../../../idl -O$(OUT_COMP_URD) ../../../../idl/org/OpenOffice/XInstanceInspector.idl # end added #office_connectrc is provided with SDK $(OUT_COMP_BIN)/office_connectrc : office_connectrc -mkdir -p $(OUT_COMP_BIN) cp office_connectrc $(OUT_COMP_BIN)/office_connectrc $(COMPONENT_RDB) : $(OUT_COMP_URD)/XInstanceInspector.urd -mkdir -p $(OUT_COMP_BIN) # added for Inspector regmerge $(COMPONENT_RDB) /UCR $(OUT_COMP_URD)/XInstanceInspector.urd # end added regmerge $(COMPONENT_RDB) / "/usr/lib/openoffice/program/types.rdb" @echo -------------------------------------------------------------------------------- @echo Register necessary runtime components in $(COMPONENT_RDB) @echo -------------------------------------------------------------------------------- regcomp -register -r $(COMPONENT_RDB) -c connector.uno.so regcomp -register -r $(COMPONENT_RDB) -c remotebridge.uno.so regcomp -register -r $(COMPONENT_RDB) -c bridgefac.uno.so regcomp -register -r $(COMPONENT_RDB) -c uuresolver.uno.so # @echo bla > $@ $(GENHPPFILES) : $(subst /,$(PS),$(@D)) mkdir -p $(subst /,$(PS),$(@D)) # modified for Inspector cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) "/usr/lib/openoffice/program/types.rdb" cppumaker -Gc -BUCR -O$(OUT_COMP_INC) $(TYPESLIST) $(COMPONENT_RDB) $(OUT_COMP_OBJ)/$(OBJFILE) : $(CXXFILE) $(GENHPPFILES) $(HELPER).hpp -mkdir -p $(subst /,$(PS),$(@D)) gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(OBJFILE) $(CXXFILE) $(OUT_COMP_OBJ)/$(HELPER).o : $(HELPER).cxx $(HELPER).hpp -mkdir -p $(OUT_COMP_OBJ)/ gcc $(CC_FLAGS) $(CC_INCLUDES) -I. -I/usr/include -I$(OUT_COMP_INC)/examples \ -I../../../../include -I$(OUT_COMP_INC) $(CC_DEFINES) -o$(OUT_COMP_OBJ)/$(HELPER).o $(HELPER).cxx $(OUT_COMP_BIN)/$(OUTBIN) : $(OUT_COMP_OBJ)/$(OBJFILE) $(OUT_COMP_OBJ)/$(HELPER).o -mkdir -p $(OUT_COMP_BIN) gcc -Wl -export-dynamic -L../../../../LINUXexample.out/lib -L../../../../linux/lib -L/usr/lib/openoffice/program \ $(OUT_COMP_OBJ)/$(HELPER).o \ -o$(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_OBJ)/$(OBJFILE) -lcppuhelpergcc3 -lcppu -lsalhelpergcc3 -lsal -lstlport_gcc ProUNOCppBindingExample : $(COMPONENT_RDB) $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc @echo -------------------------------------------------------------------------------- @echo Please use one of the following commands to execute the examples! @echo @echo make office_connect.run @echo -------------------------------------------------------------------------------- office_connect.run : $(OUT_COMP_BIN)/$(OUTBIN) $(OUT_COMP_BIN)/office_connectrc cd $(OUT_COMP_BIN) && $(OUTBIN)
Note 1 : The New Object Inspector apparaît dans le SDK après la version 2.0. Il est plus complexe et capable de générer du code Java, C++ ou OOoBasic. Je n'ai pas testé le code ci-dessus avec the new object inspector mais ne vois pas pourquoi cela ne fonctionnerait pas correctement. |
Note 2 : Un petit exemple avec the new object inspector peut être trouvé dans ce document. |
Traduire des programmes OooBasic en C++
La traduction des programmes OooBasic en C++ n'est pas si immédiate que cela. Les interfaces et attributs vus par les programmes OooBasic sont construits à travers un pont (bridge) pour des questions de facilité. Alors ce qui est vu en OooBasic ne sera pas forcément vu en C++. Une des conséquences de tout cela est qu'il est impossible de réaliser cette traduction sans passer un peu de temps avec les fichiers IDL.
Quand j'ai abordé Writer, j'ai laissé le lecteur résoudre un certain nombre de problèmes (particulièrement les problèmes de curseurs). Nous choisissons ces problèmes ici comme exemple. Nous commençons par donner le programme OOoBasic de départ.
'Listing 36 Simple OOoBasic program to translate
REM **** OOoBasic
Dim MyDocument As Object, MyText As Object
Dim MyCursor As Object
MyDocument = ThisComponent
MyText = MyDocument.Text
MyCurseur= MyTexte.createTextCursor
MyCurseur.goRight(1, false) ' move right one character
MyCurseur.goLeft(2, true) ' select the two previous characters
Toutes les instructions OOoBasic pour bouger le curseur sont résumées dans le tableau ci-dessous :
- OOoBasic instructions
Méthode | Signification |
goRight(n, false) | bouge le curseur d'un nombre spécifié de caractères vers la droite |
goLeft(n, false) | bouge le curseur d'un nombre spécifié de caractères vers la gauche |
gotoStart(false) | bouge le curseur au début du texte |
gotoEnd(false) | bouge le curseur à la fin du texte |
gotoStartOfParagraph(false) | bouge le curseur au début du paragraphe courant |
gotoEndOfParagraph(false) | bouge le curseur à la fin du paragraphe courant |
gotoNextParagraph(false) | bouge le curseur au prochain paragraphe |
gotoPreviousParagraph(false) | bouge le curseur au précédent paragraphe |
gotoNextWord(false) | bouge le curseur au prochain mot |
gotoPreviousWord(false) | bouge le curseur au précédent mot |
gotoStartOfWord(false) | bouge le curseur au début du mot courant |
gotoEndOfWord(false) | bouge le curseur à la fin du mot courant |
gotoNextSentence(false) | bouge le curseur au début de la prochaine phrase |
gotoPreviousSentence(false) | bouge le curseur au début de la précédente phrase |
gotoStartOfSentence(false) | bouge le curseur au début de la phrase courante |
gotoEndOfSentence(false) | bouge le curseur à la fin de la phrase courante |
Mais si vous voulez traduire l'utilisation de ces fonctions en C++, il vous faut obtenir les interfaces en partant de l'interface XtextCursor interface (voir plus bas en Listing 41). Cela rend la traduction difficile. Par exemple trois interfaces curseur différentes en utilisant les méthodes OOoBasic du programme de départ. Il est grand temps de montrer les fichiers IDL correspondants.
Commençons par la première de toutes, l'interface com.sun.star.text.XWordCursor est montrée maintenant :
//Listing 37 XWordCursor interface (IDL file)
// IDL
module com { module sun { module star { module text {
interface XWordCursor: com::sun::star::text::XTextCursor
{
boolean isStartOfWord();
boolean isEndOfWord();
boolean gotoNextWord( [in] boolean bExpand );
boolean gotoPreviousWord( [in] boolean bExpand );
boolean gotoEndOfWord( [in] boolean bExpand );
boolean gotoStartOfWord( [in] boolean bExpand );
};
}; }; }; };
L'interface com.sun.star.text.XParagraphCursor est montrée maintenant :
//Listing 38 XParagraphCursor interface (IDL file)
// IDL
module com { module sun { module star { module text {
interface XParagraphCursor: com::sun::star::text::XTextCursor
{
com::sun::star::text::XParagraphCursor::isStartOfParagraph
boolean isStartOfParagraph();
boolean isEndOfParagraph();
com::sun::star::text::XParagraphCursor::gotoStartOfParagraph
boolean gotoStartOfParagraph( [in] boolean bExpand );
com::sun::star::text::XParagraphCursor::gotoEndOfParagraph
boolean gotoEndOfParagraph( [in] boolean bExpand );
boolean gotoNextParagraph( [in] boolean bExpand );
com::sun::star::text::XParagraphCursor::gotoPreviousParagraph
boolean gotoPreviousParagraph( [in] boolean bExpand );
};
}; }; }; };
et pour finir l'interface com.sun.star.text.XSentenceCursor :
// Listing 39 XSentenceCursor interface (IDL file)
// IDL
module com { module sun { module star { module text {
interface XSentenceCursor: com::sun::star::text::XTextCursor
{
boolean isStartOfSentence();
boolean isEndOfSentence();
boolean gotoNextSentence( [in] boolean Expand );
boolean gotoPreviousSentence( [in] boolean Expand );
boolean gotoStartOfSentence( [in] boolean Expand );
boolean gotoEndOfSentence( [in] boolean Expand );
};
//=============================================================================
}; }; }; };
Si vous voulez savoir quelles interfaces vous pouvez demander il vous faut retrouver le service. Pour notre exemple c'est le service com.sun.star.text.TextCursor. Voici son fichier IDL où vous voyez les interfaces que vous pouvez demander.
//Listing 40 TextCursor service (IDL file)
// IDL
module com { module sun { module star { module text {
service TextCursor
{
service com::sun::star::text::TextRange;
interface com::sun::star::text::XTextCursor;
[optional] interface com::sun::star::text::XWordCursor;
[optional] interface com::sun::star::text::XSentenceCursor;
[optional] interface com::sun::star::text::XParagraphCursor;
interface com::sun::star::beans::XPropertySet;
interface com::sun::star::beans::XPropertyState;
interface com::sun::star::beans::XMultiPropertyStates;
[optional] interface com::sun::star::document::XDocumentInsertable;
[optional] interface com::sun::star::util::XSortable;
};
}; }; }; };
Si vous partez de nouveau du Listing 11 il vous faudra un UNO_QUERY pour obtenir l'interface com.sun.star.text.XWordCursor.
//Listing 41 Using XwordCursor Interface
// C++
// Don't forget to add : #include <com/sun/star/text/XWordCursor.hpp>
// Don't forget to add "com.sun.star.text.XWordCursor \" in the makefile
Reference < XWordCursor > xWordCursor (xTextCursor,UNO_QUERY);
xWordCursor->gotoNextWord(false);
xWordCursor->gotoNextWord(false);
xWordCursor->gotoNextWord(true);
La traduction peut probablement se faire automatiquement, mais un tel traducteur aurait besoin de connaissances sur les fichiers IDL.
En passant nous avons encore les huit services disponibles :
******** Services : 8 com.sun.star.text.TextSortable com.sun.star.style.ParagraphPropertiesComplex com.sun.star.style.ParagraphPropertiesAsian com.sun.star.style.ParagraphProperties com.sun.star.style.CharacterPropertiesComplex com.sun.star.style.CharacterPropertiesAsian com.sun.star.style.CharacterProperties com.sun.star.text.TextCursor
La traduction de OOoBasic en C++ nécessite donc une bonne connaissance des services. Par exemple, le code
Dim Obj As Object Obj = createUnoService("com.sun.star.frame.Desktop")
est différent de
Dim RectangleShape As Object
RectangleShape = _
Spreadsheet.createInstance("com.sun.star.drawing.RectangleShape")
Le deuxième dénote un objet contextuel.
Les objets contextuels sont généralement créés par une méthode d'objet dont dépend l'objet. La méthode createInstance, définie dans l'interface XMultiServiceFactory, est notamment utilisée dans les objets Document.
Voir Introduction à l'API StarOffice pour plus d'informations.
J'ai eu aussi l'occasion de traduire des programmes OOoBasic dans les chapitres Composants et boîte de dialogue et Plus loin avec les composants et les boîtes de dialogue.
Retour à la page d'accueil
Page d'accueil du développement C++ à l'aide du SDK
Voir aussi
- Introduction à l'API StarOffice
- C++ and UNO tutorial
- UNO tutorial
- UNO IDL
- Uno/Article/Types&Reflection
- Introduction to the OpenOffice.org API
- Writing a Program to Control OpenOffice.org, by Franco Pingiori — Part 1 and Part 2, Linux Journal
- Voir aussi The New Object Inspector
- Extensions Introspection
- BASIC UNO Object Browser