Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bazı cihaz sürücüleri, tek bir işlev çağrısında birden çok nesnenin özelliklerini ayarlamayı destekler; bu, toplu yazma olarak adlandırılır. Uygulamanız, aşağıdaki tabloda açıklanan arabirimleri kullanarak toplu yazma gerçekleştirebilir.
| Arayüz | Açıklama |
|---|---|
| IPortableDeviceContent Arabirimi | İçeriğe özgü yöntemlere erişim sağlar. |
| IPortableDeviceProperties Arabirimi | Özelliğe özgü yöntemlere erişim sağlar. |
| IPortableDevicePropertiesBulk Arabirimi | Toplu yazma işlemini destekler. |
| IPortableDevicePropVariantCollection Arabirimi | Toplu işlemin nesne tanımlayıcılarını depolamak için kullanılır. |
| IPortableDeviceValuesCollection Arabirimi | Yazılacak özellikleri tanımlamak için kullanılır. |
Örnek uygulamanın ContentProperties.cpp modülündeki WriteContentPropertiesBulk işlevi toplu yazma işlemini gösterir.
Bu örnekte gerçekleştirilir ilk görev, verilen sürücünün toplu işlemleri destekleyip desteklemediğini belirlemektir. Bu, IPortableDeviceProperties nesnesinde QueryInterface çağrısı yaparak ve IPortableDevicePropertiesBulkvarlığını denetleyerek gerçekleştirilir.
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CSetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceValuesCollection> pPropertiesToWrite;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
DWORD cObjectIDs = 0;
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->Properties(&pProperties);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
}
}
if (SUCCEEDED(hr))
{
hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
if (FAILED(hr))
{
printf("This driver does not support BULK property operations.\n");
}
}
Sonraki görev, IPortableDeviceValuesCollection nesnesi oluşturmayı gerektirir. Bu, örneğin yazacağı özellik değerlerini içeren nesnedir.
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CSetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceValuesCollection> pPropertiesToWrite;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
DWORD cObjectIDs = 0;
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_PortableDeviceValuesCollection,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPortableDeviceValuesCollection,
(VOID**) &pPropertiesToWrite);
if (FAILED(hr))
{
printf("! Failed to CoCreate IPortableDeviceValuesCollection for bulk property values, hr = 0x%lx\n", hr);
}
}
Bundan sonra örnek,IPortableDevicePropertiesBulkCallback arabiriminin bir örneğini oluşturur. Uygulama, zaman uyumsuz toplu yazma işleminin ilerleme durumunu izlemek için bu arabirimdeki yöntemleri kullanır.
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CSetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceValuesCollection> pPropertiesToWrite;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
DWORD cObjectIDs = 0;
if (SUCCEEDED(hr))
{
pCallback = new CSetBulkValuesCallback();
if (pCallback == NULL)
{
hr = E_OUTOFMEMORY;
printf("! Failed to allocate CSetBulkValuesCallback, hr = 0x%lx\n", hr);
}
}
Örnek uygulamanın çağırdığı bir sonraki işlev CreateIPortableDevicePropVariantCollectionWithAllObjectIDs yardımcı işlevdir. Bu işlev, belirli bir cihazdaki tüm nesneleri yinelemeli olarak numaralandırır ve bulduğu her nesne için bir tanımlayıcı içeren IPortableDevicePropVariantCollection arabirimi döndürür. Bu işlev modül ContentEnumeration.cpp tanımlanır.
// 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
// to enumerate and create an IPortableDevicePropVariantCollection with the object
// identifiers needed to perform the bulk operation on.
if (SUCCEEDED(hr))
{
hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pDevice,
pContent,
&pObjectIDs);
}
IPortableDevicePropVariantCollection nesnesi, aynı VARTYPE'ın dizinli PROPVARIANT değerlerinden oluşan bir koleksiyonu tutar. Bu durumda, bu değerler cihazda bulunan her nesne için belirli bir nesne tanımlayıcısı içerir.
Nesne tanımlayıcıları ve ilgili ad özellikleri IPortableDeviceValuesCollection nesnesinde depolanır. Ad özellikleri, ilk nesneye "NewName0" ad özelliği atanması, ikinci nesneye "NewName1" ad özelliği atanması vb. için düzenlenir.
Örnekten aşağıdaki alıntı, IPortableDeviceValuesCollection nesnesinin nesne tanımlayıcıları ve yeni ad dizeleriyle nasıl başlatıldığını gösterir.
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CSetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceValuesCollection> pPropertiesToWrite;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
DWORD cObjectIDs = 0;
if (SUCCEEDED(hr))
{
hr = pObjectIDs->GetCount(&cObjectIDs);
if (FAILED(hr))
{
printf("! Failed to get number of objectIDs from IPortableDevicePropVariantCollection, hr = 0x%lx\n", hr);
}
}
if (SUCCEEDED(hr))
{
for(DWORD dwIndex = 0; (dwIndex < cObjectIDs) && (hr == S_OK); dwIndex++)
{
CComPtr<IPortableDeviceValues> pValues;
PROPVARIANT pv = {0};
PropVariantInit(&pv);
hr = CoCreateInstance(CLSID_PortableDeviceValues,
NULL,
CLSCTX_INPROC_SERVER,
IID_IPortableDeviceValues,
(VOID**) &pValues);
if (FAILED(hr))
{
printf("! Failed to CoCreate CLSID_PortableDeviceValues, hr = 0x%lx\n", hr);
}
// Get the Object ID whose properties we will set
if (hr == S_OK)
{
hr = pObjectIDs->GetAt(dwIndex, &pv);
if (FAILED(hr))
{
printf("! Failed to get next Object ID from list, hr = 0x%lx\n", hr);
}
}
// Save them into the IPortableDeviceValues so the driver knows which object this proeprty set belongs to
if (hr == S_OK)
{
hr = pValues->SetStringValue(WPD_OBJECT_ID, pv.pwszVal);
if (FAILED(hr))
{
printf("! Failed to set WPD_OBJECT_ID, hr = 0x%lx\n", hr);
}
}
// Set the new values. In this sample, we attempt to set the name property.
if (hr == S_OK)
{
CAtlStringW strValue;
strValue.Format(L"NewName%d", dwIndex);
hr = pValues->SetStringValue(WPD_OBJECT_NAME, strValue.GetString());
if (FAILED(hr))
{
printf("! Failed to set WPD_OBJECT_NAME, hr = 0x%lx\n", hr);
}
}
// Add this property set to the collection
if (hr == S_OK)
{
hr = pPropertiesToWrite->Add(pValues);
if (FAILED(hr))
{
printf("! Failed to add values to collection, hr = 0x%lx\n", hr);
}
}
PropVariantClear(&pv);
}
}
Örnek, nesne tanımlayıcısını ve ad çiftlerini içeren IPortableDeviceValuesCollection nesnesini oluşturduğunda, zaman uyumsuz işlemi başlatabilir.
Zaman uyumsuz yazma işlemi, örnek IPortableDevicePropertiesBulk::QueueSetValuesByObjectList yöntemini çağırdığında başlar. Bu yöntem, toplu işlemin başlamak üzere olduğunu sürücüye bildirir. Bundan sonra örnek, yeni ad değerlerini yazmaya başlamak için IPortableDeviceBulk::Start yöntemini çağırır.
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CSetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceValuesCollection> pPropertiesToWrite;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
DWORD cObjectIDs = 0;
if (SUCCEEDED(hr))
{
hr = pPropertiesBulk->QueueSetValuesByObjectList(pPropertiesToWrite,
pCallback,
&guidContext);
if(SUCCEEDED(hr))
{
// Cleanup any previously created global event handles.
if (g_hBulkPropertyOperationEvent != NULL)
{
CloseHandle(g_hBulkPropertyOperationEvent);
g_hBulkPropertyOperationEvent = NULL;
}
// In order to create a simpler to follow example we create and wait infinitly
// for the bulk property operation to complete and ignore any errors.
// Production code should be written in a more robust manner.
// Create the global event handle to wait on for the bulk operation
// to complete.
g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hBulkPropertyOperationEvent != NULL)
{
// Call Start() to actually being the Asynchronous bulk operation.
hr = pPropertiesBulk->Start(guidContext);
if(FAILED(hr))
{
printf("! Failed to start property operation, hr = 0x%lx\n", hr);
}
}
else
{
printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
}
}
else
{
printf("! QueueSetValuesByObjectList Failed, hr = 0x%lx\n", hr);
}
}
Örneğin işlemin tamamlanması için sonsuz uzun bir süre beklediğini unutmayın. Bu bir üretim uygulaması olsaydı kodun değiştirilmesi gerekirdi.
İlgili konular