Cet article explique comment utiliser la version 4.2 de la bibliothèque Microsoft Foundation Class (MFC) installé avec les versions 5.0 et 6.0 de Microsoft Visual C++ pour rechercher et imprimer les propriétés de document intégrées d'un document Microsoft Word. Les propriétés de document prédéfinies contiennent le titre du document, sujet, auteur, mots-clés, commentaires, modèle, dates, nombre de pages, mots, caractères et de nombreuses autres propriétés.
Vous pouvez copier le code dans cet article à la fonction de gestionnaire de messages d'un événement défini dans un fichier .cpp MFC. Toutefois, l'objectif du code est d'illustrer le processus d'utilisation les interfaces IDispatch et les fonctions membres définies dans la bibliothèque de type MSWord. Le principal avantage vient de la lecture et de comprendre le code dans l'exemple afin que vous pouvez modifier l'exemple ou écrire du code à partir de zéro pour automatiser la recherche et impression d'une liste des propriétés de document prédéfinies.
Étapes pour créer le projet
Dans Microsoft Word, créez un document nommé test.doc et enregistrer le répertoire racine du lecteur c.
Suivez les étapes 1 à 12 dans l'article de base de connaissances Microsoft suivant pour créer un projet exemple qui utilise les interfaces IDispatch et les fonctions membres définies dans la bibliothèque de type MSWord8.olb :
Comment faire pour créer un projet Automation à l'aide de MFC et d'une bibliothèque de types
En haut de la AutoProjectDlg.cpp, ajoutez la ligne suivante :
#include "MSWord8.h" // msword9.h for Word 2000, msword.h for Word 2002
Ajoutez le code suivant à CAutoProjectDlg::OnRun () dans le fichier AutoProjectDlg.cpp.
Exemple de code
_Application objWordApp;
_Document objDoc;
LPDISPATCH lpDisp;
Range objRange;
// Common OLE variants that are easy to use for calling arguments.
COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
objWordApp.CreateDispatch("Word.Application");
objWordApp.SetVisible(TRUE);
Documents docs(objWordApp.GetDocuments());
lpDisp = docs.Open(COleVariant("C:\\Test.doc",VT_BSTR),
covFalse, // Confirm.
// Conversion.
covFalse, // ReadOnly.
covFalse, // AddToRecentFiles.
covOptional, // NULL,
// PasswordDocument.
covOptional, // PasswordTemplate.
covFalse, // Revert.
covOptional, // Write-
// PasswordDocument.
covOptional, // Write-
// PasswordTemplate.
covOptional // Format. //Last parameter for Word 97
covOptional, // Encoding // Word 2000/2002 from here on
covTrue, // Visible
covOptional, // OpenConflictDocument
covOptional, // OpenAndRepair
(long)0, // DocumentDirection
//wdDocumentDirection LeftToRight
covOptional // NoEncodingDialog
);
objDoc.AttachDispatch(lpDisp);
lpDisp = objDoc.GetContent();
objRange.AttachDispatch(lpDisp);
// Move the insertion point to the beginning of the document.
objRange.Collapse(COleVariant((long)1)); //0 = wdCollapseEnd.
objRange.InsertAfter("Here are the BuiltInDocumentProperties!!");
objRange.InsertParagraphAfter(); // Write them one-by-one in a loop.
lpDisp = objDoc.GetBuiltInDocumentProperties();
COleDispatchDriver rootDisp[64]; // Temporary object array.
int curRootIndex = 0; // Index into rootDisp[] array.
DISPID dispID; // Temporary dispid for use in
// OleDispatchDriver::
// InvokeHelper().
DISPID dispID2; // Dispid for 'Value'.
unsigned short *ucPtr; // Temporary name holder for
// IDispatch::GetIDsOfNames().
VARIANT vtResult; // Holds results from
// OleDispatchDriver::
// InvokeHelper().
VARIANT vtResult2; // Holds result for 'Type'.
BYTE *parmStr; // Holds parameter descriptions
// for COleDispatchDriver::
// InvokeHelper().
rootDisp[0].AttachDispatch(lpDisp); // LPDISPATCH returned from
// GetBuiltInDocumentProperties.
VARIANT i; // integer;
VARIANT count; // integer;
char buf[512]; // General purpose message buffer.
char buf2[512];
ucPtr = L"Count"; // Collections have a Count
// member.
try
{
rootDisp[curRootIndex].m_lpDispatch->GetIDsOfNames(
IID_NULL,
&ucPtr,
1,
LOCALE_USER_DEFAULT,
&dispID);
rootDisp[curRootIndex].InvokeHelper(dispID,
DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&vtResult,
NULL);
count = vtResult; // Require a separate variable for loop limiter.
// For i = 1 to count,
// get the Item, Name & Value members of the collection.
i.vt = VT_I4;
for(i.lVal=1; i.lVal<=count.lVal; i.lVal++)
{
ucPtr = L"Item"; // Collection has an Item member.
rootDisp[curRootIndex].m_lpDispatch->GetIDsOfNames(
IID_NULL,
&ucPtr,
1,
LOCALE_USER_DEFAULT,
&dispID);
parmStr = (BYTE *)( VTS_VARIANT );
rootDisp[curRootIndex].InvokeHelper(dispID,
DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&vtResult,
parmStr,
&COleVariant(i));
// Move to the next element of the array.
// Get the Name member for the Item.
rootDisp[++curRootIndex].AttachDispatch(vtResult.pdispVal);
ucPtr = L"Name"; // Collection has a Name member
rootDisp[curRootIndex].m_lpDispatch->GetIDsOfNames(
IID_NULL,
&ucPtr,
1,
LOCALE_USER_DEFAULT,
&dispID);
rootDisp[curRootIndex].InvokeHelper(dispID,
DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&vtResult,
NULL);
ucPtr = L"Value"; // Collection has a Value member.
rootDisp[curRootIndex].m_lpDispatch->GetIDsOfNames(
IID_NULL,
&ucPtr,
1,
LOCALE_USER_DEFAULT,
&dispID2);
rootDisp[curRootIndex].InvokeHelper(dispID2,
DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&vtResult2,
NULL);
Continue: // Come back here from Catch(COleDispatchException).
rootDisp[curRootIndex--].ReleaseDispatch();
// Initialize buf2 with representation of the value.
switch(vtResult2.vt) // Type of property.
{
case VT_BSTR:
sprintf(buf2, "%s", (CString)vtResult2.bstrVal);
break;
case VT_DATE:
{
COleDateTime codt(vtResult2.date);
sprintf(buf2, "Time = %d:%02d, Date = %d/%d/%d",
codt.GetHour(), codt.GetMinute(),
codt.GetMonth(), codt.GetDay(), codt.GetYear()
);
}
break;
case VT_I4:
sprintf(buf2, "%ld", vtResult2.lVal);
break;
default:
sprintf(buf2, "not VT_BSTR, VT_DATE, or VT_I4");
} // End of Switch.
sprintf(buf, "Item(%d).Name = %s, .Type = %d, .Value = %s\n",
i.lVal, CString(vtResult.bstrVal), vtResult2.vt, buf2);
objRange.Collapse(COleVariant((long)0)); // Move insertion point
// to end of the range.
objRange.InsertAfter(CString(buf)); // Insert after the insertion
// point.
} ////////////////// End of For loop. ///////////////////////
objRange.InsertParagraphAfter(); // Spacing.
objRange.InsertAfter("");
objRange.InsertParagraphAfter(); // Spacing.
// Release IDispatch pointers on local objects.
if(vtResult.vt == VT_DISPATCH) vtResult.pdispVal->Release();
if(count.vt == VT_DISPATCH) count.pdispVal->Release();
rootDisp[0].ReleaseDispatch();
AfxMessageBox("All done, waiting...");
objDoc.SetSaved(TRUE); // Hides the "Save your changes..." dialog.
AfxMessageBox("Word will close now. Goodbye");
objWordApp.Quit(covFalse, covFalse, covFalse);
} // End try.
catch(COleException *e)
{
sprintf(buf, "COleException. SCODE: %08lx.", (long)e->m_sc);
::MessageBox(NULL, buf, "COleException", MB_SETFOREGROUND | MB_OK);
}
catch(COleDispatchException *e)
{
if(vtResult2.vt ==VT_ERROR)
{
AfxMessageBox("Discarding vtResult2.VT_ERROR");
}
vtResult2.vt = VT_BSTR;
vtResult2.bstrVal = L"Value not available";
goto Continue;
}
catch(...)
{
MessageBox( "General Exception caught.", "Catch-All",
MB_SETFOREGROUND | MB_OK);
}
//////////////////// For information only. /////////////////////
// Do not uncomment the following code snippet. //
// You can copy it and use it in lieu of the previous code when //
// you need to see just one property. //
/***************** Code to get a single property. *****************
// Works for one property.
COleDispatchDriver myDocumentProperties(lpDisp);
COleVariant result;
// Get myDocumentProperties.Item(1).
// Item(n) where n = property index
// value in properties collection.
UCHAR *parmStr = (BYTE *)( VTS_VARIANT );
myDocumentProperties.InvokeHelper(0, DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&result,
parmStr,
&COleVariant((long)1));
COleDispatchDriver myDocumentProperty(result.pdispVal);
// Get Name of this document property.
myDocumentProperty.InvokeHelper(3, DISPATCH_METHOD |
DISPATCH_PROPERTYGET,
VT_VARIANT,
(void *)&result,
NULL);
AfxMessageBox(CString("Item(1).Name =") + CString(result.bstrVal));
// Release this document property.
myDocumentProperty.ReleaseDispatch();
// Release the document properties collection.
myDocumentProperties.ReleaseDispatch();
//*************** End of code for single property. ****************/
Vous devrez peut-être modifier le code dans CAutoProjectDlg::OnRun () pour indiquer le chemin d'accès correct pour votre document test.doc. Le document est référencé dans la ligne suivante :
Pour plus d'informations sur l'Automation des applications Office, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 179494
(http://support.microsoft.com/kb/179494/en-us/
)
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.
Merci ! Vos commentaires sont très utiles pour l'amélioration de notre contenu d'aide et de support. Si vous avez besoin d'aide complémentaire, veuillez consulter la page d'accueil d'aide et support.