Bagikan melalui


Mengambil Kemampuan Penyajian yang Didukung oleh Perangkat

Perangkat Portabel Windows yang mendukung kategori fungsi informasi penyajian (WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION) akan mengembalikan informasi penyajian saat dikueri. Informasi penyajian menjelaskan persyaratan dan pembatasan yang diberlakukan pada aplikasi yang mencoba menulis konten ke perangkat.

Fungsi ListRenderingCapabilityInformation, fungsi pembantu SupportsFunctionalCategory, dan fungsi pembantu ReadProfileInformationProperties dalam modul DeviceCapabilities.cpp menunjukkan pengambilan kemampuan penyajian untuk perangkat yang dipilih.

Aplikasi Anda dapat mengambil kemampuan penyajian yang didukung oleh perangkat menggunakan antarmuka yang dijelaskan dalam tabel berikut.

Antarmuka Deskripsi
Antarmuka IPortableDeviceContent Menyediakan akses ke antarmuka IPortableDeviceProperties.
Antarmuka IPortableDeviceProperties Menyediakan akses ke metode khusus properti.
Antarmuka IPortableDeviceKeyCollection Digunakan untuk menyimpan kunci properti untuk profil yang diberikan.
Antarmuka IPortableDeviceValues Digunakan untuk menyimpan nilai properti untuk profil yang diberikan.
Antarmuka IPortableDeviceCapabilities Digunakan untuk menyimpan nilai properti untuk profil yang diberikan.
Antarmuka IPortableDevicePropVariantCollection Digunakan untuk menyimpan nilai properti untuk profil yang diberikan.
Antarmuka IPortableDeviceValuesCollection Digunakan untuk menyimpan nilai properti untuk profil yang diberikan.

 

Salah satu tugas pertama yang diselesaikan oleh aplikasi sampel adalah menentukan apakah perangkat yang dipilih mampu mencantumkan kemampuan penyajian. Fungsi pembantu SupportsFunctionalCategory menentukan apakah ini masalahnya dengan memanggil fungsi pembantu ListRenderingCapabilityInformation dan meneruskan WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION sebagai argumen kedua.

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;
}

Jika perangkat mampu mencantumkan kemampuan penyajian, langkah berikutnya memerlukan pengambilan objek IPortableDeviceCapabilities dan memanggil metode GetFunctionalObjects untuk mengambil pengidentifikasi objek untuk objek informasi 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);
    }
}

Langkah selanjutnya adalah menyimpan pengidentifikasi objek informasi penyajian yang baru saja diambil dalam variabel string (strRenderingInfoObjectID), lalu memanggil fungsi pembantu ReadProfileInformationProperties. (Variabel, strRenderingInfoObjectID, diteruskan sebagai argumen kedua ke fungsi pembantu.)

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.
}

Salah satu tugas pertama yang dilakukan oleh fungsi pembantu adalah mengambil objek IPortableDeviceContent , yang akan digunakan untuk mengakses metode khusus konten.

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);
    }
}

Selanjutnya, fungsi pembantu mengambil objek IPortableDeviceProperties , yang akan digunakan untuk mengakses metode khusus properti.

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);
    }
}

Langkah selanjutnya adalah membuat objek IPortableDeviceKeyCollection tempat kunci properti untuk informasi penyajian disimpan. Setelah objek dibuat, metode IPortableDeviceKeyCollection::Add dipanggil untuk menambahkan kunci yang diperlukan. (Perlu untuk menambahkan kunci ini sehingga profil penyajian yang sesuai dapat diambil dalam langkah-langkah berikutnya.)

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);
        }
    }
}

Langkah selanjutnya adalah mengambil nilai properti dari driver perangkat dengan memanggil metode 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);
    }
}

Langkah berikutnya mengambil profil informasi penyajian dan menyimpannya di argumen 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);
    }
}

Setelah fungsi pembantu membaca properti WPD_RENDERING_INFORMATION_PROFILES, profil penyajian ditampilkan. Profil ini ditampilkan oleh fungsi pembantu 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);
        }
    }
}

Perhatikan bahwa karena profil penyajian statis, aplikasi Anda dapat memilih untuk membaca profil dan menyimpannya secara lokal (alih-alih mengakses perangkat setiap kali data diperlukan).

Antarmuka IPortableDevice

Antarmuka IPortableDeviceCapabilities

Antarmuka IPortableDeviceContent

Antarmuka IPortableDeviceKeyCollection

Antarmuka IPortableDevicePropVariantCollection

Antarmuka IPortableDeviceValuesCollection

Panduan Pemrograman