Meminta Objek untuk Antarmuka
Kami melihat sebelumnya bahwa objek dapat mengimplementasikan lebih dari satu antarmuka. Objek Dialog Item Umum sebagai contoh nyata dari hal ini. Untuk mendukung penggunaan yang paling umum, objek mengimplementasikan antarmukaIFileOpenDialog. Antarmuka ini menentukan metode dasar untuk menampilkan kotak dialog dan mendapatkan informasi tentang file yang dipilih. Namun, untuk penggunaan yang lebih canggih, objek juga mengimplementasikan antarmuka bernama IFileDialogCustomize. Program dapat menggunakan antarmuka ini untuk menyesuaikan tampilan dan perilaku kotak dialog, dengan menambahkan kontrol UI baru.
Ingat bahwa setiap antarmuka COM harus mewarisi, secara langsung atau tidak langsung, dari antarmukaIUnknown. Diagram berikut menunjukkan pewarisan objek Dialog Item Umum.
diagram
Seperti yang Anda lihat dari diagram, nenek moyang langsungIFileOpenDialog adalah antarmukaIFileDialog, yang pada gilirannya mewarisi IModalWindow. Saat Anda naik dalam hierarki pewarisan dari IFileOpenDialog ke IModalWindow, antarmuka mendefinisikan fungsionalitas jendela yang semakin menggeneralisasi. Akhirnya, antarmuka IModalWindow mewarisi IUnknown. Objek Dialog Item Umum juga mengimplementasikan IFileDialogCustomize, yang ada dalam hierarki pewarisan terpisah.
Sekarang misalkan Anda memiliki penunjuk ke antarmukaIFileOpenDialog. Bagaimana Anda akan mendapatkan penunjuk ke antarmuka IFileDialogCustomize?
diagram
Mengonversi penunjuk IFileOpenDialog menjadi penunjuk IFileDialogCustomize tidak akan berfungsi. Tidak ada cara yang dapat diandalkan untuk melakukan "penyalin silang tipe" di seluruh hierarki pewarisan, tanpa bentuk informasi tipe run-time (RTTI), yang merupakan fitur yang sangat bergantung pada bahasa.
Pendekatan COM adalah meminta objek untuk memberi Anda IFileDialogCustomize pointer, menggunakan antarmuka pertama sebagai saluran ke dalam objek. Ini dilakukan dengan memanggil metodeIUnknown::QueryInterface dari pointer antarmuka pertama. Anda dapat menganggap QueryInterface sebagai versi independen bahasa dari kata kunci dynamic_cast di C++.
MetodeQueryInterfacememiliki tanda tangan berikut:
HRESULT QueryInterface(REFIID riid, void **ppvObject);
Berdasarkan apa yang sudah Anda ketahui tentang CoCreateInstance, Anda mungkin dapat menebak cara kerjaQueryInterface.
- Parameter riid adalah GUID yang mengidentifikasi antarmuka yang Anda minta. Jenis data REFIID adalah typedef untuk
const GUID&
. Perhatikan bahwa pengidentifikasi kelas (CLSID) tidak diperlukan, karena objek telah dibuat. Hanya pengidentifikasi antarmuka yang diperlukan. - Parameter ppvObject menerima penunjuk ke antarmuka. Jenis data parameter ini void**, karena alasan yang sama bahwa CoCreateInstance menggunakan jenis data ini: QueryInterface dapat digunakan untuk mengkueri antarmuka COM apa pun, sehingga parameter tidak dapat diketik dengan kuat.
Berikut adalah cara Anda memanggil QueryInterface untuk mendapatkan IFileDialogCustomize pointer:
hr = pFileOpen->QueryInterface(IID_IFileDialogCustomize,
reinterpret_cast<void**>(&pCustom));
if (SUCCEEDED(hr))
{
// Use the interface. (Not shown.)
// ...
pCustom->Release();
}
else
{
// Handle the error.
}
Seperti biasa, periksa nilai pengembalian HRESULT, jika metode gagal. Jika metode berhasil, Anda harus memanggilRilisketika Anda selesai menggunakan pointer, seperti yang dijelaskan dalam Mengelola Masa Pakai Objek.
Berikutnya