Compartilhar via


Recuperando propriedades para vários objetos

Alguns drivers de dispositivo dão suporte à recuperação de propriedades para vários objetos em uma única chamada de função; isso é chamado de recuperação em massa. Há dois tipos de operações de recuperação em massa: o primeiro tipo recupera propriedades para uma lista de objetos e o segundo tipo recupera propriedades para todos os objetos de um determinado formato. O exemplo descrito nesta seção demonstra o primeiro.

Seu aplicativo pode executar uma recuperação em massa usando as interfaces descritas na tabela a seguir.

Interface Descrição
IPortableDeviceContent Interface Fornece acesso aos métodos específicos do conteúdo.
IPortableDeviceKeyCollection Interface Usado para identificar as propriedades a serem recuperadas.
IPortableDeviceProperties Interface Usado para determinar se um determinado driver dá suporte a operações em massa.
IPortableDevicePropertiesBulk Interface Dá suporte à operação de recuperação em massa.
IPortableDevicePropVariantCollection Interface Usado para armazenar os identificadores de objeto para a operação em massa.

 

A função ReadContentPropertiesBulk no módulo ContentProperties.cpp do aplicativo de exemplo demonstra uma operação de recuperação em massa.

A primeira tarefa realizada neste exemplo é determinar se o driver determinado dá suporte ou não a operações em massa. Isso é feito chamando QueryInterface na interface IPortableDeviceProperties e verificando a existência 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");
    }
}

Se o driver der suporte a operações em massa, a próxima etapa será criar uma instância da interface IPortableDeviceKeyCollection e especificar as chaves que correspondem às propriedades que o aplicativo recuperará. Para obter uma descrição desse processo, consulte o tópico Recuperando propriedades de um único objeto .

Depois que as chaves apropriadas são especificadas, o aplicativo de exemplo cria uma instância da interface IPortableDevicePropertiesBulkCallback. O aplicativo usará os métodos nessa interface para acompanhar o progresso da operação de recuperação em massa assíncrona.

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

A próxima função que o aplicativo de exemplo chama é a função auxiliar CreateIPortableDevicePropVariantCollectionWithAllObjectIDs. Essa função cria uma lista de todos os identificadores de objeto disponíveis para fins de exemplo. (Um aplicativo do mundo real limitaria a lista de identificadores a um determinado conjunto de objetos. Por exemplo, um aplicativo pode criar uma lista de identificadores para todos os objetos atualmente em uma determinada exibição de pasta.)

Conforme observado acima, a função auxiliar enumera recursivamente todos os objetos em um determinado dispositivo. Ele retorna essa lista em uma interface IPortableDevicePropVariantCollection que contém um identificador para cada objeto encontrado. A função auxiliar é definida no 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);
}

Depois que as etapas anteriores forem realizadas, o aplicativo de exemplo iniciará a recuperação de propriedade assíncrona. Isso é feito fazendo o seguinte:

  1. Chamando IPortableDevicePropertiesBulk::QueueGetValuesByObjectList, que enfileira uma solicitação para a recuperação de propriedade em massa. (Observe que, embora a solicitação esteja na fila, ela não foi iniciada.)
  2. Chamando IPortableDevicePropertiesBulk::Start para iniciar a solicitação na fila.

Essas etapas são demonstradas no trecho de código a seguir do aplicativo de exemplo.

   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 Interface

IPortableDeviceContent Interface

IPortableDeviceKeyCollection Interface

IPortableDeviceProperties Interface

IPortableDevicePropertiesBulk Interface

IPortableDevicePropVariantCollection Interface

Guia de programação