感謝 scott,他反編譯了HTC的GSensor用接口, http://scottandmichelle.net/scott/comments.html?entry=784
感謝 Timothy,他的示例程序很清晰易懂 http://www.xiaozhou.net/vcdevelopment/htc-touch-pro-of-gravity-sensing-2009-07-07.htm
核心內容從http://scottandmichelle.net/scott/comments.html?entry=784處借用
頭文件HTCGSensor.h
#pragma once
#include <WinDef.h>
namespace HTC {
const DWORD ERROR_OK = 0;
const DWORD ERROR_ALREADY_INIT = 1;
const DWORD ERROR_LOAD_DLL = 2;
const DWORD ERROR_OPEN_REG = 3;
const DWORD ERROR_PARAM = 4;
const DWORD ERROR_OPEN_SENSOR = 5;
typedef struct _SENSORDATA
{
SHORT TiltX; // From -1000 to 1000 (about), 0 is flat
SHORT TiltY; // From -1000 to 1000 (about), 0 is flat
SHORT Orientation; // From -1000 to 1000 (about)
// 0 = Straight up, -1000 = Flat, 1000 = Upside down
WORD Unknown1; // Always zero
DWORD AngleY; // From 0 to 359
DWORD AngleX; // From 0 to 359
DWORD Unknown2; // Bit field?
} SENSORDATA, *PSENSORDATA;
enum {
ORIENTATION_LANDSCAPE = 0,
ORIENTATION_REVERSE_LANDSCAPE = 1,
ORIENTATION_PORTRAIT = 2,
ORIENTATION_UPSIDE_DOWN = 3,
ORIENTATION_FACE_DOWN = 4,
ORIENTATION_FACE_UP = 5,
};
class HTCGSensor
{
public:
HTCGSensor(void);
~HTCGSensor(void);
public:
DWORD Init();
DWORD Fina();
DWORD GetGSensorEvent(DWORD* dwEvent);
DWORD GetGSensorData(SENSORDATA* pSensorData);
protected:
typedef HANDLE (WINAPI * PFN_HTCSensorOpen)(DWORD);
typedef void (WINAPI * PFN_HTCSensorClose)(HANDLE);
typedef DWORD (WINAPI * PFN_HTCSensorGetDataOutput)(HANDLE, PSENSORDATA);
private:
HKEY m_hKey;
HANDLE m_hSensor;
HMODULE m_hSensorDll;
PFN_HTCSensorOpen m_pfnHTCSensorOpen;
PFN_HTCSensorClose m_pfnHTCSensorClose;
PFN_HTCSensorGetDataOutput m_pfnHTCSensorGetDataOutput;
};
}
實現文件HTCGSensor.cpp
#include <Windows.h>
#include "HTCGSensor.h"
#define SENSOR_DLL L"HTCSensorSDK.dll"
#define SENSOR_TILT 1
#define SN_GSENSOR_ROOT HKEY_LOCAL_MACHINE
#define SN_GSENSOR_PATH _T("Software//HTC//HTCSensor//GSensor")
#define SN_GSENSOR_VALUE _T("EventChanged")
#define SN_GSENSOR_BITMASK 0xF
namespace HTC {
HTCGSensor::HTCGSensor(void)
{
m_hKey = NULL;
m_hSensor = NULL;
m_hSensorDll = NULL;
}
HTCGSensor::~HTCGSensor(void)
{
}
DWORD HTCGSensor::Init()
{
DWORD dwRet = ERROR_OK;
if( m_hSensorDll ) {
return ERROR_ALREADY_INIT;
}
m_hSensorDll = LoadLibrary(SENSOR_DLL);
if( m_hSensorDll == NULL ) {
return ERROR_LOAD_DLL;
}
// Get Function Adrress
m_pfnHTCSensorOpen = (PFN_HTCSensorOpen) GetProcAddress(m_hSensorDll, L"HTCSensorOpen");
m_pfnHTCSensorClose = (PFN_HTCSensorClose) GetProcAddress(m_hSensorDll, L"HTCSensorClose");
m_pfnHTCSensorGetDataOutput = (PFN_HTCSensorGetDataOutput) GetProcAddress(m_hSensorDll, L"HTCSensorGetDataOutput");
if( m_pfnHTCSensorClose == NULL || m_pfnHTCSensorOpen == NULL || m_pfnHTCSensorGetDataOutput == NULL ) {
dwRet = ERROR_LOAD_DLL;
goto out;
}
m_hSensor = m_pfnHTCSensorOpen(SENSOR_TILT);
if( m_hSensor == NULL ) {
dwRet = ERROR_OPEN_SENSOR;
goto out;
}
// Open EventChange related Register Key
if( RegOpenKeyEx(SN_GSENSOR_ROOT, SN_GSENSOR_PATH, 0, KEY_READ, &m_hKey) != ERROR_SUCCESS ) {
dwRet = ERROR_OPEN_REG;
goto out;
}
return ERROR_OK;
out:
m_pfnHTCSensorOpen = NULL;
m_pfnHTCSensorClose = NULL;
m_pfnHTCSensorGetDataOutput = NULL;
if( m_hSensorDll ) {
FreeLibrary(m_hSensorDll);
m_hSensorDll = NULL;
}
if( m_hSensor ) {
m_pfnHTCSensorClose(m_hSensor);
m_hSensor = NULL;
}
return dwRet;
}
DWORD HTCGSensor::Fina()
{
m_pfnHTCSensorOpen = NULL;
m_pfnHTCSensorClose = NULL;
m_pfnHTCSensorGetDataOutput = NULL;
if( m_hSensorDll ) {
FreeLibrary(m_hSensorDll);
m_hSensorDll = NULL;
}
if( m_hSensor ) {
m_pfnHTCSensorClose(m_hSensor);
m_hSensor = NULL;
}
if( m_hKey ) {
RegCloseKey(m_hKey);
m_hKey = NULL;
}
return ERROR_OK;
}
DWORD HTCGSensor::GetGSensorData(SENSORDATA* pSensorData)
{
if( !pSensorData ) {
return ERROR_PARAM;
}
DWORD dwRet = m_pfnHTCSensorGetDataOutput(m_hSensor, pSensorData);
return ERROR_OK;
}
DWORD HTCGSensor::GetGSensorEvent(DWORD* dwEvent)
{
if( !dwEvent ) {
return ERROR_PARAM;
}
DWORD dwType = REG_DWORD;
DWORD dwSize= sizeof(DWORD);
if( RegQueryValueEx(m_hKey, SN_GSENSOR_VALUE, NULL, &dwType, (BYTE*)dwEvent, &dwSize) != ERROR_SUCCESS) {
return ERROR_OPEN_REG;
}
return ERROR_OK;
}
}