Wednesday, February 20, 2008

DesignTime-Controls for .Net CompactFramework with P/Invoke

Creating designtime-controls for the .Net CompactFramework isn't so difficult today like in former days. The tools are much better and the documentation also. But only when you just use the 'normal '-.Net stuff.

When you plan to create a custom control for the .Net CompactFramework which uses a lot of Api-functions, you will get into a lot of trouble.

The reason? The Reason is quiet simple. The .Net CompactFramework isn't so complex like the desktop-version, and so you have to use much more often P/Invokes for some features.

The Win32-Api provides a lot of function. The most functions are based in ‘user32.dll’ and ‘gdi32.dll’. Sure there are nearly uncountable more functions in other Dll-files, but these two files should be enough for the moment.

On devices with Windows Ce it’s a little bit different. The WinCe-Api is mostly in the file ‘coredll.dll’. The WinCe-Api contains a smaller number of functions from Win32-Api.

For this documentation I choosed an Api-function which you might use very often, the SendMessage-function. Sure, you can use the SendMessage-implementation from the ‘Microsoft.WindowsCE.Forms”-namespace (MessageWindow.SendMessage()), but in my opionon, this is a good example.

OK, let us start now:

When you declare a P/Invoke in a solution for mobile devices it looks like that:

[System.Runtime.InteropServices.DllImport(“coredll.dll”, EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);

That source code works fine on a mobile device, but you want to create a design time-control and than, that part of source code had to run on a Win32-Api. Damn – it fails. But why? You tried to let source code run for mobile devices with a WinCe-Api on a Desktop-Computer with a Win32-Api. The source code just tried to do what you want, to import the ‘coredll.dll’-file and they is ‘missing’ in the Win32-Api.

So what we do to let that source code run on both Api? It’s not very difficult but sometimes very helpful. Let’s take a look on the following diagram, it shows you a simple and easy way how you can use the same source code on both platforms.

In the contructor of your class you need a condition which ask on which platform the source code is running.

How to implement both Api:

All what we need are three new classes and a new object in your current source code.

At first we need a base class which provides all api-functions.

Api-base class

At the next step, we need for both, the WinCe and the Win32,-Api a class which imports the correct Dll-files snd declares the correct imported functionnames. Both classes inherits the base class.

ApiCe for WinCe-Api

ApiDsk for Win32-Api

The following step is to create an Api-object in your custom control. The object type is the Api-base class.

The last step is to modify the constructor of your custom control. It need a condition which ask on which platform your source code is running.

Condition for the OS


To call the Api-function from your source code, you need just a single call for both Api.