Nama di IStorage
Kumpulan properti diidentifikasi dengan pengidentifikasi format (FMTID) di antarmuka IPropertySetStorage. Dalam antarmukaIStorage, set properti diberi nama dengan string Unicode null-terminated dengan panjang maksimum 32 karakter. Untuk mengaktifkan interoperabilitas, pemetaan antara FMTID dan string Unicode yang dihentikan null yang sesuai harus dibuat.
Mengonversi kumpulan properti dari FMTID ke nama string
Saat mengonversi dari FMTID ke nama string Unicode yang sesuai, pertama-tama verifikasi bahwa FMTID adalah nilai terkenal, yang tercantum dalam tabel berikut. Jika demikian, gunakan nama string terkenal yang sesuai.
FMTID | Nama string | Semantik |
---|---|---|
F29F85E0-4FF9-1068-AB91-08002B27B3D9 | "\005InformasiSummary" | Informasi ringkasan COM2 |
D5CDD502-2E9C-101B-9397-08002B2CF9AE D5CDD505-2E9C-101B-9397-08002B2CF9AE |
"\005DocumentSummaryInformation" | Informasi ringkasan dokumen Office dan properti yang ditentukan pengguna. |
Nota
Kumpulan properti DocumentSummaryInformation dan UserDefined unik karena berisi dua bagian. Beberapa bagian tidak diizinkan dalam kumpulan properti lainnya. Untuk informasi selengkapnya, lihat Format Kumpulan Properti Serial Penyimpanan Terstruktur, dan Kumpulan Properti DocumentSummaryInformation dan UserDefined. Bagian pertama didefinisikan sebagai bagian dari COM; yang kedua ditentukan oleh Microsoft Office.
Jika FMTID bukan nilai terkenal, gunakan prosedur berikut untuk membentuk nama string secara algoritma.
Untuk membentuk nama string secara algoritma
- Konversikan FMTID ke urutan byte little-endian, jika perlu.
- Ambil 128 bit FMTID dan pertimbangkan sebagai satu string bit panjang dengan menggabungkan masing-masing byte bersama-sama. Bit pertama dari nilai 128 bit adalah bit yang paling tidak signifikan dari byte pertama dalam memori FMTID; bit terakhir dari nilai 128 bit adalah bit paling signifikan dari byte terakhir dalam memori FMTID. Perluas 128 bit ini menjadi 130 bit dengan menambahkan dua bit nol ke akhir.
- Bagi 130 bit menjadi kelompok lima bit; akan ada 26 kelompok tersebut. Pertimbangkan setiap grup sebagai bilangan bulat dengan prioritas bit terbalik. Misalnya, yang pertama dari 128 bit adalah bit paling tidak signifikan dari grup pertama lima bit; kelima dari 128 bit adalah bit paling signifikan dari grup pertama.
- Petakan masing-masing bilangan bulat ini sebagai indeks ke dalam array tiga puluh dua karakter: ABCDEFGHIJKLMNOPQRSTUVWXYZ012345. Ini menghasilkan urutan 26 karakter Unicode yang hanya menggunakan karakter huruf besar dan angka. Pertimbangan peka huruf besar/kecil dan tidak peka huruf besar/kecil tidak berlaku, menyebabkan setiap karakter unik dalam lokal apa pun.
- Buat string akhir dengan menggabungkan string "\005" ke bagian depan 26 karakter ini, untuk panjang total 27 karakter.
Contoh kode berikut menunjukkan cara memetakan dari FMTID ke string properti.
#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';
}
Mengonversi kumpulan properti dari nama string ke FMTID
Pengonversi nama string properti ke GUID harus menerima huruf kecil sebagai identik dengan rekan-rekan huruf besarnya.
Contoh kode berikut menunjukkan cara memetakan dari string properti ke FMTID.
#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);
}
Saat mencoba membuka kumpulan properti yang ada, di IPropertySetStorage::Open, FMTID (root) dikonversi ke string seperti yang dijelaskan di atas. Jika ada elemen IStorage nama tersebut, maka akan digunakan. Jika tidak, pembukaan gagal.
Saat membuat kumpulan properti baru, pemetaan di atas menentukan nama string yang digunakan.