Delen via


Sensor-API-gebeurtenissen gebruiken

Belangrijk

Gebruik in plaats daarvan de UWP Sensor-API .

De SENSOR-API op basis van COM is afgeschaft en mag niet worden gebruikt in nieuwe toepassingen. Er zijn geen extra functies of verbeteringen gepland en ondersteuning wordt beperkt.

De Sensor-API biedt gebeurtenismeldingen via callback-interfaces.

Als u gebeurtenismeldingen wilt ontvangen, moet uw programma de vereiste COM-callback-interfaces implementeren. Als u gebeurtenissen van sensoren wilt ontvangen, moet u ISensorEventsimplementeren. Als u gebeurtenissen van de sensormanager wilt ontvangen, moet u ISensorManagerEventsimplementeren.

Met de volgende voorbeeldcode wordt een klasse gemaakt waarmee ISensorEventsworden geïmplementeerd.

class CMyEvents : public ISensorEvents
{
public:

    STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
    {
        if (ppv == NULL)
        {
            return E_POINTER;
        }
        if (iid == __uuidof(IUnknown))
        {
            *ppv = static_cast<IUnknown*>(this);
        }
        else if (iid == __uuidof(ISensorEvents))
        {
            *ppv = static_cast<ISensorEvents*>(this);
        }
        else
        {
            *ppv = NULL;
            return E_NOINTERFACE;
        }
        AddRef();
        return S_OK;
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef); 
    }

    STDMETHODIMP_(ULONG) Release()
    {
        ULONG count = InterlockedDecrement(&m_cRef);
        if (count == 0)
        {
            delete this;
            return 0;
        }
        return count;
    }

    //
    // ISensorEvents methods.
    //

    STDMETHODIMP OnEvent(
            ISensor *pSensor,
            REFGUID eventID,
            IPortableDeviceValues *pEventData)
    {
        HRESULT hr = S_OK;

        // Handle custom events here.

        return hr;
    }

    STDMETHODIMP OnDataUpdated(
            ISensor *pSensor,
            ISensorDataReport *pNewData)
    {
        HRESULT hr = S_OK;

        if(NULL == pNewData ||
           NULL == pSensor)
        {
            return E_INVALIDARG;
        }

        ULONG ulHour = 0;
        ULONG ulMinute = 0;
        ULONG ulSecond = 0;

        PROPVARIANT var = {};

        hr = pNewData->GetSensorValue(SAMPLE_SENSOR_DATA_TYPE_HOUR, &var);

        if(SUCCEEDED(hr))
        {
            if(var.vt == VT_UI4)
            {
                // Get the hour value.
                ulHour = var.ulVal;                
            }
        }

        PropVariantClear(&var);

        if(SUCCEEDED(hr))
        {
            hr = pNewData->GetSensorValue(SAMPLE_SENSOR_DATA_TYPE_MINUTE, &var);
        }

        if(SUCCEEDED(hr))
        {
            if(var.vt == VT_UI4)
            {
                // Get the hour value.
                ulMinute = var.ulVal;
            }
        }

        PropVariantClear(&var);

        if(SUCCEEDED(hr))
        {
            hr = pNewData->GetSensorValue(SAMPLE_SENSOR_DATA_TYPE_SECOND, &var);
        }

        if(SUCCEEDED(hr))
        {
            if(var.vt == VT_UI4)
            {
                // Get the hour value.
                ulSecond = var.ulVal;
            }
        }

        PropVariantClear(&var);

        if(SUCCEEDED(hr))
        {
            // Print
            wprintf_s(L"Current local time is: \n");
            wprintf_s(L"%02d:%02d:%02d (asynchronous)\n", ulHour, ulMinute, ulSecond);
        }

        return hr;
    }

    STDMETHODIMP OnLeave(
            REFSENSOR_ID sensorID)
    {
        HRESULT hr = S_OK;

        // Perform any housekeeping tasks for the sensor that is leaving.
        // For example, if you have maintained a reference to the sensor,
        // release it now and set the pointer to NULL.

        return hr;
    }

    STDMETHODIMP OnStateChanged(
            ISensor* pSensor,
            SensorState state)
    {
        HRESULT hr = S_OK;

        if(NULL == pSensor)
        {
            return E_INVALIDARG;
        }


        if(state == SENSOR_STATE_READY)
        {
            wprintf_s(L"\nTime sensor is now ready.");
        }
        else if(state == SENSOR_STATE_ACCESS_DENIED)
        {
            wprintf_s(L"\nNo permission for the time sensor.\n");
            wprintf_s(L"Enable the sensor in the control panel.\n");
        }
  

        return hr;
    }

    private:
        long m_cRef;

};

Nadat u de callback-interface hebt geïmplementeerd, kunt u een bepaalde sensor voorzien van een aanwijzer naar een exemplaar van uw callback-klasse om gebeurtenismeldingen van de sensor te ontvangen.

Met de volgende voorbeeldcode wordt een exemplaar van de callback-klasse gemaakt en vervolgens gebeurtenismeldingen van een sensor aangevraagd.

CMyEvents* pEventClass = NULL;
ISensorEvents* pMyEvents = NULL;

if(SUCCEEDED(hr))
{
    // Create an instance of the event class.
    pEventClass = new(std::nothrow) CMyEvents();        
}

if(SUCCEEDED(hr))
{
    // Retrieve the pointer to the callback interface.
    hr = pEventClass->QueryInterface(IID_PPV_ARGS(&pMyEvents));
}

if(SUCCEEDED(hr))
{
    // Start receiving events.
    hr = pSensor->SetEventSink(pMyEvents);
} 

U kunt vergelijkbare code schrijven om gebeurtenissen te ontvangen van de sensormanager.

In de volgende voorbeeldcode ziet u hoe u geen gebeurtenismeldingen meer ontvangt.

if(SUCCEEDED(hr))
{
    hr = pSensor->SetEventSink(NULL);
}

Een rapportinterval aanvragen

U kunt een waarde voorstellen voor hoe vaak uw toepassing gegevensupdates ontvangt. Sensoren zijn echter niet vereist om gebeurtenissen op een bepaald interval te leveren. Houd er rekening mee dat de voorgestelde waarde mogelijk niet overeenkomt met het werkelijke rapportinterval dat de sensor gebruikt om gebeurtenissen te genereren. Als u het werkelijke rapportinterval wilt weten, haalt u de waarde voor de eigenschap SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL op, zoals beschreven in Eigenschappen van sensor ophalen en instellen.

Met de volgende voorbeeldcode wordt een helperfunctie gemaakt die een nieuwe waarde aanvraagt voor de eigenschap SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL. De functie verwijst naar de sensor waarvoor de eigenschap moet worden ingesteld en een ULONG--waarde die aangeeft dat het nieuwe rapportinterval moet worden ingesteld.

HRESULT SetCurrentReportInterval(ISensor* pSensor, ULONG ulNewInterval)
{
    assert(pSensor);

    HRESULT hr = S_OK;

    IPortableDeviceValues* pPropsToSet = NULL; // Input
    IPortableDeviceValues* pPropsReturn = NULL; // Output

    // Create the input object.
    hr = CoCreateInstance(__uuidof(PortableDeviceValues),
                            NULL,
                            CLSCTX_INPROC_SERVER,                           
                            IID_PPV_ARGS(&pPropsToSet));

    if(SUCCEEDED(hr))
    {
        // Add the current report interval property.
        hr = pPropsToSet->SetUnsignedIntegerValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, ulNewInterval);
    }

    if(SUCCEEDED(hr))
    {
        // Only setting a single property, here.
        hr = pSensor->SetProperties(pPropsToSet, &pPropsReturn);
    }

    // Test for failure.
    if(hr == S_FALSE)
    {
        HRESULT hrError = S_OK;
      
        // Check results for failure.
        hr = pPropsReturn->GetErrorValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, &hrError);

        if(SUCCEEDED(hr))
        {
            // Print an error message.
            wprintf_s(L"\nSetting current report interval failed with error 0x%X\n", hrError);

            // Return the error code.
            hr = hrError;
        }
    }
    else if(hr == E_ACCESSDENIED)
    {
        // No permission. Take appropriate action.
    }

    SafeRelease(&pPropsToSet);
    SafeRelease(&pPropsReturn);
   
    return hr;
}

Over sensor-API-gebeurtenissen