Without further ado, here's the final version of the desktop HTC G Sensor client. This very simple .NET 3.5 forms application reads the stream of data from the HTC G Sensor via RAPI and displays it on the screen. Obviously, you can adapt this to meet your particular needs.
The main project in on the HTCGConsumer folder. Before trying to use this sample application, please make sure that the HTCClient.dll file is on your output directory, otherwise you will get an exception. This is the desktop client DLL that connects to the device via RAPI and is consumed by the HTC.GSensor.dll assembly through the HTC.GSensor.RemoteClient class.
Finally, don't forget to remove the RAPI restrictions on your device if you are running a WM6.x device. Enjoy.
Showing posts with label Windows Mobile. Show all posts
Showing posts with label Windows Mobile. Show all posts
Tuesday, May 18, 2010
Saturday, May 8, 2010
The HTC G Sensor RAPI Client
Now that we have a device RAPI extension DLL to capture the HTC G Sensor data it's time to write the PC client DLL. I wrote this as a native code DLL because it made my life simpler when interfacing with RAPI. It exposes five C-style functions that can be readily P/Invoked from .NET:
So what do these functions look like? They are actually very simple:
HTCGCLIENT_API void* HTCGSensor_New()
{
HTCGSensorClient* pClient = new HTCGSensorClient();
return pClient;
}
Why the void* return type? These exported functions are meant to be used by the P/Invoke mechanism that should know nothing about the pointer type: it will be mapped to an IntPtr type and treated as an opaque data type. Likewise, there's no need to check the data type on input:
HTCGCLIENT_API int HTCGSensor_Open(void* pClient)
{
HTCGSensorClient* client = (HTCGSensorClient*)pClient;
if(client)
return client->Open();
return E_FAIL;
}
So these functions are there to act as conduits between the a C++ object of type HTCGSensorClient, where the bulk of the work is done, and the calling .NET assembly. It should come as no surprise that this class also implements the Open, Close and Read methods, besides the standard constructor and destructor. Things get a bit more interesting here because we must open a connection to the device server through RAPI (the sample code uses an updated version of the CRemoteAPI class that I published ages ago). In a nutshell, the Open function (see the sample code) initializes RAPI and remotely invokes the HTCGSensorStream function on the HTCGServer.dll file (by default it should be placed on the device's \Windows folder, but you might want to change this). Note that a reference to a client-side version of the IRAPIStream object is kept and that's how the Read function gets the G sensor data. This function is implemented in terms of a write and a read operation. The write tells the server to fetch the G sensor data and then waits on the read for the data to arrive (that's why this might prove slow for high-frequency sampling: for each sample there must be a round-trip to the server). The data is copied to an HTCGSensorData variable passed in by pointer reference. Closing the client implies writing a command to the server and closing the RAPI connection.
On my next post I will wrap this small project up by publishing the high-level .NET assemblies that consume the HTC G Sensor data.
Sample code: HTCGClient.zip
- HTCGSensor_New - Creates a new native client object
- HTCGSensor_Delete - Destroys the native client object
- HTCGSensor_Open - Opens the remote HTC G Sensor server
- HTCGSensor_Close - Closes the remote HTC G Sensor server
- HTCGSensor_Read - Reads the HTC G Sensor data
So what do these functions look like? They are actually very simple:
HTCGCLIENT_API void* HTCGSensor_New()
{
HTCGSensorClient* pClient = new HTCGSensorClient();
return pClient;
}
Why the void* return type? These exported functions are meant to be used by the P/Invoke mechanism that should know nothing about the pointer type: it will be mapped to an IntPtr type and treated as an opaque data type. Likewise, there's no need to check the data type on input:
HTCGCLIENT_API int HTCGSensor_Open(void* pClient)
{
HTCGSensorClient* client = (HTCGSensorClient*)pClient;
if(client)
return client->Open();
return E_FAIL;
}
So these functions are there to act as conduits between the a C++ object of type HTCGSensorClient, where the bulk of the work is done, and the calling .NET assembly. It should come as no surprise that this class also implements the Open, Close and Read methods, besides the standard constructor and destructor. Things get a bit more interesting here because we must open a connection to the device server through RAPI (the sample code uses an updated version of the CRemoteAPI class that I published ages ago). In a nutshell, the Open function (see the sample code) initializes RAPI and remotely invokes the HTCGSensorStream function on the HTCGServer.dll file (by default it should be placed on the device's \Windows folder, but you might want to change this). Note that a reference to a client-side version of the IRAPIStream object is kept and that's how the Read function gets the G sensor data. This function is implemented in terms of a write and a read operation. The write tells the server to fetch the G sensor data and then waits on the read for the data to arrive (that's why this might prove slow for high-frequency sampling: for each sample there must be a round-trip to the server). The data is copied to an HTCGSensorData variable passed in by pointer reference. Closing the client implies writing a command to the server and closing the RAPI connection.
On my next post I will wrap this small project up by publishing the high-level .NET assemblies that consume the HTC G Sensor data.
Sample code: HTCGClient.zip
Thursday, April 29, 2010
The HTG G Sensor
Here is a very simple application that illustrates how to use the HTC G Sensor. This is included in a number of devices (including my own HTC Touch Pro) and it provides a way to determine the spatial position of the phone by providing "tilt" values for the X, Y and Z coordinate axis.
Although HTC did not provide a public API for the G Sensor (shame on them for this), Scott Seligman reverse engineered it which eventually led to a Codeplex project on this subject. The code you see here was ported from the C# version of the Codeplex project back to C++.
The application is quite simple: it merely connects to the G Sensor data source, samples it every 200 ms and displays the tilt values on the screen. As usual, I used WTL to write this simple app and its main features are:
Sample code: HtcSensor.zip
The sample application requires an HTC device with a G Sensor like the Diamond. You can use this information in a number of different ways on the device. On a forthcoming post, I will show how you can consume this information on a desktop .NET 3.5 application.
Although HTC did not provide a public API for the G Sensor (shame on them for this), Scott Seligman reverse engineered it which eventually led to a Codeplex project on this subject. The code you see here was ported from the C# version of the Codeplex project back to C++.
The application is quite simple: it merely connects to the G Sensor data source, samples it every 200 ms and displays the tilt values on the screen. As usual, I used WTL to write this simple app and its main features are:
- The HTCGSensor class that implements an interface to the HTC G Sensor API;
- The view window (CHtcSensorView) that samples the G Sensor data every 200 milliseconds and displays the tilt values;
- The frame window (CHtcSensorFrame) where the sampling timer is started (see the OnCreate handler)
Sample code: HtcSensor.zip
The sample application requires an HTC device with a G Sensor like the Diamond. You can use this information in a number of different ways on the device. On a forthcoming post, I will show how you can consume this information on a desktop .NET 3.5 application.
Subscribe to:
Posts (Atom)