#include <windows.h>
#include <commctrl.h>
#include <aygshell.h>
#pragma comment(lib, "aygshell.lib")
#include "Resource.h"
// ---- HTC Touch Diamond sensor --------------------------------------------
// ------- by Scott Seligman <scott@scottandmichelle.net> -------------------
// ------- GESTURE_TOUCH related information from KriX <kriix@hotmail.com> --
// -- Polling the sensor using the SDK dll ------------------------
#define SENSOR_DLL L"HTCSensorSDK.dll"
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;
#define SENSOR_TILT 1
typedef HANDLE (WINAPI * PFN_HTCSensorOpen)(DWORD);
typedef void (WINAPI * PFN_HTCSensorClose)(HANDLE);
typedef DWORD (WINAPI * PFN_HTCSensorGetDataOutput)(HANDLE, PSENSORDATA);
PFN_HTCSensorOpen pfnHTCSensorOpen;
PFN_HTCSensorClose pfnHTCSensorClose;
PFN_HTCSensorGetDataOutput pfnHTCSensorGetDataOutput;
// -- Notifications via the sensor's event ------------------------
#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
#define SENSOR_START _T("HTC_GSENSOR_SERVICESTART")
#define SENSOR_STOP _T("HTC_GSENSOR_SERVICESTOP")
#define ORIENTATION_LANDSCAPE 0
#define ORIENTATION_REVERSE_LANDSCAPE 1
#define ORIENTATION_PORTRAIT 2
#define ORIENTATION_UPSIDE_DOWN 3
#define ORIENTATION_FACE_DOWN 4
#define ORIENTATION_FACE_UP 5
// TODO: Modify these two constants to your needs
#define SN_GSENSOR 1
#define WM_STATECHANGE (WM_USER + 1)
// -- Notifications for gestures around the d-pad -----------------
#define HTCAPI_DLL L"HTCAPI.dll"
typedef DWORD (WINAPI * PFN_HTCNavOpen)(HWND, DWORD);
typedef DWORD (WINAPI * PFN_HTCNavSetMode)(HWND, DWORD);
typedef DWORD (WINAPI * PFN_HTCNavClose)(DWORD);
PFN_HTCNavOpen pfnHTCNavOpen;
PFN_HTCNavSetMode pfnHTCNavSetMode;
PFN_HTCNavClose pfnHTCNavClose;
#define GESTURE_API 1
#define GESTURE_GESTURE 4 // Generates WM_HTC_GESTURE messages
#define GESTURE_TOUCH 5 // Generates WM_HTC_TOUCH messages
// (with the HTCTOUCH structs)
#define WM_HTC_GESTURE (WM_USER + 200)
#define WM_HTC_TOUCH (WM_USER + 209)
#define ROTATION_MASK 0x00000F00 // WPARAM
#define ROTATION_CLOCKWISE 0x00000800
#define ROTATION_COUNTER 0x00000900
#define COMPLETION_MASK 0x00F00000 // LPARAM
#define DIRECTION_MASK 0x0000F000 // LPARAM
typedef struct tagHTCTOUCH_WPARAM
{
BYTE Up; //0=KeyDown,1=KeyUp
BYTE Where; //Where the click occurs (left pane, wheel, right pane)
//Pos for the Right Pane click
BYTE xPosRP;
BYTE yPosRP;
} HTCTOUCH_WPARAM;
typedef struct tagHTCTOUCH_LPARAM
{
//Pos for the Left Pane click
BYTE xPosLP;
BYTE yPosLP;
//Wheel click angle
BYTE WheelAngle;
BYTE Unknown4;
} HTCTOUCH_LPARAM;
// ---- End of HTC Touch Diamond sensor -------------------------------------
// --------------------------------------------------------------------------
bool SensorPollingInit();
bool SensorPollingUninit();
bool SensorEventInit();
bool SensorEventUninit();
bool SensorGestureInit(HWND hWnd);
bool SensorGestureUninit();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int);
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass);
bool InitInstance(HINSTANCE hInstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
HINSTANCE g_hInstance;
HWND g_hWndMenuBar;
POINT g_ptCursor;
int g_nCursorAngle;
int g_nLastEvent;
HANDLE g_hSensor;
HANDLE g_hSensorEvent;
HDC g_hdcBuffer;
TCHAR g_szLastSensorMsg[100] = _T("");
#pragma region Registry Notification APIs
FARPROC g_lpRegistryCloseNotification = NULL;
FARPROC g_lpRegistryNotifyWindow = NULL;
HINSTANCE g_hDLLAygShell = NULL;
void LoadProc(HINSTANCE hDLL, LPTSTR szProc, FARPROC * lppProc)
{
*lppProc = GetProcAddress(hDLL, szProc);
}
HRESULT RegistryCloseNotification(HANDLE hNotify)
{
if (!g_hDLLAygShell)
{
g_hDLLAygShell = LoadLibrary(_T("aygshell.dll"));
}
if (g_hDLLAygShell)
{
if (!g_lpRegistryCloseNotification)
{
LoadProc(g_hDLLAygShell, _T("RegistryCloseNotification"),
&g_lpRegistryCloseNotification);
}
typedef HRESULT (WINAPI * PFN_RegistryCloseNotification)(HANDLE);
if (g_lpRegistryCloseNotification)
{
return ((PFN_RegistryCloseNotification)
g_lpRegistryCloseNotification)(hNotify);
}
}
return NULL;
}
HRESULT RegistryNotifyWindow(HKEY hKey, LPCTSTR pszSubKey,
LPCTSTR pszValueName, HWND hWnd,
UINT msg, DWORD dwUserData,
LPVOID pCondition, HANDLE * phNotify)
{
if (!g_hDLLAygShell)
{
g_hDLLAygShell = LoadLibrary(_T("aygshell.dll"));
}
if (g_hDLLAygShell)
{
if (!g_lpRegistryNotifyWindow)
{
LoadProc(g_hDLLAygShell, _T("RegistryNotifyWindow"),
&g_lpRegistryNotifyWindow);
}
typedef HRESULT (WINAPI * PFN_RegistryNotifyWindow)(HKEY, LPCTSTR,
LPCTSTR, HWND, UINT, DWORD, LPVOID, HANDLE *);
if (g_lpRegistryNotifyWindow)
{
return ((PFN_RegistryNotifyWindow)
g_lpRegistryNotifyWindow)(hKey, pszSubKey, pszValueName,
hWnd, msg, dwUserData, pCondition, phNotify);
}
}
return NULL;
}
#pragma endregion
#define TIMERID_READSENSOR 1
#define TIMERID_KEEPALIVE 2
#define PI180 (3.1415926f/180.0f)
bool SensorPollingInit()
{
HMODULE hSensorLib = LoadLibrary(SENSOR_DLL);
if (hSensorLib == NULL)
{
MessageBox(NULL,
_T("Unable to load Sensor DLL"),
_T("Error"), MB_TOPMOST);
return false;
}
pfnHTCSensorOpen = (PFN_HTCSensorOpen)
GetProcAddress(hSensorLib, L"HTCSensorOpen");
pfnHTCSensorClose = (PFN_HTCSensorClose)
GetProcAddress(hSensorLib, L"HTCSensorClose");
pfnHTCSensorGetDataOutput = (PFN_HTCSensorGetDataOutput)
GetProcAddress(hSensorLib, L"HTCSensorGetDataOutput");
if (pfnHTCSensorOpen == NULL ||
pfnHTCSensorClose == NULL ||
pfnHTCSensorGetDataOutput == NULL)
{
MessageBox(NULL,
_T("Unable to find entry point"),
_T("Error"), MB_TOPMOST);
return false;
}
g_hSensor = pfnHTCSensorOpen(SENSOR_TILT);
return true;
}
bool SensorPollingUninit()
{
pfnHTCSensorClose(g_hSensor);
return true;
}
bool SensorEventInit(HWND hWnd)
{
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, SENSOR_START);
if (hEvent == NULL || GetLastError() != ERROR_ALREADY_EXISTS)
{
MessageBox(hWnd,
_T("Unable to create Sensor Event"),
_T("Error"), MB_TOPMOST);
return false;
}
SetEvent(hEvent);
CloseHandle(hEvent);
g_hSensorEvent = NULL;
RegistryNotifyWindow(