Click here to Skip to main content
15,880,427 members
Articles / Mobile Apps / Windows Mobile

Mobile TouchPad

Rate me:
Please Sign up or sign in to vote.
4.58/5 (22 votes)
21 Nov 2008CPOL7 min read 89.7K   1.5K   87   28
Mobile TouchPad lets you control your PC through your touch pad phones. You can easily connect to your desktop without configuration.

Contents

What is Mobile TouchPad?

Mobile TouchPad lets you control your PC through your touch pad phones. You can easily connect to your desktop without configuration, you only need the driver to be active (also source code included) and the standard ActiveSync enabled.

You can use it in a presentation, or to control your media center.

Introduction

I try to explain how it is simple to write code for mobile. The project consists of two solutions, two programs are needed, because one intercepts the mouse movements on mobile and the second interacts with the desktop.

I've solved some problems about:

  • ActiveSync
  • OpenNETCF Mobile Ink
  • Mouse Hook
  • Marshal
  • P/Invoke
  • Socket
  • Byte Serialization/Deserialization
  • Registry

Image 1

Info: To make the following code example easier to read, security checking and error handling are not included.

Developer Requirement

First of all, to deploy any WM application, you need the Windows Mobile 6 Professional and Standard Software Development Kits Refresh[^].

Here, you can find all the requirements for your system and you can choose the platform Pro or standard or both. You need at least one of the two. I suggest to you the 'Professional Windows Mobile 6 Professional SDK Refresh.msi', the new SDK for Pocket PC.

Please check each application's system requirements individually.

Anyway, I add brief System Requirements:

  • Microsoft Visual Studio 2005
  • Microsoft Visual Studio 2005 SP1 [^]
  • Microsoft .NET Compact Framework v2 SP2 [^]
  • For Windows XP - ActiveSync 4.5 [^]
  • For Windows Vista - Windows Mobile Device Center [^]

Image 2

Info: To deploy this project, I use Visual Studio 2005 SE EU, Vista Business, Windows Mobile Device Center, and a Samsung i900.

Additional Requirement

For the mobile ink, I prefer to use a free Mobile Ink Library. OpenNETCF Mobile Ink is a component that provides support for WM 6 Ink here [^] and is released under the MIT X11 license [^].

I use this library, first because it's free, and Open source, and also because it's very simple to use, and I show you how do that.

Using the Mobile Side Code

The mobile solution is named MobileTouchPad and you can find it under the WM folder. The mobile app will be similar to the image below.

Image 3

OpenNETCF Mobile Ink

As seen above, I use that because it can be cool to give some effect to the touch. At the moment, I write the touched line and I clear it after releasing the screen. It's very simple to use this component, The steps to use an ink in your project are:

Add Using and Reference

C#
using OpenNETCF.WindowsMobile.Ink;
using OpenNETCF.WindowsMobile.Ink.Interfaces;

You can find it after installing the file downloaded OpenNETCF Mobile Ink (you can also find the source code in the installation dir).

Add a Panel

Add a panel or a picturebox to your form, it will be your touchPad, I've call it panelTouchPad.

Add the Overlay

Add an overlay to your panel:

C#
IInkOverlay overlay;

Add the EventHandler for the Load

In the load form, attach the panel to the overlay:

C#
overlay.hWnd = pictureBox1.Handle;
overlay.Enabled = true;

Add the Event Stroke

This enables the ink:

C#
overlay = Ink.CreateInstance();
overlay.SetEventInterest(InkCollectorEventInterest.Stroke, true);

Adapt the Screen

In the Resize form, retrieve the screen coordinate and adapt the panelTouchPad to the screen:

C#
Rectangle oScreen = Screen.PrimaryScreen.WorkingArea;
panelTouchPad.Location = new System.Drawing.Point(0, 0);
panelTouchPad.Size = new System.Drawing.Size
	(oScreen.Size.Width, oScreen.Size.Height - oScreen.Y);

Clear the Screen

C#
overlay.Enabled = false;
overlay.Ink = InkDisp.CreateInstance();
overlay.Enabled = true;

Well, the first step has ended, now we have a very simple Mobile paint.

Mouse Move

To intercept the mouse movements simply, I use the EventHandler of MouseMove of the panelTouchPad. Here, I decided how to send data to the desktop. I save the last point every time and I send to the desktop only a step movement. The data can be (+1,0) (-1,1) (0,-1), etc.

C#
Point pointDirection = new Point();
pointDirection.X = e.X - LastPoint.X  ;
pointDirection.Y = e.Y - LastPoint.Y  ;

SendData(pointDirection);

LastPoint.X = e.X;
LastPoint.Y = e.Y; 

Button Pressed and Double Click

To intercept the button pressed, you need to add the KeyEventHandler for KeyDown and KeyPress and send it with no movements.

C#
private void FormTouchPad_KeyDown(object sender, KeyEventArgs e)
{
    m_buttonState = CommonStruct.MouseButtonState.ButtonPressed;     
    SendData(new Point(0,0));
}

private void FormTouchPad_KeyUp(object sender, KeyEventArgs e)
{
    m_buttonState = CommonStruct.MouseButtonState.None;
    SendData(new Point(0, 0));
}

To intercept the double click, add an event DoubleClick to the panelTouchPad and send it with no movements.

C#
m_buttonState = CommonStruct.MouseButtonState.DblClick;
SendData(new Point(0,0));

As you can see here, I've used a common structure CommonStruct for both the solutions.

This is the enum for the button state:

C#
public enum MouseButtonState
{
    None = 0,
    ButtonClick,
    ButtonPressed,
    DblClick
}

This is the struct for the button action:

C#
public struct TouchPro
{
    public Point point;
    public MouseButtonState buttonState;
}

This common struct is in Common.cs.

Desktop IP

Image 4 Info: To communicate with the desktop, you need to sync the Device or the emulator. To do that, you need the ActiveSync 4.5 installed as System Requirements for Windows XP, and the Windows Mobile Device Center for Windows Vista.

After syncing it, you only need set up your connection as DMA, with this option, you are able to retrieve the desktop IP dynamically.

Image 5

To retrieve the desktop IP, I've used some registry key enabled by the ActiveSync. This key are stored in [HKEY_LOCAL_MACHINE\Comm\Tcpip\Hosts\ppp_peer] or if not exist [HKEY_LOCAL_MACHINE\Comm\Tcpip\Hosts\dtpt_peer]. If you have problems, I'll suggest to you this blog [^].

Using the Emulator

You can use the emulator to test the project, but obviously the mouse interaction can be a bit difficult.

Image 6 Attention: If you use the emulator, you must activate the cradle.

Image 7

In Visual Studio 2005, open Tools menu and choose Device Emulator Manager. In Device emulator manager, select your current emulator and select cradle.

Image 8

After ActiveSync starts, you can may notice a small tray icon like networking icon, with a plus sign turning left and right.

Image 9

Serialize/Deserialize

Using socket, I need to convert my class to byte[]. Normally on desktop, I use BinaryFormatter and MemoryStream , but on WM, that reference is missing... Anyway, I found another way using Marshaling. This is the CommonConvertion I use in my two projects (you can find it in Common.cs).

C#
class CommonConvertion
{
    public static byte[] StructureToByteArray(object obj)
    {
        int Length = Marshal.SizeOf(obj);
        byte[] bytearray = new byte[Length];
        IntPtr ptr = Marshal.AllocHGlobal(Length);
        Marshal.StructureToPtr(obj, ptr, false);
        Marshal.Copy(ptr, bytearray, 0, Length);
        Marshal.FreeHGlobal(ptr);
        return bytearray;
    }
    public static void ByteArrayToStructure(byte[] bytearray, ref object obj)
    {
        int Length = Marshal.SizeOf(obj);
        IntPtr ptr = Marshal.AllocHGlobal(Length);
        Marshal.Copy(bytearray, 0, ptr, Length);
        obj = Marshal.PtrToStructure(ptr, obj.GetType());
        Marshal.FreeHGlobal(ptr);
    }
}

Connect and Send Data to Desktop

To send data to desktop, I prefer to use TCP/IP instead of Web service, Rapi and so on, because it's more simple (I think).

TCP Usage

Define a TcpClient and a NetworkStream used all the same during the app life:

C#
private TcpClient m_client;
private NetworkStream m_stream;

In the constructor, add the Connection to the server and open the stream to it:

C#
m_client = new TcpClient(server, port);
m_stream = m_client.GetStream();

If it fails (the desktop server is closed), the app tries to connect to the server every time you touch the screen and gives a message box to you... you can continue without the connection or you can go on drawing on it....

Finally, we send data as you saw before in the MouseMove. Here in the code, you can see a new method SendData. This is a method where I manage the data and send it to the desktop.

C#
private void SendData(Point pointDirection)
{
    ...
    CommonStruct.TouchPro AddMove = new CommonStruct.TouchPro();
    AddMove.point = pointDirection;
    AddMove.buttonState = m_buttonState;
    object objTmp = (object)AddMove;
    Byte[] data = CommonConvertion.StructureToByteArray(AddMove);
	
    m_networkstream.Write(data, 0, data.Length);
    ...
}

Using the Desktop Side Code

The solution is named DriverMobileTouchPad and you can find it under x86 folder. This is a screenshot to show you its interface. Here, you must activate the server to wait for the mobile connection.

Mobile devices have several limitations, one above all is the small screen resolution. To avoid this problem, I've added the possibility to change the cursor velocity.

Image 10

Connect and Receive Data from Mobile

TCP Usage

Into the form, I've created a server waiting connection on a port:

C#
m_tcpserver = new TcpListener(IPAddress.Any, 5000);
m_tcpserver.Start();
m_tcpserver.BeginAcceptTcpClient
   ( new AsyncCallback(DoAcceptTcpClientCallback), m_tcpserver);

Image 11Warning: Remember to open the port 5000 on your firewall.

When it's connected to a client, it begins to read stream.Read inside the DoAcceptTcpClientCallback from the opened stream and converts it to my common struct. After reading data, deserialize it with the CommonConvertion, as shown here Serialize/deserialize.

C#
CommonStruct.TouchPro AddMove = new CommonStruct.TouchPro();
object objTmp = new object();
objTmp = (object)AddMove;
CommonConvertion.ByteArrayToStructure(bytes, iBufflen, ref objTmp);
AddMove = (CommonStruct.TouchPro)objTmp;

Mouse Interaction

For the interaction, I've created a class MouseMov. Here I use the P/Invoke to send click (pressed and release) and double click.

C#
[DllImport("user32.dll")]
private static extern void mouse_event
   (UInt32 dwFlags, UInt32 dx, UInt32 dy, UInt32 dwData, IntPtr dwExtraInfo);
private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
internal static void SendUp()
{
   mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, new System.IntPtr());
}
internal static void MoveMouse(Point p)
{
   Cursor.Position = new Point(Cursor.Position.X + p.X, Cursor.Position.Y + p.Y);
}

The MoveMouse is a simple cursor movement.

C#
internal static void SendDown()
{
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, new System.IntPtr());
}

Well, finally we have finished. Try to run the two solutions I've added and you can see the code in action. Let me know your problems and what you think about it. Have fun!

Links

I've found these links very useful:

History

  • 10th November, 2008 - First release - v 10 2008

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Welcome Italia spa
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalgreat Work ! ! Pin
g2gayan14-Jun-10 3:57
g2gayan14-Jun-10 3:57 
GeneralRe: great Work ! ! Pin
Dr.Luiji14-Jun-10 11:49
professionalDr.Luiji14-Jun-10 11:49 
QuestionProblem in deploying!!!! Pin
gg056-Nov-09 11:15
gg056-Nov-09 11:15 
AnswerRe: Problem in deploying!!!! Pin
Dr.Luiji7-Nov-09 3:26
professionalDr.Luiji7-Nov-09 3:26 
QuestionRe: Problem in deploying!!!! Pin
gg058-Nov-09 1:33
gg058-Nov-09 1:33 
AnswerRe: Problem in deploying!!!! Pin
Dr.Luiji8-Nov-09 6:14
professionalDr.Luiji8-Nov-09 6:14 
QuestionRe: Problem in deploying!!!! [modified] Pin
gg059-Nov-09 4:34
gg059-Nov-09 4:34 
AnswerRe: Problem in deploying!!!! Pin
Dr.Luiji9-Nov-09 5:04
professionalDr.Luiji9-Nov-09 5:04 
General@ Good Job Pin
PavanPareta16-Aug-09 23:55
PavanPareta16-Aug-09 23:55 
GeneralRe: @ Good Job Pin
Dr.Luiji17-Aug-09 6:30
professionalDr.Luiji17-Aug-09 6:30 
Questionplz help me about run listener app!? Pin
barbod_blue2-May-09 18:43
barbod_blue2-May-09 18:43 
AnswerRe: plz help me about run listener app!? Pin
Dr.Luiji4-May-09 1:31
professionalDr.Luiji4-May-09 1:31 
Question2 way communication???? Pin
anusho21-Apr-09 6:44
anusho21-Apr-09 6:44 
AnswerRe: 2 way communication???? Pin
Dr.Luiji22-Apr-09 11:53
professionalDr.Luiji22-Apr-09 11:53 
GeneralRe: 2 way communication???? Pin
anusho22-Apr-09 20:56
anusho22-Apr-09 20:56 
GeneralDOESNT WORK Pin
dizzy599-Apr-09 17:53
dizzy599-Apr-09 17:53 
GeneralRe: DOESNT WORK Pin
Dr.Luiji10-Apr-09 10:13
professionalDr.Luiji10-Apr-09 10:13 
GeneralVery cool Pin
Sacha Barber6-Dec-08 21:49
Sacha Barber6-Dec-08 21:49 
GeneralRe: Very cool Pin
Dr.Luiji7-Dec-08 4:16
professionalDr.Luiji7-Dec-08 4:16 
GeneralRe: Very cool Pin
Sacha Barber7-Dec-08 7:32
Sacha Barber7-Dec-08 7:32 
u r welcome

Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralMy vote of 1 Pin
khansameer5-Dec-08 22:55
khansameer5-Dec-08 22:55 
GeneralRe: My vote of 1 [modified] Pin
Dr.Luiji7-Dec-08 4:32
professionalDr.Luiji7-Dec-08 4:32 
GeneralRe: My vote of 1 Pin
Wes Aday28-Dec-09 6:45
professionalWes Aday28-Dec-09 6:45 
GeneralRe: My vote of 1 Pin
Dr.Luiji1-Jan-10 21:47
professionalDr.Luiji1-Jan-10 21:47 
GeneralAwesome Pin
Raj Lal25-Nov-08 20:44
professionalRaj Lal25-Nov-08 20:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.