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


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

Содержимое на устройстве (будь то папка, телефонная книга, видео или статическое изображение) называется объектом в 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

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