Abrufen der von einem Gerät unterstützten Renderingfunktionen
Tragbare Windows-Geräte, die die Funktionskategorie "Renderinginformationen" (WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION) unterstützen, geben Renderinginformationen zurück, wenn sie abgefragt werden. Die Renderinginformationen beschreiben Anforderungen und Einschränkungen für Anwendungen, die versuchen, Inhalte auf ein Gerät zu schreiben.
Die Funktion ListRenderingCapabilityInformation, die SupportsFunctionalCategory-Hilfsfunktion und die Hilfsfunktion ReadProfileInformationProperties im Modul DeviceCapabilities.cpp veranschaulichen das Abrufen von Renderingfunktionen für ein ausgewähltes Gerät.
Ihre Anwendung kann die von einem Gerät unterstützten Renderingfunktionen mithilfe der in der folgenden Tabelle beschriebenen Schnittstellen abrufen.
Schnittstelle | BESCHREIBUNG |
---|---|
IPortableDeviceContent-Schnittstelle | Bietet Zugriff auf die IPortableDeviceProperties-Schnittstelle. |
IPortableDeviceProperties-Schnittstelle | Bietet Zugriff auf die eigenschaftenspezifischen Methoden. |
IPortableDeviceKeyCollection-Schnittstelle | Wird zum Speichern der Eigenschaftenschlüssel für das angegebene Profil verwendet. |
IPortableDeviceValues-Schnittstelle | Wird verwendet, werden die Eigenschaftswerte für das angegebene Profil gespeichert. |
IPortableDeviceCapabilities-Schnittstelle | Wird verwendet, werden die Eigenschaftswerte für das angegebene Profil gespeichert. |
IPortableDevicePropVariantCollection-Schnittstelle | Wird verwendet, werden die Eigenschaftswerte für das angegebene Profil gespeichert. |
IPortableDeviceValuesCollection-Schnittstelle | Wird verwendet, werden die Eigenschaftswerte für das angegebene Profil gespeichert. |
Eine der ersten Aufgaben der Beispielanwendung besteht darin, zu bestimmen, ob das ausgewählte Gerät Renderingfunktionen auflisten kann. Die SupportsFunctionalCategory-Hilfsfunktion bestimmt, ob dies der Fall ist, indem die Hilfsfunktion ListRenderingCapabilityInformation aufgerufen und WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION als zweites Argument übergeben wird.
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;
}
Wenn das Gerät Renderingfunktionen auflisten kann, umfasst der nächste Schritt das Abrufen eines IPortableDeviceCapabilities-Objekts und das Aufrufen der GetFunctionalObjects-Methode zum Abrufen eines Objektbezeichners für das Renderinginformationsobjekt.
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);
}
}
Der nächste Schritt besteht darin, den soeben abgerufenen Renderinginformationsobjektbezeichner in einer Zeichenfolgenvariablen (strRenderingInfoObjectID) zu speichern und anschließend die Hilfsfunktion ReadProfileInformationProperties aufzurufen. (Die Variable strRenderingInfoObjectID wird als zweites Argument an die Hilfsfunktion übergeben.)
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.
}
Eine der ersten Aufgaben der Hilfsfunktion ist das Abrufen eines IPortableDeviceContent-Objekts , das für den Zugriff auf die inhaltsspezifischen Methoden verwendet wird.
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);
}
}
Als Nächstes ruft die Hilfsfunktion ein IPortableDeviceProperties-Objekt ab, das für den Zugriff auf die eigenschaftenspezifischen Methoden verwendet wird.
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);
}
}
Der nächste Schritt besteht darin, ein IPortableDeviceKeyCollection-Objekt zu erstellen, in dem die Eigenschaftenschlüssel für die Renderinginformationen gespeichert werden. Nachdem das Objekt erstellt wurde, wird die IPortableDeviceKeyCollection::Add-Methode aufgerufen, um die erforderlichen Schlüssel hinzuzufügen. (Es ist erforderlich, diese Schlüssel hinzuzufügen, damit die entsprechenden Renderingprofile in den folgenden Schritten abgerufen werden können.)
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);
}
}
}
Der nächste Schritt besteht darin, die Eigenschaftswerte vom Gerätetreiber abzurufen, indem Sie die IPortableDeviceProperties::GetValues-Methode aufrufen.
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);
}
}
Im nächsten Schritt wird das Renderinginformationsprofil abgerufen und im Argument ppRenderingInfoProfiles gespeichert.
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);
}
}
Nachdem die Hilfsfunktion die WPD_RENDERING_INFORMATION_PROFILES Eigenschaften gelesen hat, werden die Renderingprofile angezeigt. Diese Profile werden von der Hilfsfunktion DisplayRenderingProfile angezeigt.
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);
}
}
}
Da die Renderingprofile statisch sind, kann Ihre Anwendung die Profile lesen und lokal speichern (anstatt jedes Mal, wenn die Daten benötigt werden, auf das Gerät zuzugreifen).
Zugehörige Themen