This demo was written for Convergence 2007 to showcase how Dynamics Ax can leverage managed code. In this example it uses a managed API to allow form navigation using tablet gestures, that is small figures drawn with the pen on the tablet screen.
The technology shown here will work in 4.0 as well as in 5.0 when that version hits the streets.
The theory of operation of this is quite simple, because of the beautiful API that is provided for capturing gestures. This application is merely scratching the surface of what this API can do. The only thing needed for this to work is to set up an ink analyser to do the heavy lifting for you. For this example we choose to handle the following gestures:
The complete list of available gestures can be found at http://msdn2.microsoft.com/en-us/library/ms827547.aspx
The trick for this is how to communicate the event that happens in the managed world to the unsuspecting X++ code. There is no direct way of subscribing to an event in the managed world in X++. The way I have done this may be useful in other scenarios as well, so I'll describe it in some detail:
The control on which the gestures are drawn is a Window control, which has no other semantics than publishing its window handle. As anyone who has done any windows programming back in the old unmanaged days will know, the windows handle is an identifier that is used to identify the window for all operations (drawing etc) that takes place in the window. The trick here is to pass this windows handle to the constructor of the class that recognizes the gestures. When a gesture is recognized, the proper event handler is called, and this event handler will simply post a custom message to the windows handle. When Ax is done with its own messages, this message will be handled. There is no default handler for this message (it is a custom message after all, not a predefined one), but because Uffe had a remarkable foresight 10 years ago, he added a way of subscribing to these custom events.This is done by calling the installMessageProc method on the form with the name of a method to call as a result of the given message being posted to the given handle. The init method on the form then does the following:
void init() { int h; // ... super(); h = PenArea.hWnd(); // Get the windows handle from control. // Pass it on the the stroke handler so it can react by // posting messages to this windows handle: strokeHandler = new Villadsen.StrokeHandler(h); // Make sure the method called CallbackMethod is called // when the custom message with the id 0x7ffe is posted // to the handle this.installMessageProc(0x7ffe, h, "Callbackmethod"); // ... }
The CallbackMethod then simply branches on the gesture that was recognized and does the appropriate thing. For legibility I have created a method for each action.
The managed code (i.e the StrokeHandler) is shown below. Note that the managed libraries do not have an implementation of PostMessage, so one is created by using the DllImport facility.
That's it! That's really all there is to it.You can find the source code on ftp://ftp.villadsen.dk/GestureDemo.zip