Article ID: 179494
Article Last Modified on 2/12/2007
178749 How To Create an Automation Project Using MFC and a Type Library
#include "MSWord8.h" // msword9.h for Word 2000, msword.h for Word 2002
_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. ****************/
lpDisp = docs.Open(COleVariant("C:\\Test.doc",VT_BSTR),
222101 How To Find and Use Office Object Model Documentation
Additional query words: word 8.0 word8 word97 ole
Keywords: kbautomation kbfaq kbfaq kbhowto kbinterop KB179494