Automation de Word avec les MFC [Résolu]

Signaler
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005
-
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
-
Bonjour,



j'essaie de faire un petit programme permettant de compléter un fichier .doc via la technologie OLE Automation de Word.



J'arrive à ouvrir le .doc, à aller jusqu'aux signets qui m'intéressent, écrire du texte puis sauvegarder et fermer le document.

Je souhaite maintenant insérer une image à partir d'un fichier dans le document.



A l'heure actuelle je n'ai pas trouvé grand chose à ce sujet, .



Je pensais au début utiliser la fonction Selection::InsertFile
mais quand je l'utilise lors de l'exécution Windows m'enguirlande en me
disant que le type n'est pas bon (le type de quoi je sais pas).

COleVariant Range ;

COleVariant confirmConv;

COleVariant link;

COleVariant attachment ;



Range.vt = VT_DISPATCH ;

Range.ppdispVal = (0,0) ;



confirmConv.vt = VT_BOOL ;

link.vt = VT_BOOL ;

attachment.vt = VT_BOOL ;



confirmConv.boolVal = false ;

link.boolVal = false ;

attachment.boolVal = false ;



//wchar_t t_test ;

char test[20] ;

sprintf(test, "test.doc") ;


// MultiByteToWideChar (CP_OEMCP,MB_PRECOMPOSED,test,-1,&t_test,0) ;



selObj.InsertFile(


_T("test.doc"), // chemin du fichier à insérer


&Range, // If the
specified file is a Word document,


// this parameter refers to a bookmark. If the file is another type


// (for example, a Microsoft Excel worksheet),


// this parameter refers to a named range or a cell range


// (for example, R1C1:R3C4).


&confirmConv, // demande à l'utilisateur de confirmer
l'insertion du fichier : true sinon false


&link, // True to
insert the file by using an INCLUDETEXT field.


&attachment // True to insert the file as
an attachment to a WordMail message

) ;


J'ai vu en VB qu'ils utilisaient : docWord.Selection.InLineShapes.AddPicture



En c++, cela devrait devenir : selOvj.GetInLineShape() mais après je n'ai aucune fonction ressemblant à un AddPicture



Est ce que vous auriez une idée ?



Alice

19 réponses

Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

enfin ma quête est terminée !



Pour ceux que cela intéresse voici comment insérer une image dans word via un pgme C++ et les MFC :



COleVariant covTrue((short)true) ;

COleVariant covFalse((short)false) ;

COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR) ; // arguments optionnel



Shapes _shapes ;

_shapes = oDoc.GetShapes() ; //oDoc est le document en cours dans word



Range oRange = selObj.GetRange();


// selObj est la position de la sélection en cours,
ici correspond au signet à partir duquel on insère la photo



VARIANT vTargetRange;

vTargetRange.vt = VT_DISPATCH;

vTargetRange.pdispVal = oRange; // récupération du Range, position signet



// Ajout d'une image dans le fichier word

_shapes.AddPicture(

// filename

"D:/test.jpg",

// image issue d'un fichier lié au document word

covFalse,

// image enregistrée dans le fichier

covTrue ,

covOptional, covOptional, covOptional, covOptional,

&vTargetRange) ;
......



Special Thanks to Speedo, le chat Potté !



Alice


"A coeur Vaillant, rien d'impossible" (cfg. Chev. BA
YARD)
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
mais est-tu placé dans la classe Document quand tu appelles InLineShapes?
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
bonjour Alice,

tu devrais peut-être regarder la bibliothèque Word. AddPicture se trouve dans la Class InLineShape, qui se trouve elle même dans la class Selection, qui se trouve dans la class Application.
Pour voir ces class fais Alt + F11, puis F2.

En gros ça donnerait quelquechose comme ça:

// Déclaration
Variant vMSWord;
Variant vFileName;
Variant vSelection;
Variant vInLineShape;

// Connection ou ouverture de Word
try {
vMSWord = Variant::GetActiveObject("WordApplication");
} catch(...) {
vMSWord = Variant::CreateObject("Word.Application");
}
vFileName=C:\\Mes Documents\\MonImage;" // Chemin d'accès de ton image

vSelection = vMSWord.OlePropertyGet("Selection");
vInLineShape = vSelection.OlePropertyGet("InLineShape");
vInLineShape.OleFunction("AddPicture",vFileName); //ouverture

En espérant que cela puisse t'aider!
Tiens moi au courant!!


Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

je n'est pas accès directement à Variant mais à COleVariant

mais je sais comment récpérer la sélection.

pour le inLineShape merci à toi, tu m'as enlevé mon doute quand à la fonction getInLineShape, c'est le bon.



Après je n'ai pas de OleFunction mais possibilité de faire un invoke ()



je vais chercher de ce côté là.



Merci encore.







Alice



PS : alors là il est trop mimi ce chat !!! (c'est pas celui de shrek ?)
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
tu n'as pas de OleFunction?? tu codes en quoi? et avec quoi? tu avais compris que Selection
InLineShape;AddPicture font parti du VB de Word?


P.S. Vi, c'est le Chat ...Potté!
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

C'est bien ce qui me semblait ....

Mais je code pas avec l'éditeur de word ......



Je code en C++ avec les MFC et j'utilise VC++ 6.0
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
je sais que tu code pas avec l'éditeur de word.
en fait he code en C++ (borland C++ builder) et j'appelle les fonctions et propriétés contenu dans Word (fonctions et propiétés en VB que tu vois dans l éditeur de Word)

Donc en résume mon code est du C++ qui pilote Word!!!
Donc... ça devrait être le même principe pour ton Visual C++.. non?

Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

Efectivement c'est ce que je fais (analogiquement parlant)



donc je cherche toujours la fonction qui me permettrait d'appeler quelquechose du style AddPicture ...
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
tu arrive à appeler Word, Selection, InLineShapes ?
mais pas AddPicture??

Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

e suis toujours sur ces histoires d'automatisation de Word .





je souhaite modifier en cours de route la police du texte à écrire dans mon fichier word.




_Font font ;



font.m_lpDispatch = selObj.GetFont();



font.SetName("Comic Sans MS");



font.SetSize(16);



font.SetBold(3) ;



selObj.SetFont(font) ;



selObj est ma sélection en cours dans mon document word.





Si je ne mets pas selObj.SetFont tout ce passe bien mais la police n'est pas mise à jour.


Quand selObj.SetFont est présent, la police est mis à jour et windows me dit "mauvais paramètre" et me jette.





j'ai été voir SetFont et en entrée cela prend un LPDISPATCH et si je
lui passe directement font.m_lpdispatch, le problème est le même.



t'aurais pas une idée ?
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

C tout à fait ça j'arrive à l'obtention de l'objet inLinShape mais après je n'ai pas de fonctionnalité style AddPicture :





LPDISPATCH pDisp ;

pDisp = selObj.GetInlineShapes() ;



mais après j'ai un addRef () ou un invoke (....), je pense qu'il faut que je comprenne ce qu'est invoke mais c'est pas gagné.



ou alors je n'ai pas trouvé la bonne classe qui récupère le inLineShapes.
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

bon pour le problème des font j'ai résolu le problème.



il faut d'abord mettre le texte puis lui appliuer la font choisie.





en fait il faut d'abord aller au signet qui nous intéresse (ou à l'endroit où l'on souhaite écrire)


puis écrire le texte


et enfin mettre à jour la police qui ne prendra en compte que le texte qui vient d'être écrit.





V'là l'astuce à 2 balles .....



selObj.InsertAfter("ton texte à ajouter") ; // selObj est la sélection en cours



//-------------------------------------



// Modification de la police et de la taille du texte



font.m_lpDispatch = selObj.GetFont();



font.SetName("Comic Sans MS");



font.SetSize(16);



font.SetBold(3) ;



selObj.SetFont(font) ;






Et voili voilà c'est résolu, reste plus que le coup de l'image à
insérer dans word et ça sera pas mal




Alice
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

Hé bien je pense que oui, vois plutôt :



...

//-----------------------------------------

// ouverture d'un document

Documents oDocs(app.GetDocuments()) ;

_Document oDoc ;



oDoc.AttachDispatch( oDocs.Open(





COleVariant(nameFile),




covFalse, //
Confirm Conversion




covFalse, //
ReadOnly




covFalse, //
AddToRecentFiles




covOptional,
// PassWord Document




covOptional,
// PassWord Template




covFalse, //
Revert




covOptional,
// WritePassWord Document




covOptional,
// WritePassWord Tempalte




covOptional,
// Format




covOptional,
// Encoding




covTrue
// Visible




)



) ;



//-----------------------------------------

// accéder à un signet :

Bookmarks vBookMarks;



Selection selObj(app.GetSelection()) ; // pour écrire



// récupération de la liste des signets

vBookMarks = oDoc.GetBookmarks() ;



// test si le signet cherché appartient à cette liste

if (vBookMarks.Exists("titi"))

{

Bookmark vBookMark ;

// récupération du signet cherché et activation du signet


vBookMark.AttachDispatch(
vBookMarks.Item( COleVariant("Titi") ) ) ;



//-------------------------------------

// écriture d'un texte à la fin d'un signet

long startPos, endPos ;

startPos endPos 0 ;



startPos = vBookMark.GetStart();

endPos = vBookMark.GetEnd() ;



selObj.AttachDispatch(app.GetSelection()) ;

selObj.SetRange(startPos,endPos) ;



selObj.InsertAfter("Chat Potté !!!\n") ;

......



---> et là il m'écrit bien Chat Potté au bon en droit dans mon document.



---> je récupère GetInLineShape à partir de selObj.



je suis entrain de tester la méthode invoke que je peux appeler à partir de LPDISPATCH fourni par cette fonction.

Invoke permet à priori d'éxécuter tout un tas de méthode si tu connais leur dispid.



J'ai réussi à récupérer la dispid de "addPicture",
il me reste à comprendre comment fonctionnent les arguments que l'on
passe à cette méthode, là c'est plutôt du 6ème sens ou de l'intuition
(féminine) vu que la doc me fait un peu défaut.









Alice
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
impressionnant l'intuition féminine!
Quel puissant outil!!!

PS: joli l'avatar!


Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

Te moque pas trop quand même ....

J'rigolai c tout !



J'ai vraiment très peu d'infos/ docs sur ce sujet .



Et comme je commence à glisser doucement dans le puit de la folie des COle :

j'essaye de faire appel à cette fameuse intuition mythique qui nous appartient à nous les femmes.



remarque il parait que les chats ont neuf vies et un 6ème sens bien développé...


sinon plus sèrieusement dans mon code je sais que le mot "addPicture" existe et est reconnue :



DISPID dispid;


OLECHAR FAR * szMember = OLESTR("addPicture");

COleVariant vtInLineShapes ;

vtInLineShapes.vt = VT_DISPATCH ;


vtInLineShapes.pdispVal = selObj.GetInlineShapes() ;







if(
vtInLineShapes.pdispVal->GetIDsOfNames(IID_NULL,&szMember,1,LOCALE_SYSTEM_DEFAULT,&dispid)
S_OK)

//ça marche

else

// ça marche pas



--> GetIDsOfNames me retourne bien un S_ok, donc tout c'est bien passé et la commande a été trouvée.



maintenant je me bagarre avec invoke ....



te tiens au courant.





si tas d'autres idées n'hésite pas !





PS : Merci ! je trouve aussi
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

J'ai trouvé un autre moyen d'arrivé à AddPicture :



Shapes _shapes ;

_shapes = selObj.GetInlineShapes() ;



COleVariant _left ;

COleVariant _top ;

COleVariant _Width ;

COleVariant _Height ;

COleVariant _linkToFile ;

COleVariant _saveWithDoc ;

_linkToFile.vt = VT_BOOL ;

_saveWithDoc.vt = VT_BOOL ;

_left.vt = VT_I4 ;

_top.vt = VT_I4 ;

_Height.vt = VT_I4 ;

_Width.vt = VT_I4 ;

_linkToFile.boolVal = false ;

_saveWithDoc.boolVal = false ;

_left.intVal = 0 ;

_top.intVal = 0 ;

_Height.intVal = 200 ;

_Width.intVal = 200 ;



COleVariant _anchor ;

_anchor.vt = VT_DISPATCH ;

_anchor.pdispVal = selObj.GetRange() ;



_shapes.AddPicture(


"D:/tosave/winprj/TestOleAutomationWord/Release/test.jpg", // filename

_linkToFile, // linktofile

_saveWithDoc, //saveWithDoc

_left, // left

_top, //top

_Width, //width

_Height, //height

_anchor) ; // anchor



le problème c'est que quand je l'exécute il me dit : "Membre introuvable"



Mais quel membre ? le chemin que je lui fourni est bien pourtant correcte ....



ai je mal interprété la variable anchor ?
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
bien joué!!

mais ne me remercie pas, je ne t'ai posé que quelques questions qui ne t'ont pas aidées!!

bonne continuation, aux pays des merveilles!!
Messages postés
18
Date d'inscription
mercredi 21 avril 2004
Statut
Membre
Dernière intervention
3 octobre 2005

Hé bien disons tes questions m'ont quand
même aidées : tu m'as permis de me diriger vers le bon cheminement pour
trouver la réponse à mes questions !







Alice
Messages postés
63
Date d'inscription
jeudi 14 avril 2005
Statut
Membre
Dernière intervention
25 novembre 2005
1
Dans ce cas, ce fut un plaisir de t'aider dans ta quête!