Menambahkan Sumber Daya ke Objek
Selain mentransfer objek ke perangkat, Anda juga dapat menambahkan sumber daya ke objek. Misalnya, aplikasi dapat menambahkan foto ke informasi yang ada untuk kontak tertentu.
Sumber daya ditambahkan menggunakan antarmuka yang dijelaskan dalam tabel berikut.
Antarmuka | Deskripsi |
---|---|
Antarmuka IPortableDeviceContent | Menyediakan akses ke metode khusus konten. |
Antarmuka IPortableDeviceResources | Digunakan saat menulis properti sumber daya dan data ke perangkat. |
Antarmuka IPortableDeviceValues | Digunakan untuk menulis properti yang menjelaskan sumber daya. |
Antarmuka IStream | Digunakan untuk menyederhanakan penulisan sumber daya ke perangkat. |
Fungsi CreateContactPhotoResourceOnDevice dalam modul ContentTransfer.cpp aplikasi sampel menunjukkan bagaimana aplikasi dapat menambahkan sumber daya foto ke objek kontak. Fungsi ini meminta pengguna untuk pengidentifikasi objek kontak pada perangkat, tempat sumber daya foto akan ditambahkan. Kemudian menampilkan kotak dialog FileBuka sehingga pengguna dapat memilih gambar yang akan ditambahkan. Setelah data ini dikumpulkan, aplikasi menulis sumber daya ke perangkat.
Tugas pertama yang dicapai oleh fungsi CreateContactPhotoResourceOnDevice adalah meminta pengguna untuk memasukkan pengidentifikasi objek untuk kontak tempat foto akan ditambahkan.
HRESULT hr = S_OK;
WCHAR wszSelection[81] = {0};
WCHAR wszFilePath[MAX_PATH] = {0};
DWORD cbOptimalTransferSize = 0;
CComPtr<IStream> pFileStream;
CComPtr<IStream> pResourceStream;
CComPtr<IPortableDeviceValues> pResourceAttributes;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
printf("Enter the identifer of the object to which we will add an Audio annotation.\n>");
hr = StringCbGetsW(wszSelection,sizeof(wszSelection));
if (FAILED(hr))
{
printf("An invalid object identifier was specified, aborting resource creation\n");
}do
Langkah selanjutnya adalah pengambilan objek IPortableDeviceContent , yang pada gilirannya digunakan untuk mendapatkan objek IPortableDeviceResources . (Aplikasi menggunakan objek terakhir ini untuk membuat dan menulis sumber daya baru.)
HRESULT hr = S_OK;
WCHAR wszSelection[81] = {0};
WCHAR wszFilePath[MAX_PATH] = {0};
DWORD cbOptimalTransferSize = 0;
CComPtr<IStream> pFileStream;
CComPtr<IStream> pResourceStream;
CComPtr<IPortableDeviceValues> pResourceAttributes;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
if (SUCCEEDED(hr))
{
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
}
if (SUCCEEDED(hr))
{
hr = pContent->Transfer(&pResources);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceResources from IPortableDeviceContent, hr = 0x%lx\n",hr);
}
}
Setelah ini, sampel menampilkan kotak dialog FileBuka , yang memungkinkan pengguna menentukan nama file gambar yang berisi foto yang ingin mereka tambahkan ke informasi kontak.
HRESULT hr = S_OK;
WCHAR wszSelection[81] = {0};
WCHAR wszFilePath[MAX_PATH] = {0};
DWORD cbOptimalTransferSize = 0;
CComPtr<IStream> pFileStream;
CComPtr<IStream> pResourceStream;
CComPtr<IPortableDeviceValues> pResourceAttributes;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
if (SUCCEEDED(hr))
{
OPENFILENAME OpenFileNameInfo = {0};
OpenFileNameInfo.lStructSize = sizeof(OPENFILENAME);
OpenFileNameInfo.hwndOwner = NULL;
OpenFileNameInfo.lpstrFile = wszFilePath;
OpenFileNameInfo.nMaxFile = ARRAYSIZE(wszFilePath);
OpenFileNameInfo.lpstrFilter = L"JPEG (*.JPG)\0*.JPG\0JPEG (*.JPEG)\0*.JPEG\0JPG (*.JPE)\0*.JPE\0JPG (*.JFIF)\0*.JFIF\0\0";;
OpenFileNameInfo.nFilterIndex = 1;
OpenFileNameInfo.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
OpenFileNameInfo.lpstrDefExt = L"JPG";
if (GetOpenFileName(&OpenFileNameInfo) == FALSE)
{
printf("The transfer operation was cancelled.\n");
hr = E_ABORT;
}
}
Setelah sampel memiliki objek IPortableDeviceResources dan nama file gambar, sampel melakukan hal berikut sebagai persiapan untuk benar-benar mentransfer data ke perangkat.
- Ini membuka objek IStream pada file yang dipilih untuk operasi baca.
- Ini membuat objek IPortableDeviceValues , yang akan berisi informasi seperti ukuran dan format gambar.
HRESULT hr = S_OK;
WCHAR wszSelection[81] = {0};
WCHAR wszFilePath[MAX_PATH] = {0};
DWORD cbOptimalTransferSize = 0;
CComPtr<IStream> pFileStream;
CComPtr<IStream> pResourceStream;
CComPtr<IPortableDeviceValues> pResourceAttributes;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
if (SUCCEEDED(hr))
{
// Open the selected file as an IStream. This will simplify reading the
// data and writing to the device.
hr = SHCreateStreamOnFile(wszFilePath, STGM_READ, &pFileStream);
if (SUCCEEDED(hr))
{
// CoCreate the IPortableDeviceValues to hold the resource attributes
hr = CoCreateInstance(CLSID_PortableDeviceValues,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPortableDeviceValues,
(VOID**) &pResourceAttributes);
if (SUCCEEDED(hr))
{
// Fill in the necessary information regarding this resource
// Set the WPD_OBJECT_ID. This informs the driver which object this request is intended for.
hr = pResourceAttributes->SetStringValue(WPD_OBJECT_ID, wszSelection);
if (FAILED(hr))
{
printf("! Failed to set WPD_OBJECT_ID when creating a resource, hr = 0x%lx\n",hr);
}
// Set the WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY to WPD_RESOURCE_CONTACT_PHOTO
if (SUCCEEDED(hr))
{
hr = pResourceAttributes->SetKeyValue(WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY, WPD_RESOURCE_CONTACT_PHOTO);
if (FAILED(hr))
{
printf("! Failed to set WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY to WPD_RESOURCE_CONTACT_PHOTO, hr = 0x%lx\n",hr);
}
}
// Set the WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE by requesting the total size of the
// data stream.
if (SUCCEEDED(hr))
{
STATSTG statstg = {0};
hr = pFileStream->Stat(&statstg, STATFLAG_NONAME);
if (SUCCEEDED(hr))
{
hr = pResourceAttributes->SetUnsignedLargeIntegerValue(WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE, statstg.cbSize.QuadPart);
if (FAILED(hr))
{
printf("! Failed to set WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE, hr = 0x%lx\n",hr);
}
}
else
{
printf("! Failed to get file's total size, hr = 0x%lx\n",hr);
}
}
// Set the WPD_RESOURCE_ATTRIBUTE_FORMAT to WPD_OBJECT_FORMAT_JFIF because we are
// creating a contact photo resource with JPG image data.
if (SUCCEEDED(hr))
{
hr = pResourceAttributes->SetGuidValue(WPD_RESOURCE_ATTRIBUTE_FORMAT, WPD_OBJECT_FORMAT_JFIF);
if (FAILED(hr))
{
printf("! Failed to set WPD_RESOURCE_ATTRIBUTE_FORMAT to WPD_OBJECT_FORMAT_JFIF, hr = 0x%lx\n",hr);
}
}
}
}
if (FAILED(hr))
{
printf("! Failed to open file named (%ws) to transfer to device, hr = 0x%lx\n",wszFilePath, hr);
}
}
Setelah menyiapkan objek IStream dan IPortableDeviceValues untuk operasi tulis, sampel mentransfer gambar ke perangkat. Sampel menyelesaikan transfer dalam tiga langkah, sebagai berikut:
- Ini membuat sumber daya pada perangkat dengan memanggil metode IPortableDeviceResources::CreateResource .
- Ini memanggil fungsi pembantu StreamCopy untuk menyalin aliran sumber ke aliran tujuan.
- Ini menginformasikan driver perangkat bahwa transfer selesai dengan memanggil metode IPortableDeviceDataStream::Commit.
HRESULT hr = S_OK;
WCHAR wszSelection[81] = {0};
WCHAR wszFilePath[MAX_PATH] = {0};
DWORD cbOptimalTransferSize = 0;
CComPtr<IStream> pFileStream;
CComPtr<IStream> pResourceStream;
CComPtr<IPortableDeviceValues> pResourceAttributes;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceResources> pResources;
if (SUCCEEDED(hr))
{
hr = pResources->CreateResource(pResourceAttributes, // Properties describing this resource
&pResourceStream, // Returned resource data stream (to transfer the data to)
&cbOptimalTransferSize, // Returned optimal buffer size to use during transfer
NULL);
// Since we have IStream-compatible interfaces, call our helper function
// that copies the contents of a source stream into a destination stream.
if (SUCCEEDED(hr))
{
DWORD cbTotalBytesWritten = 0;
hr = StreamCopy(pResourceStream, // Destination (The resource to transfer to)
pFileStream, // Source (The File data to transfer from)
cbOptimalTransferSize, // The driver specified optimal transfer buffer size
&cbTotalBytesWritten); // The total number of bytes transferred from file to the device
if (FAILED(hr))
{
printf("! Failed to transfer object to device, hr = 0x%lx\n",hr);
}
}
else
{
printf("! Failed to get IStream (representing destination object data on the device) from IPortableDeviceContent, hr = 0x%lx\n",hr);
}
// After transferring content to the device, the client is responsible for letting the
// driver know that the transfer is complete by calling the Commit() method
// on the IPortableDeviceDataStream interface.
if (SUCCEEDED(hr))
{
hr = pResourceStream->Commit(0);
if (FAILED(hr))
{
printf("! Failed to commit resource to device, hr = 0x%lx\n",hr);
}
}
}
Topik terkait
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk