Получение возможностей отрисовки, поддерживаемых устройством
Переносимые устройства Windows, поддерживающие функциональную категорию сведений о отрисовке (WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION), будут возвращать данные отрисовки при запросе. Сведения о подготовке к просмотру описывают требования и ограничения, накладываемые на приложения, которые пытаются записать содержимое на устройство.
Функция ListRenderingCapabilityInformation, вспомогающая функция SupportsFunctionalCategory и вспомогающая функция ReadProfileInformationProperties в модуле DeviceCapabilities.cpp демонстрируют получение возможностей отрисовки для выбранного устройства.
Приложение может получить возможности отрисовки, поддерживаемые устройством, с помощью интерфейсов, описанных в следующей таблице.
Интерфейс | Описание |
---|---|
Интерфейс IPortableDeviceContent | Предоставляет доступ к интерфейсу IPortableDeviceProperties. |
Интерфейс IPortableDeviceProperties | Предоставляет доступ к методам, зависящим от свойств. |
Интерфейс IPortableDeviceKeyCollection | Используется для хранения ключей свойств для заданного профиля. |
Интерфейс IPortableDeviceValues | Используется для хранения значений свойств для заданного профиля. |
Интерфейс IPortableDeviceCapabilities | Используется для хранения значений свойств для заданного профиля. |
Интерфейс IPortableDevicePropVariantCollection | Используется для хранения значений свойств для заданного профиля. |
Интерфейс IPortableDeviceValuesCollection | Используется для хранения значений свойств для заданного профиля. |
Одной из первых задач, выполняемых примером приложения, является определение того, способно ли выбранное устройство перечислять возможности отрисовки. Вспомогательная функция SupportsFunctionalCategory определяет, так ли это, вызывая вспомогающую функцию ListRenderingCapabilityInformation и передавая WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION в качестве второго аргумента.
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;
}
Если устройство может отображать возможности отрисовки, следующий шаг предполагает получение объекта IPortableDeviceCapabilities и вызов метода GetFunctionalObjects для получения идентификатора объекта для объекта rendering-information.
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);
}
}
Следующим шагом является сохранение идентификатора объекта сведений о отрисовке, который был только что получен в строковой переменной (strRenderingInfoObjectID), а затем вызов вспомогательной функции ReadProfileInformationProperties. (Переменная strRenderingInfoObjectID передается в качестве второго аргумента вспомогательной функции.)
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.
}
Одной из первых задач, выполняемых вспомогательной функцией, является получение объекта IPortableDeviceContent , который будет использоваться для доступа к методам, зависящим от содержимого.
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);
}
}
Затем вспомогающая функция извлекает объект IPortableDeviceProperties , который будет использоваться для доступа к методам, зависящим от свойств.
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);
}
}
Следующим шагом является создание объекта IPortableDeviceKeyCollection , в котором хранятся ключи свойств для сведений отрисовки. После создания объекта вызывается метод IPortableDeviceKeyCollection::Add для добавления необходимых ключей. (Необходимо добавить эти ключи, чтобы на последующих шагах можно было получить соответствующие профили отрисовки.)
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);
}
}
}
Следующим шагом является получение значений свойств из драйвера устройства путем вызова метода 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);
}
}
На следующем шаге извлекается профиль сведений отрисовки и сохраняется в аргументе 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);
}
}
После того как вспомогатель считывает свойства WPD_RENDERING_INFORMATION_PROFILES, отображаются профили отрисовки. Эти профили отображаются вспомогательной функцией 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);
}
}
}
Обратите внимание, что, так как профили отрисовки являются статическими, приложение может считывать профили и хранить их локально (вместо доступа к устройству каждый раз, когда требуются данные).
Связанные темы