Bagikan melalui


Pertimbangan Penyimpanan Properti

IPropertyStorage::ReadMultiple membaca sebanyak mungkin properti yang ditentukan dalam array rgpspec seperti yang ditemukan dalam kumpulan properti. Selama salah satu properti yang diminta dibaca, permintaan untuk mengambil properti yang tidak ada bukanlah kesalahan. Sebaliknya, ini harus menyebabkan VT_EMPTY ditulis untuk properti tersebut ke array rgvar[] saat pengembalian. Ketika tidak ada properti yang diminta, metode harus mengembalikan S_FALSE, dan mengatur VT_EMPTY di setiap PROPVARIANT. Jika ada kesalahan lain yang dikembalikan, tidak ada nilai properti yang diambil, dan pemanggil tidak perlu khawatir untuk melepaskannya.

Parameter rgpspec adalah array struktur PROPSPEC , yang menentukan untuk setiap properti baik pengidentifikasi propertinya atau, jika ditetapkan, pengidentifikasi string. Anda dapat memetakan string ke pengidentifikasi properti dengan memanggil IPropertyStorage::WritePropertyNames. Namun, penggunaan pengidentifikasi properti cenderung jauh lebih efisien daripada penggunaan string.

Properti yang diminta oleh nama string (PRSPEC_LPWSTR) dipetakan secara tidak peka huruf besar/kecil ke pengidentifikasi properti (ID) seperti yang ditentukan dalam kumpulan properti saat ini (dan sesuai dengan lokal sistem saat ini).

Ketika jenis properti VT_LPSTR dan properti dibaca dari kumpulan properti ANSI, yaitu, halaman kode untuk kumpulan properti diatur ke sesuatu selain Unicode, nilai properti menggunakan halaman kode yang sama dengan kumpulan properti. Saat properti VT_LPSTR dibaca dari kumpulan properti Unicode, nilai properti menggunakan halaman kode ANSI default sistem saat ini, yaitu, halaman kode yang dikembalikan dari fungsi GetACP .

PROPVARIANT, kecuali yang merupakan penunjuk ke aliran dan penyimpanan, disebut PROPVARIANT sederhana. PROPVARIANTsederhana ini menerima data berdasarkan nilai, jadi panggilan ke IPropertyStorage::ReadMultiple menyediakan salinan data yang kemudian dimiliki pemanggil. Untuk membuat atau memperbarui properti ini, panggil IPropertyStorage::WriteMultiple.

Sebaliknya, jenis varian VT_STREAM, VT_STREAMED_OBJECT, VT_STORAGE, dan VT_STORED_OBJECT adalah properti yang tidak sederhana, karena daripada menyediakan nilai, metode mengambil pointer ke antarmuka yang ditunjukkan, dari mana data kemudian dapat dibaca. Jenis-jenis ini mengizinkan penyimpanan informasi dalam jumlah besar melalui satu properti. Ada beberapa masalah yang muncul dalam menggunakan properti nonsimple.

Untuk membuat properti ini, adapun properti lainnya, panggil IPropertyStorage::WriteMultiple. Namun, daripada memanggil metode yang sama untuk diperbarui, lebih efisien untuk terlebih dahulu memanggil IPropertyStorage::ReadMultiple untuk mendapatkan penunjuk antarmuka ke aliran atau penyimpanan, lalu menulis data menggunakan metode IStream atau IStorage . Aliran atau penyimpanan yang dibuka melalui properti selalu dibuka dalam mode langsung, sehingga tingkat transaksi berlapis tambahan tidak diperkenalkan. Namun, mungkin masih ada transaksi pada properti yang ditetapkan secara keseluruhan, tergantung pada bagaimana transaksi dibuka atau dibuat melalui IPropertySetStorage. Selanjutnya, tag mode akses dan berbagi yang ditentukan ketika kumpulan properti dibuka atau dibuat, diteruskan ke aliran atau penyimpanan berbasis properti.

Masa pakai streaming berbasis properti atau penunjuk penyimpanan, meskipun secara teoritis independen dari pointer IPropertyStorage dan IPropertySetStorage terkait, pada kenyataannya, secara efektif bergantung padanya. Data yang terlihat melalui aliran atau penyimpanan terkait dengan transaksi pada objek penyimpanan properti tempat data diambil, sama seperti untuk objek penyimpanan (mendukung IStorage) dengan sub-objek aliran dan penyimpanan yang terkandung. Jika transaksi pada objek induk dibatalkan, penunjuk IStream dan IStorage yang ada di bawah bawahan objek tersebut tidak lagi dapat diakses. Karena IPropertyStorage adalah satu-satunya antarmuka pada objek penyimpanan properti, masa pakai yang berguna dari pointer IStream dan IStorage yang terkandung dibatasi oleh masa pakai antarmuka IPropertyStorage .

Implementasi juga harus menangani situasi di mana properti bernilai aliran atau penyimpanan yang sama diminta beberapa kali melalui instans antarmuka IPropertyStorage yang sama. Misalnya, dalam implementasi file campuran COM, pembukaan akan berhasil atau gagal tergantung pada apakah properti sudah terbuka atau tidak.

Masalah lain adalah beberapa pembukaan dalam mode yang ditransaksikan. Hasilnya tergantung pada tingkat isolasi yang ditentukan melalui panggilan ke metode IPropertySetStorage , (baik metode Buka atau Buat , melalui bendera STGM) pada saat penyimpanan properti dibuka.

Jika panggilan untuk membuka kumpulan properti menentukan akses baca-tulis, properti bernilai IStorage dan IStream selalu dibuka dengan akses baca-tulis. Data kemudian dapat ditulis melalui antarmuka ini, mengubah nilai properti, yang merupakan cara paling efisien untuk memperbarui properti ini. Nilai properti itu sendiri tidak memiliki tingkat transaksi tambahan yang bersarang, sehingga perubahan dilingkup dalam transaksi (jika ada) pada objek penyimpanan properti.

Properti Penyimpanan dan Aliran

Untuk menulis aliran atau objek penyimpanan ke kumpulan properti, kumpulan properti harus dibuat sebagai nonsimple. Untuk informasi selengkapnya tentang set properti sederhana dan nonsimple, lihat bagian berjudul Penyimpanan dan Objek Aliran untuk Kumpulan Properti. Jenis properti berikut, seperti yang ditentukan dalam bidang vt elemen array rgvar , adalah jenis streaming atau penyimpanan: VT_STREAM, VT_STORAGE, VT_STREAMED_OBJECT, VT_STORED_OBJECT.

Untuk menulis aliran atau objek penyimpanan sebagai properti dalam kumpulan properti yang tidak sederhana, panggil IPropertyStorage::WriteMultiple. Meskipun Anda juga akan memanggil metode ini untuk memperbarui properti sederhana, ini bukan cara yang efisien untuk memperbarui objek aliran dan penyimpanan dalam kumpulan properti. Ini karena memperbarui salah satu properti ini melalui panggilan ke WriteMultiple membuat di objek penyimpanan properti salinan data yang diteruskan, dan pointer IStorage atau IStream tidak dipertahankan di luar durasi panggilan ini. Biasanya lebih efisien untuk memperbarui aliran atau objek penyimpanan secara langsung dengan terlebih dahulu memanggil IPropertyStorage::ReadMultiple untuk mendapatkan penunjuk antarmuka ke aliran atau penyimpanan, lalu menulis data melalui metode IStream atau IStorage .

Misalnya, Anda dapat memanggil IPropertyStorage::WriteMultiple untuk menulis aliran NULL atau objek penyimpanan. Implementasi kemudian akan membuat objek kosong dalam set properti. Anda kemudian bisa mendapatkan akses ke objek ini dengan memanggil IPropertyStorage::ReadMultiple. Ketika Anda selesai memperbarui objek ini, Anda tidak perlu menulisnya ke kumpulan properti, karena pembaruan Anda masuk langsung ke set properti.

Aliran atau penyimpanan yang dibuka melalui properti selalu dibuka dalam mode langsung, sehingga tingkat transaksi berlapis tambahan tidak diperkenalkan. Mungkin masih ada transaksi pada properti yang ditetapkan secara keseluruhan. (Misalnya, jika IPropertyStorage diperoleh dengan memanggil IPropertySetStorage::Open dengan bendera STGM_TRANSACTED yang diatur dalam parameter grfmode .) Selanjutnya, aliran atau penyimpanan berbasis properti dibuka dalam mode baca-tulis, jika memungkinkan, mengingat mode pada set properti; jika tidak, mode baca digunakan.

Seperti disebutkan sebelumnya, ketika objek aliran atau penyimpanan ditulis ke properti yang diatur dengan metode WriteMultiple , salinan objek dibuat. Ketika salinan tersebut dibuat pada objek stream, operasi salin dimulai pada posisi pencarian sumber saat ini. Posisi pencarian tidak terdefinisi pada kegagalan, tetapi pada keberhasilannya ada di akhir aliran; penunjuk pencarian tidak dipulihkan ke posisi aslinya.

Jika properti aliran atau penyimpanan telah dibaca dari properti yang diatur dengan ReadMultiple, masih terbuka, dan panggilan berikutnya ke WriteMultiple untuk properti yang sama dilakukan, operasi WriteMultiple akan berhasil. Properti aliran atau penyimpanan yang dibuka sebelumnya ditempatkan dalam status dikembalikan (semua panggilan ke dalamnya akan mengembalikan kesalahan STG_E_REVERTED).

Jika metode WriteMultiple mengembalikan kesalahan saat menulis array properti, atau bahkan properti non-sederhana individual, jumlah data yang benar-benar ditulis tidak terdefinisi.

Properti Referensi

Jika struktur PROPVARIANT tertentu menyertakan bendera VT_BYREF di anggota vt-nya , properti terkait adalah properti referensi. Properti referensi secara otomatis didereferensikan sebelum menulis nilai ke set properti. Misalnya, jika anggota vt struktur PROPVARIANT menentukan nilai jenis VT_BYREF | VT_I4, nilai aktual yang ditulis adalah jenis VT_I4. Panggilan berikutnya ke metode IPropertyStorage::ReadMultiple mengembalikan nilai sebagai VT_I4. Menggunakan properti referensi mirip dengan memanggil fungsi VariantCopyInd . VariantCopyInd membebaskan varian tujuan dan membuat salinan VARIANTARG sumber, melakukan tidak langsung yang diperlukan jika sumber ditentukan untuk VT_BYREF. Fungsi ini berguna ketika salinan varian diperlukan, dan untuk menjamin bahwa itu tidak VT_BYREF, misalnya saat menangani argumen dalam implementasi IDispatch::Invoke.

Catatan Bagi Pemanggil

Disarankan agar set properti dibuat sebagai Unicode, dengan tidak mengatur bendera PROPSETFLAG_ANSI di parameter grfFlagsIPropertySetStorage::Create. Disarankan juga agar Anda menghindari penggunaan nilai VT_LPSTR, dan menggunakan nilai VT_LPWSTR sebagai gantinya. Saat halaman kode set properti adalah Unicode, nilai string VT_LPSTR dikonversi ke Unicode saat disimpan, dan kembali ke nilai string multibyte saat diambil. Ketika halaman kode kumpulan properti bukan Unicode, nama properti, VT_BSTR string, dan nilai properti non-sederhana dikonversi ke string multibyte saat disimpan, dan dikonversi kembali ke Unicode saat diambil, semuanya menggunakan halaman kode ANSI sistem saat ini.

Catatan Bagi Implementer

Saat mengalokasikan pengidentifikasi properti, implementasi dapat memilih nilai apa pun yang saat ini tidak digunakan dalam properti yang ditetapkan untuk pengidentifikasi properti, selama bukan 0 atau 1 atau lebih besar dari 0x80000000, yang semuanya merupakan nilai cadangan. Parameter propidNameFirst menetapkan nilai minimum untuk pengidentifikasi properti dalam set, dan harus lebih besar dari 1 dan kurang dari 0x80000000. Lihat bagian Keterangan di atas.

Implementasi file IPropertyStorage-Compound

Implementasi Sistem File IPropertyStorage-NTFS

Implementasi IPropertyStorage-Stand-alone