Compartir a través de


Recuperar propiedades para varios objetos

Algunos controladores de dispositivos admiten la recuperación de propiedades para varios objetos en una sola llamada de función; esto se conoce como recuperación masiva. Hay dos tipos de operaciones de recuperación masiva: el primer tipo recupera las propiedades de una lista de objetos y el segundo tipo recupera propiedades para todos los objetos de un formato determinado. En el ejemplo descrito en esta sección se muestra el anterior.

La aplicación puede realizar una recuperación masiva mediante las interfaces descritas en la tabla siguiente.

Interfaz Descripción
IPortableDeviceContent (Interfaz) Proporciona acceso a los métodos específicos del contenido.
IPortableDeviceKeyCollection (Interfaz) Se usa para identificar las propiedades que se van a recuperar.
IPortableDeviceProperties (interfaz) Se usa para determinar si un controlador determinado admite operaciones masivas.
IPortableDevicePropertiesBulk (Interfaz) Admite la operación de recuperación masiva.
IPortableDevicePropVariantCollection (Interfaz) Se usa para almacenar los identificadores de objeto para la operación masiva.

 

La función ReadContentPropertiesBulk del módulo ContentProperties.cpp de la aplicación de ejemplo muestra una operación de recuperación masiva.

La primera tarea realizada en este ejemplo es determinar si el controlador especificado admite o no operaciones masivas. Esto se logra llamando a QueryInterface en la interfaz IPortableDeviceProperties y comprobando la existencia de 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");
    }
}

Si el controlador admite operaciones masivas, el siguiente paso es crear una instancia de la interfaz IPortableDeviceKeyCollection y especificar las claves que corresponden a las propiedades que recuperará la aplicación. Para obtener una descripción de este proceso, consulte el tema Recuperación de propiedades para un único objeto .

Una vez especificadas las claves adecuadas, la aplicación de ejemplo crea una instancia de la interfaz IPortableDevicePropertiesBulkCallback. La aplicación usará los métodos de esta interfaz para realizar un seguimiento del progreso de la operación de recuperación masiva asincrónica.

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

La siguiente función a la que llama la aplicación de ejemplo es la función auxiliar CreateIPortableDevicePropVariantCollectionWithAllObjectIDs. Esta función crea una lista de todos los identificadores de objeto disponibles con fines de ejemplo. (Una aplicación real limitaría la lista de identificadores a un conjunto determinado de objetos. Por ejemplo, una aplicación puede crear una lista de identificadores para todos los objetos actualmente en una vista de carpeta determinada).

Como se indicó anteriormente, la función auxiliar enumera de forma recursiva todos los objetos de un dispositivo determinado. Devuelve esta lista en una interfaz IPortableDevicePropVariantCollection que contiene un identificador para cada objeto que encontró. La función auxiliar se define en el módulo 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);
}

Una vez que se realizan los pasos anteriores, la aplicación de ejemplo inicia la recuperación de propiedades asincrónicas. Esto se logra haciendo lo siguiente:

  1. Llamada a IPortableDevicePropertiesBulk::QueueGetValuesByObjectList, que pone en cola una solicitud para la recuperación masiva de propiedades. (Tenga en cuenta que, aunque la solicitud está en cola, no se inicia).
  2. Llamar a IPortableDevicePropertiesBulk::Start para iniciar la solicitud en cola.

Estos pasos se muestran en el siguiente fragmento de código de la aplicación de ejemplo.

   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 (interfaz)

IPortableDeviceContent (Interfaz)

IPortableDeviceKeyCollection (Interfaz)

IPortableDeviceProperties (interfaz)

IPortableDevicePropertiesBulk (Interfaz)

IPortableDevicePropVariantCollection (Interfaz)

Guía de programación