枚举内容

设备上的内容 (该内容是文件夹、电话簿、视频还是静止图像,) 在 WPD API 中称为 对象。 这些对象由对象标识符引用,并由属性描述。 可以通过调用 IPortableDevice 接口、IPortableDeviceContent 接口IEnumPortableDeviceObjectIDs 接口中的方法来枚举设备上的对象。

示例应用程序演示在 ContentEnumeration.cpp 模块中找到的 EnumerateAllContent 函数中的内容枚举。 此函数反过来调用 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 接口

编程指南