Creating Managed Today Screen Items
Today I thought I would demonstrate a proof of concept that may enable you to create today screen items in managed languages such as C# or VB.NET. In part this early preview was brought about by a recent request for advice on how to create managed Input Methods for the SIP keyboard, something that I think could be achieved using a similar approach. This is still a work in progress to see what is possible…. at the moment I have not fully evaluated the technique to be valid and/or tidied the code to my usual standard for release. I would love your feedback on this project.
Problem Definition
The Windows Mobile OS has a Today Screen API that enables custom items to be displayed on the main screen of the device. This API is highly geared towards native (C or C++) developers, and it is not possible for managed (VB.NET or C#) developers to implement the API directly.
Jim Wilson previously demonstrated in an MSDN article titled “Creating a Pocket PC Today Screen Plug-in with the .NET Compact Framework” a technique were a C++ based today screen item was developed to display HTML based content that was generated by a C# application. Although this is suitable for some applications it doesn’t lend itself to highly interactive or graphic intensive animated displays.
What we ideally want to do is to implement a minimal amount of native code that satisifies the requirements of the Today Screen API and have this native stub delegate all the GUI functionality off to a managed application.
It would also be extremely handy if the native part of this solution could be written once and reutilised among multiple managed today screen items. In part because this would open up today screen item development to those developers who currently don’t have experience in developing native code.
Solution Architecture
My solution utilises a native today screen item written in C++. This today screen item is implemented in a DLL called ManagedTodayScreenItem.dll. The OS is configured to load this item into the today screen process. However unlike other today screen items this one looks up additional configuration data stored in the registry to determine the name of a managed (i.e. VB.NET or C#) executable that should be launched when it is first displayed.
The managed executable starts up as normal and displays it’s main form. However once displayed the managed process then proceeds to establish an inter-process communication (IPC) channel back to the native today screen item. Once this channel is established the managed application informs the native today screen item of it’s window handle. The native today screen item then reparents the managed form. to be a child of the today screen item and resizes it to fit the space allocated to the today screen item.
From this point on the illusion of a managed today screen item has been made. Whenever the managed form. needs to act like a today screen item (such as painting the today screen watermark on it’s background) it can communicate with the native today screen item stub, and conversely whenever the native stub detects a change in it’s size or location it can communicate this change back to the managed part of the item.
Creating a new today screen item
Creating a new today screen item with this framework is relatively easy. Perhaps the easiest way is to modify the SampleTodayScreenItem example within the sample application mentioned below.
If you are creating a today screen item from scratch you need to follow these steps:
- Create a new Smart Device Application (win forms project).
- Change the FormBorderStyle. property of the main form. to None. As discussed previously this enables us to make the form. non fullscreen.
- Add a reference to the Christec.WindowsMobile.TodayScreen.dll assembly found in the sample project below.
- Change the main form. to derive from the TodayScreenPluginForm. base class.
The last step is very important. The TodayScreenPluginForm. class itself derives from Form. but overrides a couple of methods (such as OnPaint) to ensure the form. has the look and feel of a today screen item. This base class also behind the scenes sets up the inter-process communication channel which allows the managed part of the solution to communicate with the native part.
Your form. source code should look something like the following after these changes:
using Christec.WindowsMobile.TodayScreen; public Form1 : TodayScreenPluginForm. { public Form1() : base(4567) { InitializeComponent(); } }
A key thing to point out here is the call to the TodayScreenPluginForm. constructor that accepts an integer parameter. This integer is an id that is a unique value that identifies this particular today screen plugin. This is the part of the framework that enables the one native today screen item to be reutilised multiple times by different managed plugins (since each managed plugin should be given a different id value to differentiate itself).
Once the managed executable has been created as described above and compiled all that is required is a couple of registry settings to be added to make the operating system aware of the new today screen item. These registry settings are as follows:
Underneath HKLM\Software\Microsoft\Today\Items\
- DLL = “\Windows\ManagedTodayScreenItem.dll”
- Flags = 4567
- Name = “A name for the item”
- Options = 0
- Type = 4
The native ManagedTodayScreenItem.dll today screen item utilises this “flags” value to lookup another set of item specific registry keys to determine which managed executable needs to be executed as outlined below:
Underneath HKLM\Software\ChrisTec\ManagedTodayScreenPlugins\
- (default) = “\path\to\managed\executable.exe”
- Height = height of today screen item in pixels.
Sample Applicaton
The sample project that is available for download contains two CAB files within a subdirectory called “bin”. These are as follows:
- ChrisTec.WindowsMobile.TodayScreen-Framework.cab - installs the native part of the today screen item framework. This part can be shared among multiple managed today screen items and only needs to be installed once per device. It can be thought of as being similar to the .NET CF or SQL Server CE CAB files that install a framework for other applications to utilise. This cab file can also be utilised by managed developers who are not comfortable rebuilding the C++ source code.
- SampleTodayScreenItem.cab - An example today screen item written in C#. It simply consists of three buttons with each button displaying a simple message box once clicked.
If both of these CAB files are installed on a Pocket PC device and the device is then soft reset you should see the new today screen item appear.
If you would like to have a go at creating your own managed today screen item you should also find a pre-compiled copy of the Christec.WindowsMobile.TodayScreen assembly that you will need to reference within this directory.
Within the other subdirectory (called “src”) you should be able to find solution files that will enable you to rebuild the two CAB files mentioned above.
Outstanding Tasks
As I stated in the introduction, this project is an early proof of concept that I have decided to share early on in the hope that it helps a few people and perhaps gets a couple interested in contributing. Since the code is not fully released there are a number of known issues and outstanding tasks.
Some of these are as follows:
- Slight compatibility issues on Pocket PC 2003 devices after a soft reset.
- Does not handle the managed application crashing in the most robust manor.
- The Visual Studio IDE experience could be improved with project item templates etc.
- Having multiple managed today screen items share the single native dll probably doesn’t work (needs a little more work).
- The Christec.WindowsMobile.TodayScreeen assembly should be placed into the Global Assembly Cache (GAC).
- It would be great if less registry configuration is required.
Summary
Hopefully this blog entry will cause some interest, as I know developing custom today screen items in managed code is a frequent question on online developer help forums. Although this solution isn’t fully complete and isn’t the most straight forward to configure (at present at-least) the results I have managed to get so far are encouraging.
If this proof of concept can validate the technique I am using to host .NET Compact Framework based forms within native processes I can see no reason why it would not work in other situations such as custom SIP based keyboards. The only difference would be the native component that would need to wrap up the native API provided by the operating system.
I would be really keen to hear your feedback and thoughts on this prototype. Especially if you are able to give me a hand to further validate and develop the concept.
February 18th, 2008 at 6:39 pm
Hi Chris,
as you post, an Identifier has to be created from type int. Is it possible for future versions to use GUIDs instead of ints? Makes this more robust and more handy for code generation. What do you think?
Cheers, Peter Nowak
February 18th, 2008 at 7:01 pm
Hi,
2 more possible enhancements:
Is it possible to create a property, which is defined in an Interface. The property would describe the ID you need for the plugin. Therefore you wouldn’t need to create another constructor and the Designer could go on working as usual. Otherwise a set of Attributes would be the other possibility, which could help at this point.
A short look at your assembly by using Reflector seems, that these possibilities coud be a possible solution.
February 18th, 2008 at 7:33 pm
Thanks for your feedback Peter. They are both great ideas, and exactly the kind of feedback that I had hoped for when I decided to release this early rather than later.
The reason the existing code uses integer id’s is because it enables the native part (that interacts with the OS provided today screen API) to store the id in the “flags” field of one of the today screen API datastructures.
I also would like to see this change to using GUIDs if possible, as they would be much more easier to manage and avoid clashes in a distributed manor.
I also like the idea of moving the plugin id into an C# Attribute. This would allow the ID to be extracted from a managed executable via System.Reflection functionality which may help in my desire to simplify the installation process (i.e. avoid needing to set all the registry keys up manually and instead use reflection to obtain the values and configure them automatically via some kind of installer helper utility).
It’s these kinds of finer points that I would like to resolve before worrying about fleshing out the features of the today screen item, such as supporting dynamically sized items, or configuration dialogs etc.
February 18th, 2008 at 10:51 pm
I had a little bit of time to spend on this tonight. With a little tweaking I have managed to utilise GUIDs instead of integers for the identifiers and tidy up the required code modifications to the managed app to be as minimal as possible, as demonstrated below:
The attribute provides the GUID based identifier that uniquely identifies this today screen item, while the TodayScreenItem base class implements all the magic of communicating to the native part of the solution.
In the next few days I’ll try to upload the latest source code to a project hosting service, so that other interested developers can download the latest code snapshots and play with it themselves.
February 19th, 2008 at 1:15 am
Hi Christopher,
this sounds well on the progress you make!
Cheers, Peter
February 20th, 2008 at 6:28 am
Hey this is pretty cool - thanks for sharing!
February 20th, 2008 at 11:02 pm
Thanks Lou,
I’ve fallen sick since I originally posted this and had a couple of days off work. As I mentioned in the original post this was quite an early proof of concept that I intended to further develop.
Over the next few weeks, you should hopefully see some updates which make it easier to develop today screen items, and provide improved functionality.
One such improvement I should be able to release fairly soon is one that removes this whole “id” business, meaning you don’t need to give each custom today screen item a unique id.
February 21st, 2008 at 12:50 am
Congratulations for coding this soft, that’s exactly what current developpers that don’t have a lot of background in Win32 are looking for.
You’re talking about SIP, I guess it also works for services (that currently have to be native code too).
I wish I could help you on the coding of this one, but I a bit short of time right now.
Good luck anyway, & hope you’ll feel better soon! :D
February 21st, 2008 at 11:38 pm
Hi,
Yes in theory this “solution” may work for services, although in that case it possibly means loosing many of the benefits that creating a service typically provides.
I have started work on an improved version of the managed today screen item proof of concept. If this pans out over the next few weeks and the technique is validated my next API to investigate would be managed SIP keyboards.
At the moment I don’t have a plan for anything after that point.
February 27th, 2008 at 3:41 am
Great - Work - I spent night about the Sample from the WM5 SDK - but when you are not so C++ you fail ;)
THANXS a Lot
February 29th, 2008 at 10:06 pm
Hi Daniels,
You might like to view the “Announcing the ChrisTec Managed Today Screen Framework” blog post. Since I wrote this blog post I have been persuaded to turn this into a project and work on fully implementing this concept.
The project is being hosted on CodePlex so more recent updates etc can be found via that website.
Thanks,
Christopher Fairbairn
March 22nd, 2008 at 10:03 am
Hi, I tried to change the heigth of the today’s item in the OnClick event. I couldn’t do it by changing the Size, ClientSize, Refreshing, Updating… and so on… the control. How should this be done properly? thanks
March 28th, 2008 at 6:59 pm
Hi Mike,
Thanks for the feedback. I’ve added this feature request into the issue tracker. The issue can be tracked at http://www.codeplex.com/ManagedTodayScreen/WorkItem/View.aspx?WorkItemId=1580.
It’s a very good suggestion.
Thanks,
Christopher Fairbairn
May 2nd, 2008 at 9:18 am
Hi Mike,
Thank you for the great job. If I understand this right all your code is applied only for Pocket PC. What’s about Home screen of Smartphones?
Did you do anything on Smartphones?
Thank you in advance.
June 11th, 2008 at 3:43 am
Tried to compile and run your sample With VS2005. I do want to migrate to WM6 and implement my own code.
Certainly not really a problem but for non professional coders it is:
Der Konstruktor für den Typ Christec.WindowsMobile.TodayScreen.TodayScreenPluginForm. wurde nicht gefunden.
Could you help me out please.
Tk u willi
July 10th, 2008 at 9:57 pm
I recently wrote a full screen managed Home Screen plugin (Smartphone). More information/tips/tricks here: http://www.koushikdutta.com/2008/07/dirty-tricks-of-windows-mobile-home.html
August 28th, 2008 at 3:28 am
Thanks for such an excellent article, but for some reason, I really need the method to realize changing the form’s height dynamically., and i’m not quite familar with c++, could you just at least give a hint on that?
September 24th, 2008 at 6:41 am
i am using your christec.windowsmobile dll to create a today screen form. my problem is when i you click on the today screen form, it goes to a standard application. within the application, you can make settings changes that affect the today screen. my problem is, i do not or can not figure out how to refresh the today screen to use the new settings.
thanks much
November 2nd, 2008 at 2:09 am
I build it, but not pass.
There are two error:
1:
error 6 fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include “stdafx.h”‘ to your source? d:\develop\UI\ManagedTodayScreen-9160\Framework\ManagedTodayScreenItem\ManagedTodayScreenItem.cpp 315
error 7 not find file “ManagedTodayScreenItem.dll” (“%InstallDir%”) file “d:\develop\ui\managedtodayscreen-9160\framework\managedtodayscreenitem\windows mobile 6 professional sdk (armv4i)\debug\ManagedTodayScreenItem.dll”,maybe it is not exist D:\develop\UI\ManagedTodayScreen-9160\Framework\ManagedTodayScreenItemCab\ManagedTodayScreenItemCab.vddproj
Please help me solve the errors.
Thanks
November 2nd, 2008 at 4:56 pm
I am trying to use your control and am able to use the sample project. However, anytime I install my project and go into the today app to activate my today screen plugin and exit I get the following error: “The file ” cannot be opened. Either it is not signed with a trusted certificate, or one of its components cannot be found. If the problem persists, try reinstalling or restoring this file.”
Very frustrated. I have compared my project and your sample project and can not find any difference with regards to registry, implementation, etc… Hope you can help shed a light.
Thanks.
December 23rd, 2008 at 5:01 pm
謝謝您!
January 10th, 2009 at 4:17 am
Could I get a VB.NET Visual Studio 2008 Sample, I can’t upgrade this project for some reason. Thanks this is just what I was looking for, but I need VB.
January 16th, 2009 at 6:41 am
Hi Chris!
Any idea why when I soft reset, plugin wont show in the Today Screen?
Thanks!