Como ler propriedades do documento compostas directamente com VC ++

Traduções de Artigos Traduções de Artigos
Artigo: 186898 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Pode obter propriedades de documentos compostos a partir de um documento utilizando o padrão de interfaces sem o servidor funcionar ou ainda a ser instalado. Por exemplo, pode obter propriedades de documentos incorporada, tais como autor, hora da última alteração e número de página de propriedades de um documento do Microsoft Office 97, bem como outras propriedades personalizadas do documento.

Mais Informação

Os seguintes passos ilustram como pode criar um visualizador de propriedade de documento composto com o Microsoft Visual C++. O exemplo é um projecto de aplicação de consola Win32 e pode ser modificado de acordo com as suas necessidades.

Passos para criar o exemplo

  1. Crie um novo projecto de aplicação de consola Win32 e chamá-lo PropDump.
  2. Adicione um novo ficheiro denominado main.cpp ao projecto.
  3. Copie o código seguinte para 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]);
       }
    					
  4. Compile o programa.
Para executar o exemplo, deve copiar o ficheiro PropDump.exe para um directório no caminho predefinido; por exemplo c:\Windows\ ou c:\Windows\Command\. Em seguida, no directório contendo um ficheiro de documento composto, escreva PropDump seguido do nome do ficheiro. Deverá ver resultados semelhantes à seguinte:

==================================================

Propriedades de BuiltInProperties...

           Title: MyTitle (VT_LPSTR)
         Subject: MySubject (VT_LPSTR)
          Author: MyAuthor (VT_LPSTR)
        Keywords: MyKeywords (VT_LPSTR)
        Comments: MyComments (VT_LPSTR)
        Template: Normal (VT_LPSTR)
      LastAuthor: Me (VT_LPSTR)

 Revision Number: 8 (VT_LPSTR)

       Edit Time: 01:05.47 pm, Mon 01/01/1601 (VT_FILETIME)
    Last printed: (VT_EMPTY)
         Created: 01:42.00 pm, Fri 05/29/1998 (VT_FILETIME)
      Last Saved: 12:31.00 pm, Mon 06/01/1998 (VT_FILETIME)
      Page Count: 1 (VT_I4)
      Word Count: 3 (VT_I4)
      Char Count: 19 (VT_I4)
       Thumpnail: (VT_EMPTY)
         AppName: Microsoft Word 8.0 (VT_LPSTR)
    Doc Security: 0 (VT_I4)
				
==================================================

Propriedades personalizadas...

   _PID_LINKBASE: (VT_BLOB)

       _PID_GUID: (VT_BLOB)
       CustProp1: CustProp1TextValue (VT_LPSTR)
       CustProp2: 77777 (VT_I4)
       CustProp3: TRUE/YES (VT_BOOL)
       CustProp4: 00:00.00 am, Tue 05/17/1977 (VT_FILETIME)
				

Notas adicionais

As interfaces IPropertyStorage e IPropertySetStorage não foram definidas na versão original do COM; assim, este código de exemplo necessita de um sistema com:
  • Windows NT 4.0 ou posterior
  • O Windows 95 com o Internet Explorer versão 4.0 ou posterior
  • O Windows 95 com o DCOM instalado
Versões anteriores do COM especificado muito pouco com respeitam às propriedades e respectiva utilização, mas definir um formato serializado permitidos aos programadores de armazenar propriedades e conjuntos de propriedades numa instância IStorage. Os identificadores de propriedade e a semântica de um conjunto de propriedade única, utilizado para informações de resumo sobre um documento, também foram definida. Nessa altura, foi necessária para criar e manipular essa estrutura directamente como uma sequência de dados. Para mais informações sobre a propriedade Definir estrutura de formato de dados serializados, consulte "OLE serializados propriedades definir Format" na Microsoft Developer Network.

(c) 1999 Microsoft Corporation, todos os direitos reservados. Contribuições de José Crump, Microsoft Corporation.

Referências

Microsoft Developer Network: Conjuntos de propriedades persistente

Microsoft Developer Network: OLE serializados formatar de conjunto de propriedades

Propriedades

Artigo: 186898 - Última revisão: 12 de fevereiro de 2007 - Revisão: 4.4
A informação contida neste artigo aplica-se a:
  • 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
Palavras-chave: 
kbmt kbcmpdoc kbfaq kbhowto KB186898 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 186898

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com