複数のオブジェクトのプロパティを取得する
一部のデバイス ドライバーは、1 つの関数呼び出しで複数のオブジェクトのプロパティの取得をサポートしています。これは一括取得と呼ばれます。 一括取得操作には 2 種類あります。最初の型はオブジェクトの一覧のプロパティを取得し、2 番目の型は特定の形式のすべてのオブジェクトのプロパティを取得します。 このセクションで説明する例では、前者を示します。
アプリケーションは、次の表に示すインターフェイスを使用して一括取得を実行できます。
インターフェイス | 説明 |
---|---|
IPortableDeviceContent インターフェイス | コンテンツ固有のメソッドへのアクセスを提供します。 |
IPortableDeviceKeyCollection インターフェイス | 取得するプロパティを識別するために使用されます。 |
IPortableDeviceProperties インターフェイス | 特定のドライバーが一括操作をサポートしているかどうかを判断するために使用されます。 |
IPortableDevicePropertiesBulk インターフェイス | 一括取得操作をサポートします。 |
IPortableDevicePropVariantCollection インターフェイス | 一括操作のオブジェクト識別子を格納するために使用されます。 |
サンプル アプリケーションの ContentProperties.cpp モジュールの ReadContentPropertiesBulk 関数は、一括取得操作を示しています。
このサンプルで最初に実行するタスクは、指定されたドライバーが一括操作をサポートしているかどうかを判断することです。 これを行うには、IPortableDeviceProperties インターフェイスで QueryInterface を呼び出し、IPortableDevicePropertiesBulk の存在を確認します。
HRESULT hr = S_OK;
GUID guidContext = GUID_NULL;
CGetBulkValuesCallback* pCallback = NULL;
CComPtr<IPortableDeviceProperties> pProperties;
CComPtr<IPortableDevicePropertiesBulk> pPropertiesBulk;
CComPtr<IPortableDeviceValues> pObjectProperties;
CComPtr<IPortableDeviceContent> pContent;
CComPtr<IPortableDeviceKeyCollection> pPropertiesToRead;
CComPtr<IPortableDevicePropVariantCollection> pObjectIDs;
if (SUCCEEDED(hr))
{
hr = pDevice->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
}
}
if (SUCCEEDED(hr))
{
hr = pContent->Properties(&pProperties);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
}
}
if (SUCCEEDED(hr))
{
hr = pProperties->QueryInterface(IID_PPV_ARGS(&pPropertiesBulk));
if (FAILED(hr))
{
printf("This driver does not support BULK property operations.\n");
}
}
ドライバーが一括操作をサポートしている場合、次の手順は 、IPortableDeviceKeyCollection インターフェイス のインスタンスを作成し、アプリケーションが取得するプロパティに対応するキーを指定することです。 このプロセスの詳細については、「 単一オブジェクトのプロパティの取得 」トピックを参照してください。
適切なキーを指定した後、サンプル アプリケーションは IPortableDevicePropertiesBulkCallback インターフェイスのインスタンスを作成します。 アプリケーションでは、このインターフェイスのメソッドを使用して、非同期の一括取得操作の進行状況を追跡します。
if (SUCCEEDED(hr))
{
pCallback = new CGetBulkValuesCallback();
if (pCallback == NULL)
{
hr = E_OUTOFMEMORY;
printf("! Failed to allocate CGetBulkValuesCallback, hr = 0x%lx\n", hr);
}
}
サンプル アプリケーションが呼び出す次の関数は、CreateIPortableDevicePropVariantCollectionWithAllObjectIDs ヘルパー関数です。 この関数は、使用できるすべてのオブジェクト識別子の一覧を作成します。 (実際のアプリケーションでは、識別子の一覧が特定のオブジェクト セットに制限されます。たとえば、アプリケーションは、特定のフォルダー ビューに現在含まれているすべてのオブジェクトの識別子の一覧を作成できます)。
前述のように、ヘルパー関数は、特定のデバイス上のすべてのオブジェクトを再帰的に列挙します。 見つかった各オブジェクトの識別子を含む IPortableDevicePropVariantCollection インターフェイス で、このリストを返します。 ヘルパー関数は、ContentEnumeration.cpp モジュールで定義されています。
// 7) Call our helper function CreateIPortableDevicePropVariantCollectionWithAllObjectIDs
// to enumerate and create an IPortableDevicePropVariantCollection with the object
// identifiers needed to perform the bulk operation on.
if (SUCCEEDED(hr))
{
hr = CreateIPortableDevicePropVariantCollectionWithAllObjectIDs(pDevice,
pContent,
&pObjectIDs);
}
前の手順が完了すると、サンプル アプリケーションは非同期プロパティの取得を開始します。 これを行うには、次の操作を行います。
- 一括プロパティ取得の要求をキューに入れる IPortableDevicePropertiesBulk::QueueGetValuesByObjectList を呼び出します。 (要求はキューに入れられますが、開始されないことに注意してください)。
- IPortableDevicePropertiesBulk::Start を呼び出して、キューに登録された要求を開始します。
これらの手順は、サンプル アプリケーションからの次のコードの抜粋で示されています。
if (SUCCEEDED(hr))
{
hr = pPropertiesBulk->QueueGetValuesByObjectList(pObjectIDs,
pPropertiesToRead,
pCallback,
&guidContext);
if(SUCCEEDED(hr))
{
// Cleanup any previously created global event handles.
if (g_hBulkPropertyOperationEvent != NULL)
{
CloseHandle(g_hBulkPropertyOperationEvent);
g_hBulkPropertyOperationEvent = NULL;
}
// In order to create a simpler to follow example we create and wait infinitly
// for the bulk property operation to complete and ignore any errors.
// Production code should be written in a more robust manner.
// Create the global event handle to wait on for the bulk operation
// to complete.
g_hBulkPropertyOperationEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hBulkPropertyOperationEvent != NULL)
{
// Call Start() to actually being the Asynchronous bulk operation.
hr = pPropertiesBulk->Start(guidContext);
if(FAILED(hr))
{
printf("! Failed to start property operation, hr = 0x%lx\n", hr);
}
}
else
{
printf("! Failed to create the global event handle to wait on for the bulk operation. Aborting operation.\n");
}
}
else
{
printf("! QueueGetValuesByObjectList Failed, hr = 0x%lx\n", hr);
}
}
関連トピック