Share via


Récupération des propriétés de plusieurs objets

Certains pilotes de périphérique prennent en charge la récupération des propriétés de plusieurs objets dans un seul appel de fonction ; il s’agit d’une récupération en bloc. Il existe deux types d’opérations de récupération en bloc : le premier type récupère les propriétés d’une liste d’objets et le second type récupère les propriétés de tous les objets d’un format donné. L’exemple décrit dans cette section illustre la première.

Votre application peut effectuer une récupération en bloc à l’aide des interfaces décrites dans le tableau suivant.

Interface Description
IPortableDeviceContent, interface Fournit l’accès aux méthodes spécifiques au contenu.
IPortableDeviceKeyCollection, interface Utilisé pour identifier les propriétés à récupérer.
IPortableDeviceProperties, interface Permet de déterminer si un pilote donné prend en charge les opérations en bloc.
IPortableDevicePropertiesBulk, interface Prend en charge l’opération de récupération en bloc.
IPortableDevicePropVariantCollection, interface Permet de stocker les identificateurs d’objet de l’opération en bloc.

 

La fonction ReadContentPropertiesBulk dans le module ContentProperties.cpp de l’exemple d’application illustre une opération de récupération en bloc.

La première tâche accomplie dans cet exemple consiste à déterminer si le pilote donné prend ou non en charge les opérations en bloc. Pour ce faire, appelez QueryInterface sur l’interface IPortableDeviceProperties et vérifiez l’existence d’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 le pilote prend en charge les opérations en bloc, l’étape suivante consiste à créer un instance de l’interface IPortableDeviceKeyCollection et à spécifier les clés qui correspondent aux propriétés que l’application va récupérer. Pour obtenir une description de ce processus, consultez la rubrique Récupération des propriétés d’un objet unique .

Une fois les clés appropriées spécifiées, l’exemple d’application crée un instance de l’interface IPortableDevicePropertiesBulkCallback. L’application utilisera les méthodes de cette interface pour suivre la progression de l’opération de récupération en bloc asynchrone.

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

La fonction suivante que l’exemple d’application appelle est la fonction d’assistance CreateIPortableDevicePropVariantCollectionWithAllObjectIDs. Cette fonction crée une liste de tous les identificateurs d’objet disponibles à des fins d’exemple. (Une application réelle limiterait la liste des identificateurs à un ensemble particulier d’objets. Par instance, une application peut créer une liste d’identificateurs pour tous les objets actuellement dans un affichage de dossiers donné.)

Comme indiqué ci-dessus, la fonction d’assistance énumère de manière récursive tous les objets sur un appareil donné. Elle retourne cette liste dans une interface IPortableDevicePropVariantCollection qui contient un identificateur pour chaque objet trouvé. La fonction d’assistance est définie dans le module 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);
}

Une fois les étapes précédentes effectuées, l’exemple d’application lance la récupération asynchrone des propriétés. Pour ce faire, procédez comme suit :

  1. Appel de IPortableDevicePropertiesBulk::QueueGetValuesByObjectList, qui met en file d’attente une demande de récupération de propriété en bloc. (Notez que bien que la requête soit mise en file d’attente, elle n’est pas démarrée.)
  2. Appel de IPortableDevicePropertiesBulk::Start pour lancer la requête mise en file d’attente.

Ces étapes sont illustrées dans l’extrait de code suivant de l’exemple d’application.

   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

Guide de programmation