Here is some code for T2 users wanting to explore the Ultrabook code directly:
//
// C++ code (VS2012) to get at sensors from desktop app
// http://www.codeproject.com/Articles/479316/All-Axis-Camera-Windows-8-Desktop-App-for-Ultraboo
// http://www.codeproject.com/Articles/262151/Visual-Cplusplus-and-WinRT-Metro-Some-fundamentals
// http://blogs.msdn.com/b/vcblog/archive/2012/09/05/cxxcxpart01asimpleclass.aspx
//
#include <InitGuid.h>
#include <SensorsApi.h>
#include <Sensors.h>
// Then you need to create a COM interface to the SensorManager object.
ISensorManager* pSensorManager = NULL;
HRESULT hr = ::CoCreateInstance(CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pSensorManager));
if (FAILED(hr)) //take required action
// Get a list of all motion sensors on the computer, but if required you can find specific sensor type e.g. SENSOR_TYPE_GYROMETER_3D. Don't forget to check the result, because the system may not have any sensors or there might be driver problem.
ISensorCollection* pSensorCollection = NULL;
hr = pSensorManager->GetSensorsByCategory(SENSOR_CATEGORY_ALL, &pSensorCollection);
// Now find out the required sensor. To get accelerometer you can provide SENSOR_DATA_TYPE_ACCELERATION_Z_G as argument, for Gyroscope use SENSOR_DATA_TYPE_TILT_Z_DEGREES and so on. Following example is for Ambient Light sensor.
ULONG ulCount = 0;
hr = pSensorCollection->GetCount(&ulCount);
//if (FAILED(hr)) ...
for (int i = 0; i < (int)ulCount; i++)
{
ISensor* pSensor;
hr = pSensorCollection->GetAt(i, &pSensor);
if (SUCCEEDED(hr))
{
VARIANT_BOOL bSupported = VARIANT_FALSE;
hr = pSensor->SupportsDataField(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, &bSupported);
if (SUCCEEDED(hr) && (bSupported == VARIANT_TRUE))
{
//this is the required sensor for Ambient light
}
}
}
// You can also check for access permissions, and request permission if necessary.
SensorState state = SENSOR_STATE_ERROR;
RESULT hr = pSensor->GetState(&state);
if (state == SENSOR_STATE_ACCESS_DENIED)
{
//You can create a new collection..so that you ask permission for only required one.
hr = m_pSensorManager->RequestPermissions(NULL, pSensorCollection, TRUE);
}
// Now you need to hook the Sensor for any DataUpdated, Leave, or StateChanged events.
SensorEventSink* pSensorEventClass = new SensorEventSink(); // create class instance
ISensorEvents* pSensorEvents = NULL;
// get the ISensorEvents COM interface pointer
hr = pSensorEventClass->QueryInterface(IID_PPV_ARGS(&pSensorEvents));
hr = pSensor->SetEventSink(pSensorEvents); // hook COM interface
// The SensorEventSink class is your own class that inherits from ISensorEvents and also implements IUnknown.
class SensorEventSink : 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;
}
STDMETHODIMP OnEvent(
ISensor *pSensor,
REFGUID eventID,
IPortableDeviceValues *pEventData)
{
HRESULT hr = S_OK;
// Handle events here.
return hr;
}
STDMETHODIMP OnDataUpdated( ISensor *pSensor, ISensorDataReport *pNewData)
{
HRESULT hr = S_OK;
if(NULL == pNewData || NULL == pSensor)
return E_INVALIDARG;
PROPVARIANT var = {};
//ask value of your required data type
hr = pNewData->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &var);
PropVariantClear(&var);
return hr;
}
STDMETHODIMP OnLeave( REFSENSOR_ID sensorID)
{
HRESULT hr = S_OK;
// handle leave event,
return hr;
}
STDMETHODIMP OnStateChanged( ISensor* pSensor, SensorState state)
{
HRESULT hr = S_OK;
if(NULL == pSensor)
return E_INVALIDARG;
if(state == SENSOR_STATE_READY)
{
//handle ready state
}
else if(state == SENSOR_STATE_ACCESS_DENIED)
{
//you can ask to Enable the sensor in the control panel
}
return hr;
}
};
// Multi-Touch & Gestures
// Using multi-touch in a desktop app is fairly simple, as all mouse related work is done though Windows Messages, touch related work is done through touch message WM_TOUCH. This message provides raw multi-touch data, as many simultaneous touch points as your hardware supports.
// Whenever the user touches a touch-sensitive device, your app gets gesture message WM_GESTURE by default. The information about gestures (Zoom, Rotate, Pan, Press and Tap) is found in the lParam parameter, use a special function GetGestureInfo to decode the gesture message.
// To receive raw touch messages you need to ask the OS to start sending touch messages (and stop sending the default gesture messages) by calling the RegisterTouchWindow function.
I am not the author of this, I found it very useful and it came from either an Intel or Code Project article. Hope you find it of use too.
Hogging the awesome since 1999