В данной статье рассматривается использование версии 4.2 библиотеки Microsoft Foundation Class (MFC), установленные вместе с Microsoft Visual C++ версий 5.0 и 6.0 для поиска и печати встроенных свойств документа из документа Microsoft Word. Встроенных свойств документа включают название документа, тема, автор, ключевые слова, комментарии, шаблон, даты, число страниц, слов, знаков и многие другие свойства.
Можно скопировать код в этой статье в функцию обработчика сообщения о событии в MFC CPP-файл. Тем не менее код предназначено для иллюстрации процесса с помощью интерфейсов IDispatch и определенные в библиотеке типов MSWord функций-членов. Основным преимуществом поступают из чтение и понимание кода в примере, таким образом, чтобы изменить пример или написания кода с нуля для автоматизации поиска и печати списка встроенных свойств документа.
Действия, чтобы создать проект
В Microsoft Word создать новый документ с именем Test.doc и сохраните его в корневом каталоге диска C.
Выполните шаги 1-12 в следующей статье базы базы знаний Майкрософт для создания образца проекта, использующий интерфейс IDispatch и определенные в библиотеке типов MSWord8.olb функций-членов.
Создание проекта автоматизации с использованием MFC и библиотеки типов (эта ссылка может указывать на содержимое полностью или частично на английском языке)
В верхней части AutoProjectDlg.cpp добавьте следующую строку:
#include "MSWord8.h" // msword9.h for Word 2000, msword.h for Word 2002
Добавьте следующий код CAutoProjectDlg::OnRun() в файле AutoProjectDlg.cpp.
Пример программы
_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. ****************/
Возможно, потребуется изменить код в CAutoProjectDlg::OnRun(), чтобы указать путь к Test.doc документа. Ссылки на документ в следующую строку:
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Спасибо! Благодаря вашему отзыву мы сможем сделать справочные материалы еще лучше. Чтобы воспользоваться дополнительными возможностями поддержки, посетите домашнюю страницу центра справки и поддержки.