MYdea – Capture your ideas with MYdea

Some time ago I started feeling the need for a tool to quickly capture any ideas. In the past I’ve used pen and paper, but because I’ve always have my phone at my fingertips, why not use a piece of software?

Yes that's about how it started. Just the idea. I started to work on paper to get a slick UI-experience. It should be simple, finger friendly and also it should be easy to share. Share with others, but more important share with yourself.

Let’s start with a few screen shots.

MYdea Home screenMYdea Draw screenMYdea Write screen

MYdea supports capturing of ideas by writing, drawing and photography. As long as your device runs on Windows Mobile 5 or later and has touch input support. It runs very fine on my own HTC Touch Diamond. I’m already using the application for a few months, the first version I used was version 0.1 which I released to myself on June 14th 2009. The first version that made it to the web was version 1.0, I released it on August 16th. Today I released the first bug-fix release which also consumes much less memory and storage, version 1.1.

As explained you can capture an idea by writing, drawing and photography. In the next step you will be asked for a name and then you’re done. And MYdea helps you manage your ideas as well, you can view it, and if you want you can e-mail it through the standard e-mail application that’s available on your Windows Mobile phone.

If you are interested you can try MYdea for free, if you have more than two ideas you want to capture you will have to buy it. Please contact me if you have any questions regarding MYdea. Please let me know what you think about this application.

The commercial version of MYdea is available for $ 14,99 or € 12,99.

Windows Mobile and Handango Dynamic Registration

Did you every investigate how you could commercialize your Windows Mobile application? Of course there are a lot of different app stores on the internet, very soon Microsoft will open up it’s own Marketplace for Windows Mobile applications. But I think the largest app store for Windows Mobile applications is Handango.

This article is about how to enable a licensing system in your Windows Mobile application that’s compatible with Handango. Handango supports a few registration methods for licenses like: Static, Pool, Dynamic and HTTP Post.

- Static: One registration code unlocks all copies of the software.

- Pool: A pool of unique registration codes given one by one to the customers.

- Dynamic: Handango will create the registration codes based on a RPN string and the customers Device User ID.

- HTTP Post: Handango will communicate with one of your servers through XML to provide license keys.

In my opinion the first one isn’t really safe at all. It of course depends but, I don’t want just one license key. The pool is an option, but if you’ve got a best-selling application it will give you a lot of work.

The Dynamic option sounds interesting but what is a RPN string? More on that later.

The HTTP Post is a very interesting option, but it requires you to develop a service to generate license keys.

Let’s investigate the Dynamic Registration method for licenses for Handango

The Dynamic Registration method uses the customers Device User ID as input. But what is this Device User ID? It’s basically the Owner name of the Windows Mobile device. This is something that’s provided by the customers, so your application should be able to handle different owner names for the application and the device. Though pre filling the registration form in your application with the device owner is probably a good thing. You can get the Device Owner by using this code.

string ownerName = Microsoft.WindowsMobile.Status.SystemState.OwnerName

So that’s the simple part, but what about the RPN string? RPN stands for Reverse Polish Notation. RPN strings are expressions that can be easily parsed. It’s a postfix notation of a normal formula. The following expressions are exactly the same but the RPN one can be easily parsed.

Standard: 2 * 3
RPN: 2 3 *

Besides the ability for you to specify almost any arithmetic / logical / bitwise operators, there are a few parameters you have to put in somewhere in your RPN string. First of all it’s important to know that the owners name will be used in combination with the RPN string. Basically each character will be used with the RPN string. To be more exact, if the owner’s name exceeds 10 characters the first 5 and the last 5 characters of the owner will be used.

The parameters are:

- i: the indexer over the characters, starting with 0.

- key: the result of the RPN evaluation with the previous character, for the first character use 0.

- c: the ASCII value of the character.

An example RPN string can be like this: i 0 == 111 * key + c 2 * +

Handango has a very nice test-site, you can test your RPN string and an owner name to see what the RPN string evaluation will result in.

Let’s build a RPN Evaluator

Alright we now kind of know what RPN stands for, and how it’s used by Handango to generate license keys. I expect the Registration Form in your application to consist of two fields, an owner field and the license key field. I would check the validness of the license key by generating the license key myself by using the same RPN string. After the generation of the license key based on the owners name, it would be easy to compare those licenses.

Let’s first write the code to generate the correct RPN string for each character (first 5 and last 5).

public int SolveRpnFor(string baseRpn, string owner)
{
    if (owner.Length > 10)
        owner = owner.Substring(0, 5) + owner.Substring(owner.Length - 5);
    char[] ownerChars = owner.ToCharArray();
    double key = 0;
    for (int i = 0; i < ownerChars.Length; i++)
    {
        string rpnForChar =
            baseRpn.Replace("i", string.Format("{0}", i))
                .Replace("c", string.Format("{0}", (int) ownerChars[i]))
                .Replace("key", string.Format("{0}", key));
        key = SolveRpn(rpnForChar);
    }
    return (int) Math.Round(key);
}

This code first of all makes sure the owner isn’t longer than 10 characters, if it is the code will pickup the first and last 5 characters. Next we walk through each character, and replace the “i” with the index, the “c” with the ASCII value of the character, and the “key” with the RPN result from the previous character or with 0 if we are create a RPN string for the first character. These are just standard string replacements, but what about the real RPN Evaluation? That’s where we are now.

public double SolveRpn(string rpn)
{
    if (string.IsNullOrEmpty(rpn)) return 0;
    var tokens = new Stack<string>
        (rpn.Split(' ', '\t'));
    if (tokens.Count == 0) return 0;
    double evalResult = EvalRpn(tokens);
    if (tokens.Count != 0) throw new Exception();
    return evalResult;
}

First we convert the elements in the RPN string (divided by either a space or tab) to a stack containing the elements. If the amount of tokens is 0, we return 0. If the amount of tokens isn’t 0 we try to evaluate the stack of elements. If after the evaluation there are still elements in the stack, something definitely has gone wrong, so throw an exception. This exception might happen when the RPN string isn’t a valid RPN string.

We know like any formula a RPN string contains both values and operators. Let’s define the operators and write the function calls for them. We need a class to represent the operator and the function as well.

private class Operator
{
    public string Sign { get; set; }
    public Func<double, double, double> Function { get; set; }
}

private readonly List<Operator> operators =
    new List<Operator>
        {
            new Operator {Sign = "+", Function = (argX, argY) => argX + argY},
            new Operator {Sign = "-", Function = (argX, argY) => argX - argY},
            new Operator {Sign = "*", Function = (argX, argY) => argX*argY},
            new Operator {Sign = "/", Function = (argX, argY) => argX/argY},
            new Operator {Sign = "^", Function = Math.Pow},
            new Operator {Sign = "%", Function = (argX, argY) => argX%argY},
            new Operator {Sign = "<<", Function = (argX, argY) => (int) argX << (int) argY},
            new Operator {Sign = ">>", Function = (argX, argY) => (int) argX >> (int) argY},
            new Operator {Sign = "==", Function = (argX, argY) => (argX == argY) ? 1 : 0},
            new Operator {Sign = "<", Function = (argX, argY) => (argX < argY) ? 1 : 0},
            new Operator {Sign = "<=", Function = (argX, argY) => (argX <= argY) ? 1 : 0},
            new Operator {Sign = ">", Function = (argX, argY) => (argX > argY) ? 1 : 0},
            new Operator {Sign = ">=", Function = (argX, argY) => (argX >= argY) ? 1 : 0}
        };

Each Operator has a sign and an expression on how to calculate the result, basically each operation has two input values and one result. That makes it easy. As you can see there are a lot of operations in this list but the list isn’t complete. You can of course add other operators if you require them.

Alright we now have a stack setup and the operations, let’s walk through the stack and evaluate that RPN string.

private double EvalRpn(Stack<string> tokens)
{
    string token = tokens.Pop();

    Operator operatorFound = operators.Where(o => o.Sign == token).FirstOrDefault();

    double x;
    if (operatorFound != null)
    {
        double y = EvalRpn(tokens);
        x = EvalRpn(tokens);
        x = operatorFound.Function(x, y);
    }
    else
    {
        x = double.Parse(token);
    }
    return x;
}

I think the recursive mind in this code makes it very clean, but also difficult to understand. Let’s walk through the code.

- Pop the first token from the stack.

- Find out if this token is an operator and save the operator in a variable.

- If it isn’t an operator just parse it as a double and return it.

- If it is an operator evaluate the next things in the stack for y and x. (this is where the recursion comes in)

- Execute the operator on both x and y and return the result of it.

This code can evaluate RPN strings like: i 0 == 111 * key + c 2 * +

But make sure you always test your RPN strings and compare with the Handango test site result. It’s also very important you keep your RPN strings secret, because it enables people to generate license keys. I suggest to change the RPN string every time you have a new release. I am not guaranteeing this code is working correctly in all situations, and probably this code can be enhanced, but it’s a first start for you to create production ready code. To be complete you can use the full RpnService class.

public class RpnService
{
    private readonly List<Operator> operators =
        new List<Operator>
            {
                new Operator {Sign = "+", Function = (argX, argY) => argX + argY},
                new Operator {Sign = "-", Function = (argX, argY) => argX - argY},
                new Operator {Sign = "*", Function = (argX, argY) => argX*argY},
                new Operator {Sign = "/", Function = (argX, argY) => argX/argY},
                new Operator {Sign = "^", Function = Math.Pow},
                new Operator {Sign = "%", Function = (argX, argY) => argX%argY},
                new Operator {Sign = "<<", Function = (argX, argY) => (int) argX << (int) argY},
                new Operator {Sign = ">>", Function = (argX, argY) => (int) argX >> (int) argY},
                new Operator {Sign = "==", Function = (argX, argY) => (argX == argY) ? 1 : 0},
                new Operator {Sign = "<", Function = (argX, argY) => (argX < argY) ? 1 : 0},
                new Operator {Sign = "<=", Function = (argX, argY) => (argX <= argY) ? 1 : 0},
                new Operator {Sign = ">", Function = (argX, argY) => (argX > argY) ? 1 : 0},
                new Operator {Sign = ">=", Function = (argX, argY) => (argX >= argY) ? 1 : 0}
            };

    public int SolveRpnFor(string baseRpn, string owner)
    {
        if (owner.Length > 10)
            owner = owner.Substring(0, 5) + owner.Substring(owner.Length - 5);
        char[] ownerChars = owner.ToCharArray();
        double key = 0;
        for (int i = 0; i < ownerChars.Length; i++)
        {
            string rpnForChar =
                baseRpn.Replace("i", string.Format("{0}", i))
                    .Replace("c", string.Format("{0}", (int) ownerChars[i]))
                    .Replace("key", string.Format("{0}", key));
            key = SolveRpn(rpnForChar);
        }
        return (int) Math.Round(key);
    }

    public double SolveRpn(string rpn)
    {
        if (string.IsNullOrEmpty(rpn)) return 0;
        var tokens = new Stack<string>
            (rpn.Split(' ', '\t'));
        if (tokens.Count == 0) return 0;
        double evalResult = EvalRpn(tokens);
        if (tokens.Count != 0) throw new Exception();
        return evalResult;
    }

    private double EvalRpn(Stack<string> tokens)
    {
        string token = tokens.Pop();

        Operator operatorFound = operators.Where(o => o.Sign == token).FirstOrDefault();

        double x;
        if (operatorFound != null)
        {
            double y = EvalRpn(tokens);
            x = EvalRpn(tokens);
            x = operatorFound.Function(x, y);
        }
        else
        {
            x = double.Parse(token);
        }
        return x;
    }
		
    #region Nested type: Operator

    private class Operator
    {
        public string Sign { get; set; }
        public Func<double, double, double> Function { get; set; }
    }

    #endregion
}

Touch Form for Windows Mobile

When we take a look at Windows Mobile applications, we see more and more applications that need the ability to work with touch. Yes finger touch and not the touch by Stylus. The TouchFlo 3D software from HTC is a good example of such an application.

So I got an idea. A .NET Compact Framework TouchForm that recognizes some gestures.

TouchForm with Gesture Recognition

Yes I was thinking about very basic gesture recognition. I only want to recognize the following gestures:

  • Drag to North
  • Drag to East
  • Drag to South
  • Drag to West

But what is important though, is the fact that the gesture needs to be recognized. The gesture doesn’t have to be perfect is my opinion.

My idea was making use of Mathematics I learned a long time ago. Making use of the Unit Circle. By translating the start point of the dragging to (0,0) making the end point always having a position in the Unit Circle. The next step was the calculation of the angle inside the Unit Circle. We could basically use the following translation:

  • East (0 or 360 degrees)
  • North (90 degrees)
  • West (180 degrees)
  • South (270 degrees)

But of course I wanted to calculate everything instead of using a translation table. It took me some time to completely understand the mathematics again (I haven’t used this Mathematics for almost 10 years). Using the combination of both Sinus and Cosines to determine the real angle based on coordinates.

After the angle was calculated I want to ensure that the users gesture is also recognized when their dragging isn’t exact 90 degrees for example but might be 85 degrees or 95 degrees as well.

You can see a resulting example in this Silverlight Video. This example is just counting the gestures and showing the amount in labels. The center label is used for unrecognized gestures.

You can easily use this code. Just make sure you inherit your own form from TouchForm instead of the normal Form. Beside that you can attach a listener to the GestureRecognized event.

public partial class MyTouchForm : MM.Touch.TouchForm

{

    private int amountOfEast;

    private int amountOfNorth;

    private int amountOfNotRecognized;

    private int amountOfSouth;

    private int amountOfWest;

 

    public MyTouchForm()

    {

        InitializeComponent();

        GestureRecognized += MyTouchForm_GestureRecognized;

    }

 

    private void MyTouchForm_GestureRecognized(object sender, GestureRecognizedEventArgs e)

    {

        if (e.Gesture == MM.Touch.GestureType.NotRecognized)

            amountOfNotRecognized++;

        else if (e.Gesture == MM.Touch.GestureType.North)

            amountOfNorth++;

        else if (e.Gesture == MM.Touch.GestureType.East)

            amountOfEast++;

        else if (e.Gesture == MM.Touch.GestureType.South)

            amountOfSouth++;

        else if (e.Gesture == MM.Touch.GestureType.West)

            amountOfWest++;

 

        northLabel.Text = amountOfNorth.ToString();

        eastLabel.Text = amountOfEast.ToString();

        southLabel.Text = amountOfSouth.ToString();

        westLabel.Text = amountOfWest.ToString();

        notRecognizedLabel.Text = amountOfNotRecognized.ToString();

    }

}

You can download the source code here. Please let me know if you’re using this library in your project.

Setting up a Windows Mobile Development environment for HTC Touch Diamond development

Just this week I bought a new mobile phone. Of course it's a Windows Mobile powered mobile phone, a HTC Touch Diamond. I thought: "What about some .NET Compact Framework 3.5 development". So I started setting up a Windows Mobile Development VPC.

I started with the following:

  • Windows Server 2008
  • Visual Studio 2008 (with Smart Device extensions installed)

After this I wanted to be able to develop for Windows Mobile 6.x so I needed more, much more.

Installing Windows Mobile 6 wasn't really easy. I needed a pre-requisite, Windows Mobile Device Center. But sadly trying to install this I got a very informative message: "The update could not be installed because at least one Windows component required by Windows Mobile Device Center is missing". So which component? After some Googling I found out it was the "Desktop Experience" feature that needed to be installed on Windows Server 2008. So it took me some time, but in the end I got the SDK running.

Next step would be getting the networking available from the emulator. This looked easy, but I got a strange message: "Failed to open the VPC Network Driver. Verify that the driver is installed...". So some more Googling. The solution lies in using the Windows Mobile Device Center for sharing the connection. This article explains everything (in the old days we would have used ActiveSync as mentioned in the article).

In the end I got my blog loaded in Internet Explorer on the Emulator.

image