Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Karena konten sisi perangkat tidak dapat diakses melalui sistem file di Windows Vista, Anda harus menggunakan Windows Shell API atau WPD API untuk mengambil data untuk objek perangkat. Ini adalah perbedaan utama antara handler lembar properti normal dan handler lembar properti WPD. Kode sampel berikut menunjukkan pengambilan konten sisi perangkat menggunakan Windows Shell API.
Langkah pertama adalah inisialisasi daftar pengidentifikasi item atau PIDL. (Daftar ini berisi pengidentifikasi unik untuk objek perangkat yang diberikan.)
HRESULT CWPDPropSheet::_InitializePIDLArray(IDataObject *pDataObj)
{
if (m_cfHIDA == 0)
{
m_cfHIDA = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLIDLIST);
}
STGMEDIUM medium;
FORMATETC fmte = {m_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
m_pPropInfo = (PROPINFO*)LocalAlloc(LPTR, sizeof(PROPINFO));
if (m_pPropInfo == NULL)
return E_OUTOFMEMORY;
AddRef_PropInfo(m_pPropInfo);
HRESULT hr = pDataObj->GetData(&fmte, &medium);
if (SUCCEEDED(hr))
{
SIZE_T cb = GlobalSize(medium.hGlobal);
CIDA *pida = (CIDA*)GlobalAlloc(GPTR, cb);
if (pida)
{
void *pv = GlobalLock(medium.hGlobal);
if (pv != NULL)
{
CopyMemory(pida, pv, cb);
GlobalUnlock(medium.hGlobal);
m_pPropInfo->pida = pida;
_ExaminePIDLArray();
}
else
{
hr = E_UNEXPECTED;
}
}
else
{
hr = E_OUTOFMEMORY;
}
ReleaseStgMedium(&medium);
}
return hr;
}
Fungsi inisialisasi memanggil fungsi _ExaminePIDLArray, yang mengambil properti untuk objek yang diidentifikasi oleh PIDL dalam array PIDL.
HRESULT CWPDPropSheet::_ExaminePIDLArray()
{
CComPtr<IShellFolder2> spParentFolder;
CComVariant variant;
LPITEMIDLIST pidl = NULL;
HRESULT hr = S_OK;
UINT index = 0;
pidl = GetPIDL(m_pPropInfo->pida, index);
if (pidl)
{
hr = SHBindToParent(pidl, IID_PPV_ARGS(&spParentFolder), NULL);
IF_FAILED_JUMP(hr, Exit);
}
do
{
CComPtr<IPropertySetStorage> spSetStorage;
CComPtr<IPropertyStorage> spPropStorage;
// Get the IpropertySetStorage interface for this PIDL. This method could also
// be used to retrieve an IPortableDevice interface to allow more low-level interaction
// with the WPD API.
hr = spParentFolder->BindToObject(ILFindLastID(pidl), NULL, IID_PPV_ARGS(&spSetStorage));
if (SUCCEEDED(hr))
{
hr = spSetStorage->Open(WPD_FUNCTIONAL_OBJECT_PROPERTIES_V1, STGM_READ, &spPropStorage);
if (SUCCEEDED(hr))
{
PROPVARIANT PropVar = {0};
PROPSPEC PropSpec = {0};
PropSpec.ulKind = PRSPEC_PROPID;
PropSpec.propid = 2; // WPD_FUNCTIONAL_OBJECT_CATEGORY
PropVariantInit(&PropVar);
hr = spPropStorage->ReadMultiple(1, &PropSpec, &PropVar);
if (SUCCEEDED(hr) && PropVar.vt == VT_CLSID)
{
// The PIDL array contains a non-file object.
// This means we don't want to take over the
// default menu action.
m_bPIDAContainsOnlyFiles = FALSE;
PropVariantClear(&PropVar);
break;
}
else
{
CComPtr<IPropertyStorage> spObjectProperties;
hr = spSetStorage->Open(WPD_OBJECT_PROPERTIES_V1, STGM_READ, &spObjectProperties);
if (SUCCEEDED(hr))
{
PropSpec.ulKind = PRSPEC_PROPID;
PropSpec.propid = 7; // WPD_OBJECT_CONTENT_TYPE
PropVariantClear(&PropVar);
hr = spObjectProperties->ReadMultiple(1, &PropSpec, &PropVar);
if (SUCCEEDED(hr) && PropVar.vt == VT_CLSID)
{
if (IsEqualGUID(*PropVar.puuid, WPD_CONTENT_TYPE_FOLDER))
{
// The PIDL array contains a folder object.
// This means we don't want to take over the
// default menu action.
m_bPIDAContainsOnlyFiles = FALSE;
PropVariantClear(&PropVar);
break;
}
}
}
}
PropVariantClear(&PropVar);
}
}
UI_SAFE_ILFREE(pidl);
pidl = GetPIDL(m_pPropInfo->pida, ++index);
} while (pidl != NULL && index < m_pPropInfo->pida->cidl);
Exit:
UI_SAFE_ILFREE(pidl);
return hr;
}
Selain inisialisasi dan pemrosesan daftar pengidentifikasi item, aplikasi Anda harus menerapkan metode IShellPropSheetExt::ReplacePage dan menyisipkan penangan pengganti yang sesuai. Windows Shell memanggil metode ini setiap kali akan menampilkan lembar properti yang dapat diganti, memberi aplikasi Anda kesempatan untuk memanggil handler pengganti yang sesuai. Bagian bawah dari parameter pertama dari metode ReplacePage adalah sebuah pengidentifikasi untuk lembar properti tertentu yang akan ditampilkan oleh Windows. Nilai yang diteruskan pada bagian bawah dari kata pertama parameter sesuai dengan nilai yang ditentukan dalam file WpdShellExtension.h. Nilai-nilai ini dan deskripsinya muncul dalam tabel berikut.
Nilai | Deskripsi |
---|---|
WPDNSE_PROPSHEET_DEVICE_GENERAL | Sesuai dengan tab umum untuk perangkat. |
Properti Umum Penyimpanan WPDNSE | Sesuai dengan tab umum untuk objek penyimpanan yang ditemukan di perangkat. |
WPDNSE_LEMBAR_PROPISI_KONTEN_UMUM | Sesuai dengan tab umum untuk objek konten yang ditemukan di perangkat. |
WPDNSE_PROPSHEET_CONTENT_REFERENCES | Sesuai dengan tab referensi untuk objek konten yang ditemukan di perangkat. |
WPDNSE_PROPSHEET_CONTENT_RESOURCES | Sesuai dengan tab sumber daya untuk objek konten yang ditemukan di perangkat. |
WPDNSE_SHEET_PROPSISI_KONTEN_DETIL | Merujuk ke tab detail untuk objek konten yang ditemukan di perangkat. |
Dalam ekstensi lembar properti sampel, metode ReplacePage memanggil dua handler pengganti: _ReplaceDeviceGeneral dan _ReplaceContentReferences. Handler ini menggantikan perangkat umum dan tab referensi konten di lembar properti yang dapat diperluas.
STDMETHODIMP CWPDPropSheet::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplacePage, LPARAM lParam)
{
HRESULT hr = S_OK;
if (LOWORD(uPageID) == WPDNSE_PROPSHEET_DEVICE_GENERAL)
{
hr = _ReplaceDeviceGeneral(HIWORD(uPageID), lpfnReplacePage, lParam);
}
else if (LOWORD(uPageID) == WPDNSE_PROPSHEET_CONTENT_REFERENCES)
{
hr = _ReplaceContentReferences(HIWORD(uPageID), lpfnReplacePage, lParam);
}
return hr;
}
Karena pengguna dapat memilih beberapa perangkat, aplikasi harus menyimpan array PIDL yang dikembalikan oleh IShellExtInit::Initialize dan kemudian memeriksa bagian kata tertinggi dari parameter pertama ke ReplacePage. Nilai nol dalam kata tinggi ini sesuai dengan elemen pertama dalam array PIDL, nilai satu sesuai dengan elemen kedua, dan seterusnya. Dalam fungsi ReplacePage aplikasi sampel, nilai kata tinggi ini diteruskan ke kedua handler pengganti. Handler ini, pada gilirannya, menggunakan nilai ini untuk mengidentifikasi perangkat tertentu.
Topik terkait