Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Important
Utilisez plutôt l’API de capteur UWP .
L’API de capteur COM est déconseillée et ne doit pas être utilisée dans les nouvelles applications. Aucune fonctionnalité ou amélioration supplémentaire n’est planifiée et la prise en charge sera limitée.
L’API Sensor fournit des notifications d’événements via des interfaces de rappel.
Pour recevoir des notifications d’événements, votre programme doit implémenter les interfaces de rappel COM requises. Pour recevoir des événements de capteurs, vous devez implémenter ISensorEvents. Pour recevoir des événements du gestionnaire de capteurs, vous devez implémenter ISensorManagerEvents.
L’exemple de code suivant crée une classe qui implémente ISensorEvents.
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;
};
Après avoir implémenté l’interface de rappel, vous pouvez fournir un capteur particulier avec un pointeur vers une instance de votre classe de rappel pour commencer à recevoir des notifications d’événements à partir du capteur.
L’exemple de code suivant crée une instance de la classe de rappel, puis demande des notifications d’événements à partir d’un capteur.
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);
}
Vous pouvez écrire du code similaire pour recevoir des événements du gestionnaire de capteurs.
L’exemple de code suivant montre comment arrêter de recevoir des notifications d’événements.
if(SUCCEEDED(hr))
{
hr = pSensor->SetEventSink(NULL);
}
Demande d’un intervalle de rapport
Vous pouvez suggérer une valeur pour la fréquence à laquelle votre application reçoit des événements mis à jour des données. Toutefois, les capteurs ne sont pas tenus de fournir des événements à un intervalle particulier. Vous devez savoir que votre valeur suggérée peut ne pas correspondre à l’intervalle de rapport réel que le capteur utilise pour déclencher des événements. Pour connaître l’intervalle de rapport réel, récupérez la valeur de la propriété SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, comme décrit dans Récupération et définition des propriétés du capteur.
L’exemple de code suivant crée une fonction d’assistance qui demande une nouvelle valeur pour la propriété SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL. La fonction prend un pointeur vers le capteur pour lequel définir la propriété et une valeur ULONG qui indique le nouvel intervalle de rapport à définir.
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;
}