Condividi tramite


Recupero delle funzionalità di rendering supportate da un dispositivo

Windows Dispositivi portatili che supportano la categoria funzionale delle informazioni di rendering (WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION) restituirà le informazioni di rendering quando viene eseguita una query. Le informazioni di rendering descrivono i requisiti e le restrizioni imposte alle applicazioni che tentano di scrivere contenuto in un dispositivo.

La funzione ListRenderingCapabilityInformation, la funzione helper SupportFunctionalCategory e la funzione helper ReadProfileInformationProperties nel modulo DeviceCapabilities.cpp illustrano il recupero delle funzionalità di rendering per un dispositivo selezionato.

L'applicazione può recuperare le funzionalità di rendering supportate da un dispositivo usando le interfacce descritte nella tabella seguente.

Interfaccia Descrizione
Interfaccia IPortableDeviceContent Fornisce l'accesso all'interfaccia IPortableDeviceProperties.
Interfaccia IPortableDeviceProperties Fornisce l'accesso ai metodi specifici della proprietà.
Interfaccia IPortableDeviceKeyCollection Usato per archiviare le chiavi delle proprietà per il profilo specificato.
Interfaccia IPortableDeviceValues Usato archivia i valori delle proprietà per il profilo specificato.
Interfaccia IPortableDeviceCapabilities Usato archivia i valori delle proprietà per il profilo specificato.
Interfaccia IPortableDevicePropVariantCollection Usato archivia i valori delle proprietà per il profilo specificato.
Interfaccia IPortableDeviceValuesCollection Usato archivia i valori delle proprietà per il profilo specificato.

 

Una delle prime attività eseguite dall'applicazione di esempio consiste nel determinare se il dispositivo selezionato è in grado di elencare le funzionalità di rendering. La funzione helper SupportFunctionalCategory determina se si tratta del caso chiamando la funzione helper ListRenderingCapabilityInformation e passando WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION come secondo argomento.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceCapabilities>          pCapabilities;
CComPtr<IPortableDevicePropVariantCollection> pRenderingInfoObjects;
CComPtr<IPortableDeviceValuesCollection>      pRenderingInfoProfiles;
CAtlStringW                                   strRenderingInfoObjectID;
if (SupportsFunctionalCategory(pDevice, WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION) == FALSE)
{
    printf("This device does not support device rendering information to display\n");
    return;
}

Se il dispositivo è in grado di elencare le funzionalità di rendering, il passaggio successivo comporta il recupero di un oggetto IPortableDeviceCapabilities e richiama il metodo GetFunctionalObjects per recuperare un identificatore di oggetto per l'oggetto informazioni sul rendering.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceCapabilities>          pCapabilities;
CComPtr<IPortableDevicePropVariantCollection> pRenderingInfoObjects;
CComPtr<IPortableDeviceValuesCollection>      pRenderingInfoProfiles;
CAtlStringW                                   strRenderingInfoObjectID;
hr = pDevice->Capabilities(&pCapabilities);
if (FAILED(hr))
{
    printf("! Failed to get IPortableDeviceCapabilities from IPortableDevice, hr = 0x%lx\n",hr);
}

// Get the functional object identifier for the rendering information object
if (SUCCEEDED(hr))
{
    hr = pCapabilities->GetFunctionalObjects(WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION, &pRenderingInfoObjects);
    if (FAILED(hr))
    {
        printf("! Failed to get functional objects, hr = 0x%lx\n", hr);
    }
}

Il passaggio successivo consiste nell'archiviare l'identificatore dell'oggetto di rendering appena recuperato in una variabile stringa (strRenderingInfoObjectID) e quindi chiamare la funzione helper ReadProfileInformationProperties. La variabile strRenderingInfoObjectID viene passata come secondo argomento alla funzione helper.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceCapabilities>          pCapabilities;
CComPtr<IPortableDevicePropVariantCollection> pRenderingInfoObjects;
CComPtr<IPortableDeviceValuesCollection>      pRenderingInfoProfiles;
CAtlStringW                                   strRenderingInfoObjectID;
if (SUCCEEDED(hr))
{
    PROPVARIANT pv = {0};
    PropVariantInit(&pv);
    hr = pRenderingInfoObjects->GetAt(0, &pv);
    if ((SUCCEEDED(hr))    &&
        (pv.vt== VT_LPWSTR) )
    {
        strRenderingInfoObjectID = pv.pwszVal;
    }
    else
    {
        printf("! Failed to get first rendering object's identifier, hr = 0x%lx\n", hr);
    }

    PropVariantClear(&pv);
}

if (SUCCEEDED(hr))
{
    hr = ReadProfileInformationProperties(pDevice,
                                          strRenderingInfoObjectID,
                                          &pRenderingInfoProfiles);
    // Error output statements are performed by the helper function, so they
    // are omitted here.
}

Una delle prime attività eseguite dalla funzione helper consiste nel recuperare un oggetto IPortableDeviceContent che userà per accedere ai metodi specifici del contenuto.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceValuesCollection> pRenderingInfoProfiles;
CComPtr<IPortableDeviceContent>          pContent;
CComPtr<IPortableDeviceProperties>       pProperties;
CComPtr<IPortableDeviceKeyCollection>    pPropertiesToRead;
CComPtr<IPortableDeviceValues>           pObjectProperties;
if (SUCCEEDED(hr))
{
    hr = pDevice->Content(&pContent);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceContent from IPortableDevice, hr = 0x%lx\n",hr);
    }
}

Successivamente, la funzione helper recupera un oggetto IPortableDeviceProperties , che userà per accedere ai metodi specifici della proprietà.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceValuesCollection> pRenderingInfoProfiles;
CComPtr<IPortableDeviceContent>          pContent;
CComPtr<IPortableDeviceProperties>       pProperties;
CComPtr<IPortableDeviceKeyCollection>    pPropertiesToRead;
CComPtr<IPortableDeviceValues>           pObjectProperties;
if (SUCCEEDED(hr))
{
    hr = pContent->Properties(&pProperties);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceProperties from IPortableDevice, hr = 0x%lx\n",hr);
    }
}

Il passaggio successivo consiste nel creare un oggetto IPortableDeviceKeyCollection in cui vengono archiviate le chiavi delle proprietà per le informazioni di rendering. Dopo aver creato l'oggetto, viene richiamato il metodo IPortableDeviceKeyCollection::Add per aggiungere le chiavi necessarie. È necessario aggiungere queste chiavi in modo che i profili di rendering corrispondenti possano essere recuperati nei passaggi successivi.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceValuesCollection> pRenderingInfoProfiles;
CComPtr<IPortableDeviceContent>          pContent;
CComPtr<IPortableDeviceProperties>       pProperties;
CComPtr<IPortableDeviceKeyCollection>    pPropertiesToRead;
CComPtr<IPortableDeviceValues>           pObjectProperties;
hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_IPortableDeviceKeyCollection,
                      (VOID**) &pPropertiesToRead);
if (SUCCEEDED(hr))
{
    // Populate the IPortableDeviceKeyCollection with the keys we wish to read.
    // NOTE: We are not handling any special error cases here so we can proceed with
    // adding as many of the target properties as we can.
    if (pPropertiesToRead != NULL)
    {
        HRESULT hrTemp = S_OK;
        hrTemp = pPropertiesToRead->Add(WPD_RENDERING_INFORMATION_PROFILES);
        if (FAILED(hrTemp))
        {
            printf("! Failed to add WPD_RENDERING_INFORMATION_PROFILES to IPortableDeviceKeyCollection, hr= 0x%lx\n", hrTemp);
        }
    }
}

Il passaggio successivo consiste nel recuperare i valori delle proprietà dal driver del dispositivo chiamando il metodo IPortableDeviceProperties::GetValues .

HRESULT hr = S_OK;
CComPtr<IPortableDeviceValuesCollection> pRenderingInfoProfiles;
CComPtr<IPortableDeviceContent>          pContent;
CComPtr<IPortableDeviceProperties>       pProperties;
CComPtr<IPortableDeviceKeyCollection>    pPropertiesToRead;
CComPtr<IPortableDeviceValues>           pObjectProperties;
if (SUCCEEDED(hr))
{
    hr = pProperties->GetValues(wszFunctionalObjectID, // The object whose properties we are reading
                                pPropertiesToRead,     // The properties we want to read
                                &pObjectProperties);   // Driver supplied property values for the specified object
    if (FAILED(hr))
    {
        printf("! Failed to get all properties for object '%ws', hr= 0x%lx\n", wszFunctionalObjectID, hr);
    }
}

Il passaggio successivo recupera il profilo di informazioni sul rendering e lo archivia nell'argomento ppRenderingInfoProfiles.

HRESULT hr = S_OK;
CComPtr<IPortableDeviceValuesCollection> pRenderingInfoProfiles;
CComPtr<IPortableDeviceContent>          pContent;
CComPtr<IPortableDeviceProperties>       pProperties;
CComPtr<IPortableDeviceKeyCollection>    pPropertiesToRead;
CComPtr<IPortableDeviceValues>           pObjectProperties;
if (SUCCEEDED(hr))
{
    hr = pObjectProperties->GetIPortableDeviceValuesCollectionValue(WPD_RENDERING_INFORMATION_PROFILES,
                                                                    &pRenderingInfoProfiles);
    if (FAILED(hr))
    {
        printf("! Failed to get WPD_RENDERING_INFORMATION_PROFILES from rendering information, hr= 0x%lx\n",  hr);
    }
}

// QueryInterface the interface into the out-going parameters.
if (SUCCEEDED(hr))
{
    hr = pRenderingInfoProfiles->QueryInterface(IID_PPV_ARGS(ppRenderingInfoProfiles));
    if (FAILED(hr))
    {
        printf("! Failed to QueryInterface for IPortableDeviceValuesCollection (Rendering information profiles), hr= 0x%lx\n",  hr);
    }
}

Dopo che la funzione helper legge le proprietà WPD_RENDERING_INFORMATION_PROFILES, vengono visualizzati i profili di rendering. Questi profili vengono visualizzati dalla funzione helper DisplayRenderingProfile.

void DisplayRenderingProfile(
    IPortableDeviceValues* pProfile)
{
    HRESULT hr = S_OK;
    if (pProfile == NULL)
    {
        return;
    }

    if (SUCCEEDED(hr))
    {
        DWORD dwTotalBitrate    = 0;
        DWORD dwChannelCount    = 0;
        DWORD dwAudioFormatCode = 0;
        GUID  guidFormat        = WPD_OBJECT_FORMAT_UNSPECIFIED;

        // Display WPD_MEDIA_TOTAL_BITRATE
        hr = pProfile->GetUnsignedIntegerValue(WPD_MEDIA_TOTAL_BITRATE, &dwTotalBitrate);
        if (SUCCEEDED(hr))
        {
            printf("Total Bitrate: %d\n", dwTotalBitrate);
        }

        // If we fail to read the total bitrate as a single value, then it must be
        // a valid value set.  (i.e. returning IPortableDeviceValues as the value which
        // contains properties describing the valid values for this property.)
        if (hr == DISP_E_TYPEMISMATCH)
        {
            CComPtr<IPortableDeviceValues> pExpectedValues;
            hr = pProfile->GetIPortableDeviceValuesValue(WPD_MEDIA_TOTAL_BITRATE, &pExpectedValues);
            if (SUCCEEDED(hr))
            {
                printf("Total Bitrate: ");
                DisplayExpectedValues(pExpectedValues);
            }
        }

        // If we are still a failure here, report the error
        if (FAILED(hr))
        {

            printf("! Failed to get WPD_MEDIA_TOTAL_BITRATE from rendering profile, hr = 0x%lx\n",hr);
        }

        // Display WPD_AUDIO_CHANNEL_COUNT
        hr = pProfile->GetUnsignedIntegerValue(WPD_AUDIO_CHANNEL_COUNT, &dwChannelCount);
        if (SUCCEEDED(hr))
        {
            printf("Channel Count: %d\n", dwChannelCount);
        }
        else
        {
            printf("! Failed to get WPD_AUDIO_CHANNEL_COUNT from rendering profile, hr = 0x%lx\n",hr);
        }

        // Display WPD_AUDIO_FORMAT_CODE
        hr = pProfile->GetUnsignedIntegerValue(WPD_AUDIO_FORMAT_CODE,   &dwAudioFormatCode);
        if (SUCCEEDED(hr))
        {
            printf("Audio Format Code: %d\n", dwAudioFormatCode);
        }
        else
        {
            printf("! Failed to get WPD_AUDIO_FORMAT_CODE from rendering profile, hr = 0x%lx\n",hr);
        }

        // Display WPD_OBJECT_FORMAT
        hr = pProfile->GetGuidValue(WPD_OBJECT_FORMAT, &guidFormat);
        if (SUCCEEDED(hr))
        {
            printf("Object Format: %ws\n", (LPWSTR)CComBSTR(guidFormat));
        }
        else
        {
            printf("! Failed to get WPD_OBJECT_FORMAT from rendering profile, hr = 0x%lx\n",hr);
        }
    }
}

Si noti che poiché i profili di rendering sono statici, l'applicazione può scegliere di leggere i profili e archiviarli in locale (anziché accedere al dispositivo ogni volta che sono necessari i dati).

Interfaccia IPortableDevice

Interfaccia IPortableDeviceCapabilities

Interfaccia IPortableDeviceContent

Interfaccia IPortableDeviceKeyCollection

Interfaccia IPortableDevicePropVariantCollection

Interfaccia IPortableDeviceValuesCollection

Guida alla programmazione