Enumerar contenido
El contenido de un dispositivo (si ese contenido es una carpeta, una libreta de teléfonos, un vídeo o una imagen fija) se denomina un objeto en la API de WPD. Estos objetos se hacen referencia mediante identificadores de objeto y se describen mediante propiedades. Puede enumerar los objetos de un dispositivo llamando a métodos en la interfaz IPortableDevice, la interfaz IPortableDeviceContent y la interfaz IEnumPortableDeviceObjectIDs.
La aplicación de ejemplo muestra la enumeración de contenido en la función EnumerateAllContent que se encuentra en el módulo ContentEnumeration.cpp. Esta función, a su vez, llama a una función RecursiveEnumerate que recorre la jerarquía de objetos encontrados en el dispositivo seleccionado y devuelve un identificador de objeto para cada objeto.
Como se indicó, la función RecursiveEnumerate recupera un identificador de objeto para cada objeto encontrado en el dispositivo. El identificador de objeto es un valor de cadena. Una vez que la aplicación recupera este identificador, puede obtener información de objeto más descriptiva (como el nombre del objeto, el identificador del elemento primario del objeto, etc.). Esta información descriptiva se conoce como propiedades de objeto (o metadatos). La aplicación puede recuperar estas propiedades llamando a los miembros de la interfaz IPortableDeviceProperties.
La función EnumerateAllContent comienza recuperando un puntero a una interfaz IPortableDeviceContent. Recupera este puntero llamando al método IPortableDevice::Content .
void EnumerateAllContent(
IPortableDevice* pDevice)
{
HRESULT hr = S_OK;
CComPtr<IPortableDeviceContent> pContent;
if (pDevice == NULL)
{
printf("! A NULL IPortableDevice interface pointer was received\n");
return;
}
// Get an IPortableDeviceContent interface from the IPortableDevice interface to
// access the content-specific methods.
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
// Enumerate content starting from the "DEVICE" object.
if (SUCCEEDED(hr))
{
printf("\n");
RecursiveEnumerate(WPD_DEVICE_OBJECT_ID, pContent);
}
}
Una vez recuperado el puntero a la interfaz IPortableDeviceContent, la función EnumerateAllContent llama a la función RecursiveEnumerate, que recorre la jerarquía de objetos que se encuentran en el dispositivo especificado y devuelve un identificador de objeto para cada uno.
La función RecursiveEnumerate comienza recuperando un puntero a una interfaz IEnumPortableDeviceObjectIDs. Esta interfaz expone los métodos que usa una aplicación para navegar por la lista de objetos encontrados en un dispositivo determinado.
En este ejemplo, la función RecursiveEnumerate llama al método IEnumPortableDeviceObjectIDs::Next para recorrer la lista de objetos.
Cada llamada al método IEnumPortableDeviceObjects::Next solicita un lote de 10 identificadores. (Este valor se especifica mediante la constante NUM_OBJECTS_TO_REQUEST que se proporciona como primer argumento).
#define NUM_OBJECTS_TO_REQUEST 10
// Recursively called function which enumerates using the specified
// object identifier as the parent.
void RecursiveEnumerate(
PCWSTR pszObjectID,
IPortableDeviceContent* pContent)
{
CComPtr<IEnumPortableDeviceObjectIDs> pEnumObjectIDs;
// Print the object identifier being used as the parent during enumeration.
printf("%ws\n",pszObjectID);
// Get an IEnumPortableDeviceObjectIDs interface by calling EnumObjects with the
// specified parent object identifier.
HRESULT hr = pContent->EnumObjects(0, // Flags are unused
pszObjectID, // Starting from the passed in object
NULL, // Filter is unused
&pEnumObjectIDs);
if (FAILED(hr))
{
printf("! Failed to get IEnumPortableDeviceObjectIDs from IPortableDeviceContent, hr = 0x%lx\n",hr);
}
// Loop calling Next() while S_OK is being returned.
while(hr == S_OK)
{
DWORD cFetched = 0;
PWSTR szObjectIDArray[NUM_OBJECTS_TO_REQUEST] = {0};
hr = pEnumObjectIDs->Next(NUM_OBJECTS_TO_REQUEST, // Number of objects to request on each NEXT call
szObjectIDArray, // Array of PWSTR array which will be populated on each NEXT call
&cFetched); // Number of objects written to the PWSTR array
if (SUCCEEDED(hr))
{
// Traverse the results of the Next() operation and recursively enumerate
// Remember to free all returned object identifiers using CoTaskMemFree()
for (DWORD dwIndex = 0; dwIndex < cFetched; dwIndex++)
{
RecursiveEnumerate(szObjectIDArray[dwIndex],pContent);
// Free allocated PWSTRs after the recursive enumeration call has completed.
CoTaskMemFree(szObjectIDArray[dwIndex]);
szObjectIDArray[dwIndex] = NULL;
}
}
}
}
Temas relacionados