共用方式為


擷取多個物件的屬性

某些設備驅動器支援在單一函數調用中擷取多個對象的屬性;這稱為大量擷取。 大量擷取作業有兩種類型:第一種類型會擷取物件清單的屬性,而第二種類型會擷取指定格式之所有對象的屬性。 本節所述的範例示範前者。

您的應用程式可以使用下表所述的介面來執行大量擷取。

介面 描述
IPortableDeviceContent 介面 提供對於特定內容方法的存取權限。
IPortableDeviceKeyCollection 介面 用來識別要擷取的屬性。
IPortableDeviceProperties 介面 用來判斷指定的驅動程式是否支援大量作業。
IPortableDevicePropertiesBulk 介面 支援大量擷取作業。
IPortableDevicePropVariantCollection 介面 用於儲存批量操作的物件識別碼。

 

範例應用程式ContentProperties.cpp模組中的 ReadContentPropertiesBulk 函式示範大量擷取作業。

此範例中完成的第一項工作是判斷指定的驅動程式是否支援大量作業。 這可藉由在 IPortableDeviceProperties 介面上呼叫 QueryInterface,並檢查 IPortableDevicePropertiesBulk 是否存在來完成。

HRESULT                                       hr                = S_OK;
GUID                                          guidContext       = GUID_NULL;
CGetBulkValuesCallback*                       pCallback         = NULL;
CComPtr<IPortableDeviceProperties>            pProperties;
CComPtr<IPortableDevicePropertiesBulk>        pPropertiesBulk;
CComPtr<IPortableDeviceValues>                pObjectProperties;
CComPtr<IPortableDeviceContent>               pContent;
CComPtr<IPortableDeviceKeyCollection>         pPropertiesToRead;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;


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");
    }
}

如果驅動程式支援大量作業,下一個步驟是建立 IPortableDeviceKeyCollection 介面的實例,並指定對應至應用程式所擷取之屬性的索引鍵。 如需此過程的描述,請參閱 檢索單一物件屬性 主題。

指定適當的金鑰之後,範例應用程式會建立 IPortableDevicePropertiesBulkCallback 介面的實例。 應用程式會使用此介面中的方法來追蹤異步大量擷取作業的進度。

if (SUCCEEDED(hr))
{
    pCallback = new CGetBulkValuesCallback();
    if (pCallback == NULL)
    {
        hr = E_OUTOFMEMORY;
        printf("! Failed to allocate CGetBulkValuesCallback, hr = 0x%lx\n", hr);
    }
}

範例應用程式呼叫的下一個函式是 CreateIPortableDevicePropVariantCollectionWithAllObjectIDs 協助程式函式。 此函式會針對範例目的,建立所有可用對象識別碼的清單。 (真實世界應用程式會將標識符清單限制為一組特定的物件。例如,應用程式可能會為目前在指定資料夾檢視中的所有物件建立標識符清單。

如上所述,協助程式函式會遞歸列舉指定裝置上的所有物件。 它會在 IPortableDevicePropVariantCollection 介面 傳回此清單,其中包含找到之每個物件的標識碼。 協助程式函式定義於模組ContentEnumeration.cpp中。

// 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);
}

完成上述步驟之後,範例應用程式會起始異步屬性擷取。 執行下列動作可達成此目的:

  1. 呼叫 IPortableDevicePropertiesBulk::QueueGetValuesByObjectList,其會將大量屬性擷取的要求排入佇列。 (請注意,雖然要求已排入佇列,但尚未啟動。
  2. 呼叫 IPortableDevicePropertiesBulk::Start 開始排隊請求。

這些步驟示範於範例應用程式的下列程式代碼摘錄中。

   if (SUCCEEDED(hr))
   {
       hr = pPropertiesBulk->QueueGetValuesByObjectList(pObjectIDs,
                                                        pPropertiesToRead,
                                                        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("! QueueGetValuesByObjectList Failed, hr = 0x%lx\n", hr);
       }
   }

IPortableDevice 介面

IPortableDeviceContent 介面

IPortableDeviceKeyCollection 介面

IPortableDeviceProperties 介面

IPortableDevicePropertiesBulk 介面

IPortableDevicePropVariantCollection 介面

程式設計手冊