Enumerazione del contenuto del servizio
Dopo aver aperto un servizio, l'applicazione può iniziare a eseguire operazioni correlate al servizio. Nel caso dell'applicazione WpdServicesApiSample, una di queste operazioni è l'enumerazione del contenuto per un determinato servizio Contatti. Nella tabella seguente vengono descritte le interfacce usate.
Interfaccia | Descrizione |
---|---|
IPortableDeviceService | Usato per recuperare l'interfaccia IPortableDeviceContent2 per accedere al contenuto nel servizio. |
IPortableDeviceContent2 | Usato per recuperare l'interfaccia IEnumPortableDeviceObjectIDs per enumerare gli oggetti nel servizio. |
Id IEnumPortableDeviceObjectIDs | Usato per enumerare gli oggetti nel servizio. |
Il codice di enumerazione del contenuto è disponibile nel modulo ContentEnumeration.cpp. Questo codice si trova nei metodi EnumerateAllContent e RecursiveEnumerate . Il metodo precedente chiama quest'ultimo.
Il metodo EnumerateContent accetta un puntatore a un oggetto IPortableDeviceService come parametro. Questo oggetto corrisponde a un servizio aperto in precedenza quando ha chiamato il metodo IPortableDeviceService::Open .
Il metodo EnumerateContent crea un oggetto IPortableDeviceContent2 e passa questo oggetto al metodo IPortableDeviceService::Content . Questo metodo, a sua volta, recupera il contenuto a livello radice del servizio e quindi inizia in modo ricorsivo a recuperare il contenuto trovato sotto la radice.
Il codice seguente corrisponde al metodo EnumerateContent .
// Enumerate all content on the service starting with the
// "DEVICE" object
void EnumerateAllContent(
IPortableDeviceService* pService)
{
HRESULT hr = S_OK;
CComPtr<IPortableDeviceContent2> pContent;
if (pService == NULL)
{
printf("! A NULL IPortableDeviceService interface pointer was received\n");
return;
}
// Get an IPortableDeviceContent2 interface from the IPortableDeviceService interface to
// access the content-specific methods.
hr = pService->Content(&pContent);
if (FAILED(hr))
{
printf("! Failed to get IPortableDeviceContent2 from IPortableDeviceService, hr = 0x%lx\n",hr);
}
// Enumerate content starting from the "DEVICE" object.
if (SUCCEEDED(hr))
{
printf("\n");
RecursiveEnumerate(WPD_DEVICE_OBJECT_ID, pContent);
}
}
Il codice seguente corrisponde al metodo RecursiveEnumerate . Il metodo RecursiveEnumerate crea un'istanza di un'interfaccia IEnumPortableDeviceObjectIDs per l'oggetto padre fornito e chiama IEnumPortableDeviceObjectIDs::Next, recuperando un batch di oggetti figlio immediati. Per ogni oggetto figlio viene chiamato nuovamente RecursiveEnumerate per restituire i relativi oggetti figlio discendenti e così via.
// Recursively called function which enumerates using the specified
// object identifier as the parent.
void RecursiveEnumerate(
PCWSTR pszObjectID,
IPortableDeviceContent2* 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 IPortableDeviceContent2, 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;
}
}
}
}
Argomenti correlati