检索受支持的服务事件

WpdServicesApiSample 应用程序包括代码,该代码演示如何通过调用以下接口上的方法检索给定联系人服务支持的事件。

接口 说明
IPortableDeviceService 用于检索 IPortableDeviceServiceCapabilities 接口以访问受支持的事件。
IPortableDeviceServiceCapabilities 提供对受支持的事件和事件属性的访问权限。
IPortableDevicePropVariantCollection 包含受支持的事件列表。
IPortableDeviceValues 包含给定事件的属性。

 

当用户在命令行中选择选项“4”时,应用程序将调用 ServiceCapabilities.cpp 模块中找到的 ListSupportedEvents 方法。

请注意,在检索事件列表之前,示例应用程序会在连接的设备上打开联系人服务。

在 WPD 中,事件的名称、选项和参数描述。 事件名称是一个脚本友好的字符串,例如“MyCustomEvent”。 事件选项指示给定事件是否广播给所有客户端,以及该事件是否支持自动播放。 事件参数属性包括给定参数的 PROPERTYKEY 和 VARTYPE。

ServiceCapabilities.cpp 模块中的四种方法支持检索给定联系人服务支持的事件:ListSupportedEventsDisplayEvent、DisplayEventOptionsDisplayEventParameters ListSupportedEvents 方法检索每个事件的受支持的事件计数和 GUID 标识符。 DisplayEvent 方法显示事件名称或 GUID,然后调用 DisplayEventOptionsDisplayEventParameters 以显示与事件相关的数据。

ListSupportedEvents 方法调用 IPortableDeviceService::Capabilities 方法以检索 IPortableDeviceServiceCapabilities 接口。 使用此接口,它通过调用 IPortableDeviceServiceCapabilities::GetSupportedEvents 方法检索受支持的事件。 GetSupportedEvents 方法检索服务支持的每个事件的 GUID,并将这些 GUID 复制到 IPortableDevicePropVariantCollection 对象中。

以下代码演示了检索受支持的服务事件。

// List all supported events on the service
void ListSupportedEvents(
    IPortableDeviceService* pService)
{
    HRESULT hr          = S_OK;
    DWORD   dwNumEvents = 0;
    CComPtr<IPortableDeviceServiceCapabilities>     pCapabilities;
    CComPtr<IPortableDevicePropVariantCollection>   pEvents;

    if (pService == NULL)
    {
        printf("! A NULL IPortableDeviceService interface pointer was received\n");
        return;
    }

    // Get an IPortableDeviceServiceCapabilities interface from the IPortableDeviceService interface to
    // access the service capabilities-specific methods.
    hr = pService->Capabilities(&pCapabilities);
    if (FAILED(hr))
    {
        printf("! Failed to get IPortableDeviceServiceCapabilities from IPortableDeviceService, hr = 0x%lx\n",hr);
    }

    // Get all events supported by the service.
    if (SUCCEEDED(hr))
    {
        hr = pCapabilities->GetSupportedEvents(&pEvents);
        if (FAILED(hr))
        {
            printf("! Failed to get supported events from the service, hr = 0x%lx\n",hr);
        }
    }

    // Get the number of supported events found on the service.
    if (SUCCEEDED(hr))
    {
        hr = pEvents->GetCount(&dwNumEvents);
        if (FAILED(hr))
        {
            printf("! Failed to get number of supported events, hr = 0x%lx\n",hr);
        }
    }

    printf("\n%d Supported Events Found on the service\n\n", dwNumEvents);

    // Loop through each event and display it
    if (SUCCEEDED(hr))
    {
        for (DWORD dwIndex = 0; dwIndex < dwNumEvents; dwIndex++)
        {
            PROPVARIANT pv = {0};
            PropVariantInit(&pv);
            hr = pEvents->GetAt(dwIndex, &pv);

            if (SUCCEEDED(hr))
            {
                // We have an event.  It is assumed that
                // events are returned as VT_CLSID VarTypes.
                if (pv.puuid != NULL)
                {
                    DisplayEvent(pCapabilities, *pv.puuid);
                    printf("\n");
                }
            }

            PropVariantClear(&pv);
        }
    }
}

ListSupportedEvents 方法检索表示给定服务支持的每个事件的 GUID 后,它将调用 DisplayEvent 方法来检索特定于事件的数据。 此数据包括事件名称、其选项 (广播或自动播放) 、参数 GUID、参数类型等。

DisplayEvent 方法调用 IPortableDeviceServiceCapabilities::GetEventAttributes 方法以检索给定事件的属性集合。 然后,它会调用 IPortableDeviceValues::GetStringValue 方法,并请求驱动程序返回给定事件的用户友好名称。 接下来, DisplayEvent 调用 IPortableDeviceValues::GetIPortableDeviceValuesValue 来检索事件选项。 最后,DisplayEvent 调用 IPortableDeviceValues::GetIPortableDeviceKeyCollectionValue 以检索事件参数列表。 它将这些方法返回的数据传递给 DisplayEventOptionsDisplayEventParameters 帮助程序函数,这些函数呈现给定事件的选项和参数信息。

以下代码使用 DisplayEvent 方法。

// Display basic information about an event
void DisplayEvent(
    IPortableDeviceServiceCapabilities* pCapabilities,
    REFGUID                             Event)
{
    CComPtr<IPortableDeviceValues> pAttributes;

    // Get the event attributes which describe the event
    HRESULT hr = pCapabilities->GetEventAttributes(Event, &pAttributes);
    if (FAILED(hr))
    {
        printf("! Failed to get the event attributes, hr = 0x%lx\n",hr);
    }

    if (SUCCEEDED(hr))
    {
        PWSTR pszFormatName = NULL;
        CComPtr<IPortableDeviceValues>          pOptions;
        CComPtr<IPortableDeviceKeyCollection>   pParameters;

        // Display the name of the event if it is available. Otherwise, fall back to displaying the GUID.
        hr = pAttributes->GetStringValue(WPD_EVENT_ATTRIBUTE_NAME, &pszFormatName);
        if (SUCCEEDED(hr))
        {
            printf("%ws\n", pszFormatName);
        }
        else
        {
            printf("%ws\n", (PWSTR)CGuidToString(Event));
        }       

        // Display the event options
        hr = pAttributes->GetIPortableDeviceValuesValue(WPD_EVENT_ATTRIBUTE_OPTIONS, &pOptions);
        if (SUCCEEDED(hr))
        {
            DisplayEventOptions(pOptions);
        }
        else
        {
            printf("! Failed to get the event options, hr = 0x%lx\n", hr);
        }       

        // Display the event parameters
        hr = pAttributes->GetIPortableDeviceKeyCollectionValue(WPD_EVENT_ATTRIBUTE_PARAMETERS, &pParameters);
        if (SUCCEEDED(hr))
        {
            DisplayEventParameters(pCapabilities, Event, pParameters);
        }
        else
        {
            printf("! Failed to get the event parameters, hr = 0x%lx\n", hr);
        }       
        
        CoTaskMemFree(pszFormatName);
        pszFormatName = NULL;
    }
}

DisplayEventOptions 帮助程序函数接收包含事件的选项数据的 IPortableDeviceValues 对象。 然后,它调用 IPortableDeviceValues::GetBoolValue 方法以检索选项数据。 使用此数据,它呈现一个字符串,指示是否支持广播和自动播放选项。

// Display the basic event options.
void DisplayEventOptions(
    IPortableDeviceValues* pOptions)
{
    printf("\tEvent Options:\n");
    // Read the WPD_EVENT_OPTION_IS_BROADCAST_EVENT value to see if the event is
    // a broadcast event. If the read fails, assume FALSE
    BOOL  bIsBroadcastEvent = FALSE;
    pOptions->GetBoolValue(WPD_EVENT_OPTION_IS_BROADCAST_EVENT, &bIsBroadcastEvent);
    printf("\tWPD_EVENT_OPTION_IS_BROADCAST_EVENT = %ws\n",bIsBroadcastEvent ? L"TRUE" : L"FALSE");
}

IPortableDeviceKeyCollection

IPortableDeviceService

IPortableDeviceServiceCapabilities

IPortableDeviceValues

WpdServicesApiSample