B?n có th? l?y các thu?c tính tài li?u h?p ch?t t? m?t tài li?u b?ng cách s? d?ng
tiêu chu?n giao di?n mà không có máy ch? ch?y ho?c th?m chí đang đư?c cài đ?t. Cho
Ví d?, b?n có th? l?y các thu?c tính đư?c xây d?ng trong tài li?u như là tác gi?,
Th?i gian qua l?n, và thu?c tính trang Count m?t Microsoft văn ph?ng 97
tài li?u c?ng như các thu?c tính tu? ch?nh tài li?u khác.
Các bư?c sau đây minh h?a như th? nào b?n có th? xây d?ng m?t tài li?u h?p ch?t
b?t đ?ng s?n ngư?i xem v?i Microsoft Visual C++. Ví d? là m?t giao di?n đi?u khi?n Win32
?ng d?ng d? án, và có th? s?a đ?i cho phù h?p v?i nhu c?u c?a b?n.
Các bư?c đ? t?o m?u
T?o m?t d? án Win32 giao di?n đi?u khi?n ?ng d?ng m?i, và g?i nó là PropDump.
Thêm m?t t?p tin m?i đư?c g?i là main.cpp đ? d? án c?a b?n.
Copy đo?n m? sau vào main.cpp:
#include <stdio.h>
#include <windows.h>
#include <ole2.h>
#include <locale.h>
// Dumps simple PROPVARIANT values.
void DumpPropVariant(PROPVARIANT *pPropVar) {
// Don't iterate arrays, just inform as an array.
if(pPropVar->vt & VT_ARRAY) {
printf("(Array)\n");
return;
}
// Don't handle byref for simplicity, just inform byref.
if(pPropVar->vt & VT_BYREF) {
printf("(ByRef)\n");
return;
}
// Switch types.
switch(pPropVar->vt) {
case VT_EMPTY:
printf("(VT_EMPTY)\n");
break;
case VT_NULL:
printf("(VT_NULL)\n");
break;
case VT_BLOB:
printf("(VT_BLOB)\n");
break;
case VT_BOOL:
printf("%s (VT_BOOL)\n",
pPropVar->boolVal ? "TRUE/YES" : "FALSE/NO");
break;
case VT_I2: // 2-byte signed int.
printf("%d (VT_I2)\n", (int)pPropVar->iVal);
break;
case VT_I4: // 4-byte signed int.
printf("%d (VT_I4)\n", (int)pPropVar->lVal);
break;
case VT_R4: // 4-byte real.
printf("%.2lf (VT_R4)\n", (double)pPropVar->fltVal);
break;
case VT_R8: // 8-byte real.
printf("%.2lf (VT_R8)\n", (double)pPropVar->dblVal);
break;
case VT_BSTR: // OLE Automation string.
{
// Translate into ASCII.
char dbcs[1024];
char *pbstr = (char *)pPropVar->bstrVal;
int i = wcstombs(
dbcs, pPropVar->bstrVal, *((DWORD *)(pbstr-4)));
dbcs[i] = 0;
printf("%s (VT_BSTR)\n", dbcs);
}
break;
case VT_LPSTR: // Null-terminated string.
{
printf("%s (VT_LPSTR)\n", pPropVar->pszVal);
}
break;
case VT_FILETIME:
{
char *dayPre[] =
{"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
FILETIME lft;
FileTimeToLocalFileTime(&pPropVar->filetime, &lft); SYSTEMTIME lst;
FileTimeToSystemTime(&lft, &lst);
printf("%02d:%02d.%02d %s, %s %02d/%02d/%d (VT_FILETIME)\n",
1+(lst.wHour-1)%12, lst.wMinute, lst.wSecond,
(lst.wHour>=12) ? "pm" : "am",
dayPre[lst.wDayOfWeek%7],
lst.wMonth, lst.wDay, lst.wYear);
}
break;
case VT_CF: // Clipboard format.
printf("(Clipboard format)\n");
break;
default: // Unhandled type, consult wtypes.h's VARENUM structure.
printf("(Unhandled type: 0x%08lx)\n", pPropVar->vt);
break;
}
}
// Dump's built-in properties of a property storage.
void DumpBuiltInProps(IPropertySetStorage *pPropSetStg) {
printf("\n==================================================\n");
printf("BuiltInProperties Properties...\n");
printf("==================================================\n");
IPropertyStorage *pPropStg = NULL;
HRESULT hr;
// Open summary information, getting an IpropertyStorage.
hr = pPropSetStg->Open(FMTID_SummaryInformation,
STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);
//hr = pPropSetStg->Open(FMTID_UserDefinedProperties,
//STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);
if(FAILED(hr)) {
printf("No Summary-Information.\n");
return;
}
// Array of PIDSI's you are interested in.
struct pidsiStruct {
char *name;
long pidsi;
} pidsiArr[] = {
{"Title", PIDSI_TITLE}, // VT_LPSTR
{"Subject", PIDSI_SUBJECT}, // ...
{"Author", PIDSI_AUTHOR},
{"Keywords", PIDSI_KEYWORDS},
{"Comments", PIDSI_COMMENTS},
{"Template", PIDSI_TEMPLATE},
{"LastAuthor", PIDSI_LASTAUTHOR},
{"Revision Number", PIDSI_REVNUMBER},
{"Edit Time", PIDSI_EDITTIME}, // VT_FILENAME (UTC)
{"Last printed", PIDSI_LASTPRINTED}, // ...
{"Created", PIDSI_CREATE_DTM},
{"Last Saved", PIDSI_LASTSAVE_DTM},
{"Page Count", PIDSI_PAGECOUNT}, // VT_I4
{"Word Count", PIDSI_WORDCOUNT}, // ...
{"Char Count", PIDSI_CHARCOUNT},
{"Thumpnail", PIDSI_THUMBNAIL}, // VT_CF
{"AppName", PIDSI_APPNAME}, // VT_LPSTR
{"Doc Security", PIDSI_DOC_SECURITY}, // VT_I4
{0, 0}
};
// Count elements in pidsiArr.
int nPidsi = 0;
for(nPidsi=0; pidsiArr[nPidsi].name; nPidsi++);
// Initialize PROPSPEC for the properties you want.
PROPSPEC *pPropSpec = new PROPSPEC [nPidsi];
PROPVARIANT *pPropVar = new PROPVARIANT [nPidsi];
for(int i=0; i<nPidsi; i++) {
ZeroMemory(&pPropSpec[i], sizeof(PROPSPEC));
pPropSpec[i].ulKind = PRSPEC_PROPID;
pPropSpec[i].propid = pidsiArr[i].pidsi;
}
// Read properties.
hr = pPropStg->ReadMultiple(nPidsi, pPropSpec, pPropVar);
if(FAILED(hr)) {
printf("IPropertyStg::ReadMultiple() failed w/error %08lx\n",
hr);
}
else {
// Dump properties.
for(i=0; i<nPidsi; i++) {
printf("%16s: ", pidsiArr[i].name);
DumpPropVariant(pPropVar + i);
}
}
// De-allocate memory.
delete [] pPropVar;
delete [] pPropSpec;
// Release obtained interface.
pPropStg->Release();
}
// Dump's custom properties of a property storage.
void DumpCustomProps(IPropertySetStorage *pPropSetStg) {
printf("\n==================================================\n");
printf("Custom Properties...\n");
printf("==================================================\n");
IPropertyStorage *pPropStg = NULL;
HRESULT hr;
IEnumSTATPROPSTG *pEnumProp;
// Open User-Defined-Properties, getting an IpropertyStorage.
hr = pPropSetStg->Open(FMTID_UserDefinedProperties,
STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);
if(FAILED(hr)) {
printf("No User Defined Properties.\n");
return;
}
// Get property enumerator.
hr = pPropStg->Enum(&pEnumProp);
if(FAILED(hr)) {
pPropStg->Release();
printf("Couldn't enumerate custom properties.\n");
return;
}
// Enumerate properties.
STATPROPSTG sps;
ULONG fetched;
PROPSPEC propSpec[1];
PROPVARIANT propVar[1];
while(pEnumProp->Next(1, &sps, &fetched) == S_OK) {
// Build a PROPSPEC for this property.
ZeroMemory(&propSpec[0], sizeof(PROPSPEC));
propSpec[0].ulKind = PRSPEC_PROPID;
propSpec[0].propid = sps.propid;
// Read this property.
hr = pPropStg->ReadMultiple(1, &propSpec[0], &propVar[0]);
if(!FAILED(hr)) {
// Translate Prop name into ASCII.
char dbcs[1024];
char *pbstr = (char *)sps.lpwstrName;
int i = wcstombs(dbcs, sps.lpwstrName,
*((DWORD *)(pbstr-4)));
dbcs[i] = 0;
// Dump this property.
printf("%16s: ", dbcs);
DumpPropVariant(&propVar[0]);
}
}
// Release obtained interface.
pEnumProp->Release();
pPropStg->Release();
}
// Dump's custom and built-in properties of a compound document.
void DumpProps(char *filename) {
// Translate filename to Unicode.
WCHAR wcFilename[1024];
setlocale( LC_ALL, "" );
int i = mbstowcs(wcFilename, filename, strlen(filename));
setlocale( LC_ALL, "C" );
wcFilename[i] = 0;
IStorage *pStorage = NULL;
IPropertySetStorage *pPropSetStg = NULL;
HRESULT hr;
// Open the document as an OLE compound document.
hr = ::StgOpenStorage(wcFilename, NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
if(FAILED(hr)) {
if(hr == STG_E_FILENOTFOUND)
printf("File not found.");
else if(hr == STG_E_FILEALREADYEXISTS)
printf("Not a compound file.");
else
printf("StgOpenStorage() failed w/error %08lx", hr);
return;
}
// Obtain the IPropertySetStorage interface.
hr = pStorage->QueryInterface(
IID_IPropertySetStorage, (void **)&pPropSetStg);
if(FAILED(hr)) {
printf("QI for IPropertySetStorage failed w/error %08lx", hr);
pStorage->Release();
return;
}
// Dump properties.
DumpBuiltInProps(pPropSetStg);
DumpCustomProps(pPropSetStg);
// Release obtained interfaces.
pPropSetStg->Release();
pStorage->Release();
}
// Program entry-point.
void main(int argc, char **argv) {
// Validate arguments.
if(argc != 2) {
printf("- OLE Document Property Viewer\n");
printf("- Usage: %s filename", argv[0]);
return;
}
// Pass filename to the subroutine.
DumpProps(argv[1]);
}
Biên d?ch chương tr?nh.
Đ? ch?y các ví d?, b?n nên sao chép các t?p tin PropDump.exe vào m?t thư m?c trong
đư?ng d?n m?c đ?nh c?a b?n; Ví d? c:\Windows\ ho?c c:\Windows\Command\. Sau đó,
trong m?t thư m?c có ch?a m?t t?p tin h?p ch?t tài li?u, lo?i PropDump theo sau
tên t?p tin. B?n s? th?y đ?u ra tương t? như sau:
Các giao di?n IPropertyStorage và IPropertySetStorage không đư?c xác đ?nh trong
vi?c phát hành b?n g?c c?a COM; do đó m? m?u này đ?i h?i m?t h? th?ng v?i:
Windows NT 4.0 ho?c cao hơn
Windows 95 v?i Internet Explorer phiên b?n 4.0 ho?c cao hơn
Windows 95 v?i DCOM cài đ?t
Phiên b?n trư?c c?a COM ch? đ?nh r?t ít đ?i v?i thu?c tính
và s? d?ng c?a h?, nhưng đ? xác đ?nh m?t đ?nh d?ng đăng trên cho phép các nhà phát tri?n
đ? lưu tr? các tài s?n và tài s?n b? trong m?t th? hi?n IStorage. B?t đ?ng s?n
đ?nh danh và ng? ngh?a c?a m?t b? tài s?n duy nh?t, đư?c s? d?ng cho b?n tóm t?t
thông tin v? m?t tài li?u, c?ng đ? đư?c xác đ?nh. T?i th?i đi?m đó, nó đ?
c?n thi?t đ? t?o và thao tác đó cơ c?u tr?c ti?p như là m?t d? li?u
d?ng. Cho bi?t thêm thông tin trên các thi?t l?p tài s?n xu?t đ?nh d?ng d? li?u
cơ c?u t? ch?c, đ? c?p đ?n "OLE đăng trên b?t đ?ng s?n Set Format" trong Microsoft
Nhà phát tri?n m?ng.
(c) t?p đoàn Microsoft 1999, t?t c? các quy?n. Nh?ng đóng góp c?a Joe Crump, Microsoft Corporation.
ID c?a bài: 186898 - L?n xem xét sau cùng: 20 Tháng Tám 2011 - Xem xét l?i: 2.0
Áp d?ng
Microsoft Project 2000 Standard Edition
Microsoft Excel 2000 Standard Edition
Microsoft Visual C++ 5.0 Enterprise Edition
Microsoft Visual C++ 5.0 Professional Edition
Microsoft Excel 97 Standard Edition
Microsoft PowerPoint 97 Standard Edition
Microsoft Word 97 Standard Edition
Microsoft PowerPoint 2000 Standard Edition
Microsoft Word 2000 Standard Edition
Microsoft Excel 2002 Standard Edition
Microsoft PowerPoint 2002 Standard Edition
Microsoft Word 2002 Standard Edition
T? khóa:
kbcmpdoc kbfaq kbhowto kbmt KB186898 KbMtvi
Máy d?ch
QUAN TRỌNG: Bài vi?t này đư?c d?ch b?ng ph?n m?m d?ch máy c?a Microsoft ch? không ph?i do con ngư?i d?ch. Microsoft cung c?p các bài vi?t do con ngư?i d?ch và c? các bài vi?t do máy d?ch đ? b?n có th? truy c?p vào t?t c? các bài vi?t trong Cơ s? Ki?n th?c c?a chúng tôi b?ng ngôn ng? c?a b?n. Tuy nhiên, bài vi?t do máy d?ch không ph?i lúc nào c?ng hoàn h?o. Lo?i bài vi?t này có th? ch?a các sai sót v? t? v?ng, cú pháp ho?c ng? pháp, gi?ng như m?t ngư?i nư?c ngoài có th? m?c sai sót khi nói ngôn ng? c?a b?n. Microsoft không ch?u trách nhi?m v? b?t k? s? thi?u chính xác, sai sót ho?c thi?t h?i nào do vi?c d?ch sai n?i dung ho?c do ho?t đ?ng s? d?ng c?a khách hàng gây ra. Microsoft c?ng thư?ng xuyên c?p nh?t ph?n m?m d?ch máy này.
Nh?p chu?t vào đây đ? xem b?n ti?ng Anh c?a bài vi?t này:186898