Поделиться через


Перечисление содержимого

Содержимое на устройстве (будь то папка, телефонная книга, видео или неподвижное изображение) называется объектом в API WPD. На эти объекты ссылаются идентификаторы объектов и описываются свойствами. Вы можете перечислить объекты на устройстве, вызвав методы в интерфейсе IPortableDevice, интерфейсе IPortableDeviceContent и интерфейсе IEnumPortableDeviceObjectIDs.

Пример приложения демонстрирует перечисление содержимого в функции EnumerateAllContent, которая находится в модуле ContentEnumeration.cpp. Эта функция, в свою очередь, вызывает функцию RecursiveEnumerate, которая проходит по иерархии объектов, найденных на выбранном устройстве, и возвращает идентификатор объекта для каждого объекта.

Как уже отмечалось, функция RecursiveEnumerate извлекает идентификатор объекта для каждого объекта, найденного на устройстве. Идентификатор объекта является строковым значением. После получения этого идентификатора приложение может получить более описательные сведения об объекте (например, имя объекта, идентификатор родительского объекта и т. д.). Эти описательные сведения называются свойствами объекта (или метаданными). Приложение может получить эти свойства, вызывая члены интерфейса IPortableDeviceProperties.

Функция EnumerateAllContent начинается с получения указателя на интерфейс IPortableDeviceContent. Он извлекает этот указатель путем вызова метода 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);
    }
}

После получения указателя на интерфейс IPortableDeviceContent функция EnumerateAllContent вызывает функцию RecursiveEnumerate, которая проходит по иерархии объектов, найденных на данном устройстве, и возвращает идентификатор объекта для каждого из них.

Функция RecursiveEnumerate начинается с получения указателя на интерфейс IEnumPortableDeviceObjectIDs. Этот интерфейс предоставляет методы, которые приложение использует для навигации по списку объектов, найденных на данном устройстве.

В этом примере функция RecursiveEnumerate вызывает метод IEnumPortableDeviceObjectIDs::Next для обхода списка объектов.

Каждый вызов метода IEnumPortableDeviceObjects::Next запрашивает пакет из 10 идентификаторов. (Это значение задается константой NUM_OBJECTS_TO_REQUEST, предоставленной в качестве первого аргумента.)

#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;
            }
        }
    }
}

Интерфейс IEnumPortableDeviceObjectIDs

Интерфейс IPortableDevice

Интерфейс IPortableDeviceContent

Интерфейс IPortableDeviceProperties

Руководство по программированию