Namen in IStorage

Ein Eigenschaftensatz wird mit einem Formatbezeichner (FMTID) in der IPropertySetStorage-Schnittstelle identifiziert. In der IStorage-Schnittstelle wird ein Eigenschaftensatz mit einer Unicode-Zeichenfolge mit NULL-Terminen mit einer maximalen Länge von 32 Zeichen benannt. Um die Interoperabilität zu ermöglichen, muss eine Zuordnung zwischen einer FMTID-Zeichenfolge und einer entsprechenden Unicode-Zeichenfolge mit Null-Endung eingerichtet werden.

Konvertieren eines Eigenschaftssatzes von einer FMTID in einen Zeichenfolgennamen

Wenn Sie von einer FMTID in einen entsprechenden Unicode-Zeichenfolgennamen konvertieren, vergewissern Sie sich zunächst, dass der FMTID ein bekannter Wert ist, der in der folgenden Tabelle aufgeführt ist. Wenn ja, verwenden Sie den entsprechenden bekannten Zeichenfolgennamen.

FMTID Zeichenfolgenname Semantik
F29F85E0-4FF9-1068-AB91-08002B27B3D9 "\005SummaryInformation" COM2-Zusammenfassungsinformationen
D5CDD502-2E9C-101B-9397-08002B2CF9AE D5CDD505-2E9C-101B-9397-08002B2CF9AE
"\005DocumentSummaryInformation" Office-Dokumentzusammenfassungsinformationen und benutzerdefinierte Eigenschaften.

Hinweis

Die Eigenschaft DocumentSummaryInformation und UserDefined ist eindeutig, da sie zwei Abschnitte enthält. Mehrere Abschnitte sind in keinem anderen Eigenschaftensatz zulässig. Weitere Informationen finden Sie unter Serialisiertes Eigenschaftssatzformat für strukturierten Speicher und DocumentSummaryInformation und UserDefined-Eigenschaftssätze. Der erste Abschnitt wurde als Teil von COM definiert; die zweite wurde von Microsoft Office definiert.

Wenn der FMTID kein bekannter Wert ist, verwenden Sie das folgende Verfahren, um algorithmisch einen Zeichenfolgennamen zu bilden.

So bilden Sie algorithmisch einen Zeichenfolgennamen

  1. Konvertieren Sie die FMTID bei Bedarf in die Bytereihenfolge little-endian.
  2. Nehmen Sie die 128 Bits der FMTID und betrachten Sie sie als eine lange Bitzeichenfolge, indem Sie die einzelnen Bytes miteinander verketten. Das erste Bit des 128-Bit-Werts ist das am wenigsten signifikante Bit des ersten Byte im Arbeitsspeicher der FMTID; das letzte Bit des 128-Bit-Werts ist das wichtigste Bit des letzten Byte im Arbeitsspeicher der FMTID. Erweitern Sie diese 128 Bits auf 130 Bits, indem Sie am Ende zwei Nullbits hinzufügen.
  3. Teilen Sie die 130 Bits in Gruppen von fünf Bits auf. es wird 26 solche Gruppen geben. Betrachten Sie jede Gruppe als ganze Zahl mit umgekehrter Bitrangfolge. Beispielsweise ist das erste der 128 Bits das am wenigsten signifikante Bit der ersten Gruppe von fünf Bits; das fünfte der 128 Bits ist das wichtigste Bit der ersten Gruppe.
  4. Ordnen Sie jede dieser ganzen Zahlen als Index dem Array von zweiunddreißig Zeichen zu: ABCDEFGHIJKLMNOPQRSTUVWXYZ012345. Dies ergibt eine Sequenz von 26 Unicode-Zeichen, die nur Großbuchstaben und Zahlen verwendet. Beachten Sie die Groß-/Kleinschreibung und die Nichtberücksichtigung der Groß-/Kleinschreibung, sodass jedes Zeichen in jedem Gebietsschema eindeutig ist.
  5. Erstellen Sie die endgültige Zeichenfolge, indem Sie die Zeichenfolge "\005" an der Vorderseite dieser 26 Zeichen für eine Gesamtlänge von 27 Zeichen verketten.

Der folgende Beispielcode zeigt, wie Sie eine FMTID einer Eigenschaftszeichenfolge zuordnen.

#define CBIT_BYTE        8
#define CBIT_CHARMASK    5
#define CCH_MAP          (1 << CBIT_CHARMASK)    // 32
#define CHARMASK         (CCH_MAP - 1)           // 0x1f
 
CHAR awcMap[CCH_MAP + 1] = "abcdefghijklmnopqrstuvwxyz012345";
 
WCHAR MapChar(ULONG I) {
    return((WCHAR) awcMap[i & CHARMASK]);
    }
 
VOID GuidToPropertyStringName(GUID *pguid, WCHAR awcname[]) {
    BYTE *pb = (BYTE *) pguid;
    BYTE *pbEnd = pb + sizeof(*pguid);
    ULONG cbitRemain = CBIT_BYTE;
    WCHAR *pwc = awcname;
 
    *pwc++ = ((WCHAR) 0x0005);
    while (pb < pbEnd) {
        ULONG i = *pb >> (CBIT_BYTE - cbitRemain);
        if (cbitRemain >= CBIT_CHARMASK) {
            *pwc = MapChar(i);
            if (cbitRemain == CBIT_BYTE && 
                                    *pwc >= L'a' && *pwc <= L'z')
                {
                *pwc += (WCHAR) (L'A' - L'a');
                }
            pwc++;
            cbitRemain -= CBIT_CHARMASK;
            if (cbitRemain == 0) {
                pb++;
                cbitRemain = CBIT_BYTE;
                }
            }
        else {
            if (++pb < pbEnd) {
                i |= *pb << cbitRemain;
                }
            *pwc++ = MapChar(i);
            cbitRemain += CBIT_BYTE - CBIT_CHARMASK;
            }
        }
    *pwc = L'\0';
    }

Konvertieren eines Eigenschaftensatzes von einem Zeichenfolgennamen in eine FMTID

Konverter von Eigenschaftenzeichenfolgennamen in GUIDs sollten Kleinbuchstaben als Synonym für ihre Großbuchstaben-Entsprechungen akzeptieren.

Der folgende Beispielcode zeigt, wie Sie eine Eigenschaftszeichenfolge einer FMTID zuordnen.

#include "stdafx.h"
#define _INC_OLE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define CBIT_CHARMASK 5
#define CBIT_BYTE     8
#define CBIT_GUID    (CBIT_BYTE * sizeof(GUID))
#define CWC_PROPSET  (1 + (CBIT_GUID + CBIT_CHARMASK-1)/CBIT_CHARMASK)
#define WC_PROPSET0  ((WCHAR) 0x0005)
#define CCH_MAP      (1 << CBIT_CHARMASK)        // 32
#define CHARMASK     (CCH_MAP - 1)            // 0x1f
CHAR awcMap[CCH_MAP + 1] = "abcdefghijklmnopqrstuvwxyz012345";
#define CALPHACHARS  ('z' - 'a' + 1)

GUID guidSummary =
{ 0xf29f85e0,0x4ff9, 0x1068,
{ 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9 } };

WCHAR wszSummary[] = L"SummaryInformation";

GUID guidDocumentSummary =
    { 0xd5cdd502,
      0x2e9c, 0x101b,
      { 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae } };

WCHAR wszDocumentSummary[] = L"DocumentSummaryInformation";
__inline WCHAR

MapChar(IN ULONG i)
{
    return((WCHAR) awcMap[i & CHARMASK]);
}

ULONG PropertySetNameToGuid(
    IN ULONG cwcname,
    IN WCHAR const awcname[],
    OUT GUID *pguid)
{
    ULONG Status = ERROR_INVALID_PARAMETER;
    WCHAR const *pwc = awcname;

    if (pwc[0] == WC_PROPSET0)
    {
        //Note: cwcname includes the WC_PROPSET0, and
        //sizeof(wsz...) includes the trailing L'\0', but
        //the comparison excludes both the leading
        //WC_PROPSET0 and the trailing L'\0'.
        if (cwcname == sizeof(wszSummary)/sizeof(WCHAR) &&
            wcsnicmp(&pwc[1], wszSummary, cwcname - 1) == 0)
        {
            *pguid = guidSummary;
            return(NO_ERROR);
        }
        if (cwcname == CWC_PROPSET)
        {
            ULONG cbit;
            BYTE *pb = (BYTE *) pguid - 1;
            ZeroMemory(pguid, sizeof(*pguid));
            for (cbit = 0; cbit < CBIT_GUID; cbit += 
            CBIT_CHARMASK)
            {
                ULONG cbitUsed = cbit % CBIT_BYTE;
                ULONG cbitStored;
                WCHAR wc;
                if (cbitUsed == 0)
                {
                    pb++;
                }
                wc = *++pwc - L'A';        //assume uppercase
                if (wc > CALPHACHARS)
                {
                    wc += (WCHAR) (L'A' - L'a'); //try lowercase
                    if (wc > CALPHACHARS)
                    {
                        wc += L'a' - L'0' + CALPHACHARS; 
                        if (wc > CHARMASK)
                        {
                            goto fail;       //invalid character
                        }
                    }
                }
                *pb |= (BYTE) (wc << cbitUsed);
                cbitStored = min(CBIT_BYTE - cbitUsed, 
                CBIT_CHARMASK);

                //If the translated bits will not fit in the 
                //current byte
                if (cbitStored < CBIT_CHARMASK)
                {
                    wc >>= CBIT_BYTE - cbitUsed;
                    if (cbit + cbitStored == CBIT_GUID)
                    {
                       if (wc != 0)
                       {
                           goto fail;        //extra bits
                       }
                       break;
                    }
                    pb++;
                    *pb |= (BYTE) wc;
                }
           }
           Status = NO_ERROR;
      }
    }
fail:
    return(Status);
}

Beim Versuch, einen vorhandenen Eigenschaftssatz zu öffnen, wird in IPropertySetStorage::Open die FMTID (Stamm-)FMTID wie oben beschrieben in eine Zeichenfolge konvertiert. Wenn ein Element des IStorage mit diesem Namen vorhanden ist, wird es verwendet. Andernfalls schlägt das geöffnete Fehlschlagen.

Beim Erstellen eines neuen Eigenschaftensatzes bestimmt die obige Zuordnung den verwendeten Zeichenfolgennamen.