コンテンツの列挙
デバイス上のコンテンツ (そのコンテンツがフォルダー、電話帳、ビデオ、または静止画像であるかどうか) は、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;
}
}
}
}
関連トピック