Showing posts with label Windows Mobile. Show all posts
Showing posts with label Windows Mobile. Show all posts

Windows Mobile Unified Sensor API heads to CodePlex

codeplex_toplogo[36]

At the behest of the development community and colleagues, the Windows Moble Unified Sensor API is now hosted on CodePlex. I will continue blogging about the changes on my website of course, but all the releases and source code must now be retrieved from CodePlex! (CodePlex is pretty awesome by the way... it has support for multiple source control bindings, and the web client repository browser is fantastic. (I use CodePlex for Windows Mobile stuff, and Google Code for Android. It makes sense in my head. [0])

In the following weeks, I intend to do the following:

  • Reexamine the implementation (and possibly even the current interfaces) so it is easier for manufacturers to build devices that can leverage the dizzying array of sensor enabled software that already utilize the Sensor API.
  • Clean up the HTC implementation.
  • Add support for capacitive touch panel to the HTC implementation with the new reversed engineered headers provided by a reader of this blog.
  • Create a few tutorials.
  • Add a FAQ to the CodePlex wiki.

If anyone else is interested in contributing to the Sensor API project, please let me know!

 

[0] The decision on whether to put the Android Mono port on CodePlex or Google Code was a tough one. :)

Quoted in Business Week

I was interviewed/quoted for an article in Business Week, "Windows Mobile: What Microsoft Needs to Fix". Kinda cool.

The Microsoft/Netflix Marriage - Coming Soon to a Windows Mobile phone near you?

Netflix's Watch Instantly first came to the Windows PC, and then to the Xbox. And, apparently Netflix loves being in bed with Microsoft so much they decided to scrap their existing online movie player in favor of one based on Silverlight. If you want to try the new Beta player, check this link out: http://www.netflix.com/silverlightoptin

How long till we see a player for Windows Mobile? I made an offhand prediction a while ago that we'd see Netflix on Windows Mobile phones within the year. A Silverlight implementation may make it that much more of a reality...

Post 11: Android versus Windows Mobile Development

I wanted to refrain from blogging about this until I had at least somewhat delved into Android development. And although I am by no means a guru at the Android platform yet, I feel I can safely make some broad statements, step on some toes, and be able to sufficiently back up my opinions. [0] :)

 

The Byte Code

Google made some interesting architectural and strategic decisions regarding Android. The most notable being Java as the development language and Dalvik as the underlying bytecode. Dalvik, in short, is a byte code that is interpreted at runtime, similar to Sun's Java byte code or Microsoft's Intermediate Language (aka IL)[1]. I didn't really understand why Google would go and create another byte code specification for Java until I read a great article by Stefano Mazzochi. The long and short of it is, Sun has some nasty licensing around Java ME, and the "Open" Handset Alliance can't really have an Open platform with the possibility of some mega-corporation trying to wet their beaks at their expense. [2]

So, still begs the same question: why invent a whole new byte code when Intermediate Language has no such licensing (it is an ECMA approved standard)?  Maybe Google took a look at it and decided it wasn't suitable for a mobile platform, or maybe they didn't want to jump into bed with Microsoft. I'm guessing the latter.

 

The Language

At the end of the day, the byte code generated behind the scenes is about as important as the color of my socks. I generally don't think about it on a daily basis, and what really matters is the language you are writing in. I can understand that Google chose Java to ease their target developer base's transition the new platform, but still... I'm going to just go ahead and say it. Java sucks.

How much does Java suck? Let me count the ways.

  1. Terrible constraints around package/file/directory/class names.
  2. Lack of anonymous methods.
  3. Lack of closures.
  4. No lambda expressions (or LINQ).
  5. Lack of events/delegates.
  6. Lack of partial classes.
  7. Ridiculous implementation of enumerations.
  8. Terrible implementation of generics (type erasure).
  9. No user defined value-types: no "struct" and thus no capability of having objects that live purely on the stack. This is nasty on performance when it counts (such as in games).
  10. Strings are immutable, but not interned.
  11. No access to "unsafe" code.
  12. No get/set accessor methods.
  13. No operator overloading.
  14. No extension methods.
  15. Last but not least, stupid and unintuitive brace positioning.

How many ways? 13, 14, 15, Ha, Ha, Ha, Ha, Ha!

 

I'm not trying to be a nit-picky zealot here; everything I listed is a feature I use on a regular basis. I will admit though, that I am enjoying anonymous classes to some degree, but they would be mostly pointless with the availability of events/delegates. I realize that most of what I listed is just syntactic sugar, and neither Java or C# is more "powerful" than the other; they can each do anything you need in their own way. Except C# lets you do it more quickly, intuitively, and elegantly. [3]

 

The Development Environments

Eclipse is a giant steaming pile of... yeah. Yes, very capable, very flexible, but whoever is doing usability testing on this junk needs to get a job that involves testing the constricting force of a rope around their neck.

My biggest pet peeve is the fact that you can't simply click in the Expressions view and edit or add something inline. You have to right click it and click add/edit. That takes you to a vanilla text editor (which has no Intellisense/Content Assist), type in your expression, pray it is parsable, and then click ok. Otherwise you are having to go through that zillion step process yet again.

Earlier I gave some kudos to Java's inner class capabilities. As neat as they are, Eclipse makes them damn near unusable: you can't watch a value of a member variable in the parent class of an inner class. That makes debugging a giant pain: you need to load all those members into local variables if something is going wrong, otherwise it is impossible to find and fix even simple issues, such as a null reference. I'm not sure if this is a problem with Eclipse, Java, or Android though.

The auto-complete in Eclipse is painfully annoying. Auto-complete should be optional, and not forcibly inserted with no regard to what the developer wants. I ended up turning it all off, because what it was inserting was generally useless. And even though the auto-complete is off, Eclipse is still inserting parenthesis for me...

 

The SDKs 

Though I have been complaining a lot about developing on Android, I do want to point out that I haven't actually complained about Android. Basically every API I could think of was standardized and implemented.

My litmus test in this regard was a port of Klaxon to Android. It really helped underscore the huge differences between the two platforms.

For me, most notable was the APIs to access device sensors. Version 1 of the Android SDK exposes a simple SensorManager class that took me 5 minutes to figure out and access. Microsoft has had 6ish versions of Windows Mobile with no Sensor API in sight.

Secondly, scheduling processes to start on Android is infinitely easier than in Windows Mobile. Here's how that learning process worked for me on Windows Mobile:

  • First I started with CeRunAppAtTime. I write a gross PInvoke for this. This works for a while, then stops working completely. Others have had this issue as well. I need to switch to another mechanism.
  • Then I switched to CeSetUserNotificationEx. I write yet another gross PInvoke for this.
  • This involves filling out some elaborate UserNotificationTrigger structure. I eventually get this working.
  • Then I find that if the device is sleeping, Klaxon sometimes does not start properly.
  • I solve this issue by digging through some documentation and randomly figuring out the problem: I need to force the device to turn on or it goes back to sleep.
  • Klaxon works again for a while, until daylight savings occurs. On some phones, it is now firing an hour late. I have no idea why. I have given up.

Let's compare this to Android:

  • Access the AlarmManager.
  • Tell it to turn on and fire an intent at a certain time.
  • Handle the intent.

This just works, no hassle, no fuss. I must say, intents are easy to use, amazingly flexible, and equally powerful.

So, two of the "difficult" parts for creating Klaxon on Windows Mobile were not so difficult at all on Android. The final piece: UI implementation.

Windows Forms code versus Android's XML Layout. Windows Forms which works with absolute sizing and positioning, and Android which uses relative sizing and positioning. Windows "Static" Controls versus Android's Animatable Controls. There really is no comparison, so I won't even bother.

Simply put, the relevant Android SDK blows the Windows Mobile SDK out of the water (language and framework features aside).

Windows Mobile does have far better documentation (MSDN) than Android, but I consider that more of a teething issue that would occur with any new SDK.

 

The Platforms

Android is pretty heavily locked down from a security standpoint. Applications must register what capabilities they wish to have, and the user must approve of them. And though this security is all in all a positive thing, it does have it's downsides; for example, it is impossible to write an application that screen shots a screen other than its own, as this is considered a security risk. [4]

And though this is not really a fault of Android per se, the phones that are actually being released are not as "open" as the name Open Handset Alliance would suggest. Carriers always have and will continue to lock down phones so long as they subsidize them. For example, the user does not have access to the root account on the G1; this makes removal/tweaking of the standard Android applications impossible. But at least on Android you can tweak the standard applications due to it being open source (after getting root).

On the flip side of the coin, Windows Mobile doesn't have a VM hiding all the nitty gritty details from you. Developers can easily get low level access to anything, without having to worry about Microsoft filling the holes. For example, if Android were to have shipped without a Sensor API, there is no way (outside of manually installing native binaries through ADB) that a developer could implement it. And that is not a comforting feeling. For example: Android does not support streaming video through the MediaPlayer yet, and as far as I know, nothing can be done about that unless the native android binaries are patched through an OTA update.

Oh, and the Android Market. Not going to bother elaborating on this point, as the statement itself is pretty self explanatory.

 

Summary

I don't really have anything insightful to say here, and that may be because it is 4AM. I'll wrap it up by saying, I really enjoy developing for Windows Mobile. The language and tools are great. However, the platform and applications simply are not very usable. On the other hand, though I'm not completely discontent with Android development, the platform, applications, and general usability is fantastic; for once I don't have to fight my phone to do simple things like browse the web. So you can guess which phone is always in my pocket. And then you can infer which once I am more interested in developing in.

That said, I hope Microsoft can produce a usable platform in the near future; as that would make me a very happy user and developer. I can't believe I'm going to say this, but they should take a page out of Apple's book and just say "screw backwards compatibility, screw existing applications, we're going to develop a brand new platform that works". They've been catering to the backwards compatibility mantra for so long that it is impossible for them to move forward. And all the while, they are alienating the very market share they are so afraid to lose.

 

 

[0] I've released 2 applications on the Market, Telnet and Klaxon, so I feel I have a decent grasp of developing for the Android platform. Klaxon has really helped underscore the huge differences in the platform.

[1] Yes, I realize that IL is not interpreted on the Windows Platform, it is JIT compiled.

[2] As "evil" as Microsoft may be connoted to be, you don't see them on the news exercising their patent rights. Unlike Sun.

[3] I'm thinking about looking into Ruby.

[4] Maybe Google will implement this in the future.

Silverlight 2.0 Too Heavy for Windows Mobile - Pun Intended

square_peg_in_round_hole_2

I managed to get my hands on a an internal copy of Silverlight 2.0 for Windows Mobile and have been playing around with it. It makes me a sad panda. It's so unbelievably slow. It might be because it it's a Debug build. It might be because it doesn't support hardware graphics acceleration. Or it might be because they tried to fit the desktop architecture onto a mobile phone. Take your pick, you guess is as good as mine. But Silverlight application development on Windows Mobile does not look promising.

Using Samsung Omnia's Accelerometer/G-Sensor from Managed Code

Many months ago, I wrote an API to access the HTC Touch Diamond's Accelerometer from managed code. Those who investigated the code a bit deeper probably noticed that I had stubbed out an interface, IGSensor. I did that in anticipation that many Windows Mobile devices in the coming months would include an accelerometer. It turns out I was right. The idea behind the IGSensor interface was to provide a generic unified API that a developer could use to access the accelerometer of any device without having to worry about which device it was.

Anyhow, I'd gotten several requests to investigate the Samsung API, if there was one. Not an Omnia owner myself, I wasn't particularly motivated. Then yesterday, one of the requestors informed me that Spelomaniac from modaco.com had figured out how to access the Samsung Omnia's accelerometer.

We happened to have an Omnia at my workplace, Kiha, so I grabbed that, and ported the code so it was supported by my API. So yeah, it's all working!

I highly recommend that all developers to download the updated API and make the minor changes necessary so that Omnia users can make use of the HTC Touch Diamond accelerometer applications! Here are the new breaking changes in the API:

  • HTCGSensor is now a private class.
  • SamsungGSensor is a new private class.
  • Instead of creating a HTCGSensor or SamsungGSensor explicitly, developers should use the new GSensorFactory.CreateGSensor method to get the appropriate IGSensor object for the phone the application is running on.
  • IGSensor is now IDisposable. Developers should Dispose of the object once they are finished using it. Not doing so may leave resources or a thread hanging and the application may fail to exit.

That's it! The code changes you need to make should only take you a few minutes.

Click here to download the new Windows Mobile Unified Sensor API.

I'll be making the changes necessary to Klaxon this weekend so it runs on the Omnia. :)

Here is the original C++ code I for the HTC GSensor emulator in case you are interested. I would not recommend using the HTC Accelerometer emulator, because it does not support Orientation Change notifications through the Windows registry.

Post 9, The Rant Continues: TabIndex is Terrible. Windows Mobile needs "Smart" Key Navigation.

Yeah, so it's been well over 30 Days as I originally predicted, so I'm renaming this series 30 Posts of Bitching about .NET Compact Framework.

Windows Mobile "Standard" [0] device development is a pain. I've never owned one, because I can't really live without a touch screen.

I still fondly remember many years ago, when I first fired up the Visual Studio Form designer with the Smartphone form factor. I started started dragging my controls out, doing the usual, then I noticed something odd: I didn't have a Button control on my toolbox. I searched around for a bit, and assumed that my Visual Studio installation was hosed. I created a new Pocket PC project, and the Button control was there. So I dragged one out, and then changed the target platform to Smartphone. I reopened the form and saw this intimidating hazard sign:


BrokenSmartphone

Attempting to run the application resulted in a NotSupported exception. Apparently simple Button controls aren't supported on Windows Mobile Standard for whatever reason. I guess this is because there is no touch screen, and thus no mouse clicks, so they just dropped support for the Button control and left the developer with LinkLabels. That really brings application development to a grinding halt if you are trying to target both Smartphone and Pocket PC. [1]

Man, I've really strayed from the point of this article. Getting back on track: The purpose of this post is to discuss something I mentioned briefly in a previous post. One of the annoying issues associated with Smartphone development is that since you are restricted to only keyboard input, your application has to be very aware of key navigation. The user should be able to intuitively navigate through all the forms quickly and easily. However, from an API level, all the developer is given is TabIndex. TabIndex is a property that you can set on any control that let the Windows API know the tab order of controls. For example, the Up button on a Smartphone would take you back to the control with the previous TabIndex, while the Down button would take you to the next TabIndex.

All is well in the world of TabIndex and simple 5 minute applications. TabIndex works great if all your controls are laid out vertically, with one control per line. But if you need to do any real Windows Mobile application development, chances are that TabIndex will not cut it. Take for example the following Form:

TabIndexSucks

 

For visual reference, the yellow region is a panel housing 4 LinkLabels, and the white region is the Form housing the other 6. The TabIndex of each Link is shown.

Navigating through this form is gross. For one, the Left and Right keys don't actually navigate left or right to other Controls. And the Up and Down Keys simply go through the Controls in TabIndex order. So, if "Panel TabIndex 0" had focus, pressing up would take you to "Form TabIndex 5" and not "Form TabIndex 2". Conversely, if "Form TabIndex 2" had focus, pressing down would take you to "Form TabIndex 3" and not "Panel TabIndex 0".

Basically, once you introduce any sort of grid or panels, TabIndex probably will not work for you. At that point, you need to hook the KeyDown events and handle the navigation to and from each Control... manually... for every Form. And as development progesses, and the UI changes, you better make sure that you update all those nasty KeyDown event hooks so your navigation doesn't break!

This is not ideal; it introduces code bloat, bugs, and is in general just tedious to do. To that end, I wrote an algorithm that would analyze the Controls in a Form and figure out the best Navigation target from any given Control (if there was one).

I'm not going to really get into the algorithm in great detail. Basically the way it works is that it looks at the key that was pressed and finds the corresponding edge of the Control. It uses that edge to find the opposite edge of all the other controls that has the best "score". A score is comprised of 2 factors: how close are the edges to each other and how much of the edge is "shared". Yeah, that probably made no sense. Maybe this picture will help:

EdgeAlgorithm

 

So, yeah, Edge Distance and Shared Edge Length are the two weighting factors in determining the best navigation target.

This navigation code is actually a small part of the overall UI framework I use. I've stripped out the algorithm and repackaged it so that it can be used by anyone. Usage is pretty straightforward. The Navigation class has two members:

  • FindFocusedControl - Find the control on the Form that is currently focused.
  • GetBestNavigationTarget - Given a Control and a navigation Key (Up, Down, Left, or Right), find the best navigation target.

To catch navigation events easily, you can do it at a form level by enabling KeyPreview. Then override OnKeyDown and use those two methods to find the Control that should receive focus. For example, here's the code from the sample:

using System;
using System.Windows.Forms;

namespace KeyNavigationDemo
{
public partial class NavigationDemoForm : Form
{
public NavigationDemoForm()
{
InitializeComponent();

// By enabling key preview, the form receives all key events
// that would otherwise be received and processed by a control.
// We can choose to handle these events.
KeyPreview = true;
}

private void myExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}

private void mySmartNavigationMenuItem_Click(object sender, EventArgs e)
{
mySmartNavigationMenuItem.Checked = !mySmartNavigationMenuItem.Checked;
}

protected override void OnKeyDown(KeyEventArgs e)
{
if (mySmartNavigationMenuItem.Checked)
{
switch (e.KeyCode)
{
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Left:
{
Control focused = Navigation.FindFocusedControl(this);
if (focused != null)
{
Control navigateTarget = Navigation.GetBestNavigationTarget(focused, e.KeyCode);
e.Handled = true;
if (navigateTarget != null)
navigateTarget.Focus();
}
}
break;
}
}
base.OnKeyDown(e);
}
}
}

Here's the full source code to the navigation algorithm and the sample demonstrating how to use it. The sample application is the same one you see in the above image with 10 LinkLabels. By default, Smart Navigation is disabled, use the arrow keys to navigate around the form using TabIndex. Then enable Smart Navigation in the Menu and use the arrow keys to navigate intuitively.


The sample is just a demonstration of the navigation; keep in mind that some Controls may want to handle certain key presses. For example, text boxes should generally receive the left and right key presses to navigate within the entered text and not to another Control.


[0] "Standard" is the official Microsoft term for a Windows Mobile non touch screen device. Professional is the term for touch screen devices. It used to go by "Smartphone" and "Pocket PC" back in 2003, and then they changed it to Standard and Professional, so that's how it is now. I think. Don't quote me. In fact, forget you ever read this.


[1] I should mention, there is nothing to stop a developer from basically inheriting from Control and overriding OnClick and thus creating a Button control. This works just fine, and it is just benign code on a Smartphone; behind the scenes those mouse methods are just a result of receiving WM_LBUTTONDOWN/UP messages. So, I ended up creating my own ButtonBase class in the UI framework I wrote/use.

Windows Mobile Video Power States

All in all, development on Klaxon has given me some great insight into how power states affect program execution. One of the changes I am making to the newest version of Klaxon is to turn the device's video off when the user hits snooze.

Since the earliest versions of Klaxon, I have been using the SystemIdleTimerReset call to prevent the device from going to sleep. This behavior is necessary because the application needs to continue running to pick up sensor events. However, using SystemIdleTimerReset has the unintended effect of leaving the display on: it should be turned off so as not to drain the battery or have a distracting bright light on in the room while the user is trying to sleep. So I did some searching to see if there was a way to explicitly turn off the video, but allow program execution to continue. The behavior I wanted is similar to how Windows Media Player can turn off the video but the songs keep playing, and the device does not go to sleep until Windows Media Player is stopped.

It turns out that Windows Mobile has several video power states, which are described quite nicely in an MSDN article. I ended up wrapping these native power management calls into a bow tied package for usage in C# for your reusing pleasure:

using System;
using System.Runtime.InteropServices;

namespace WindowsMobile.Utilities
{
public enum VideoPowerState
{
VideoPowerOn = 1,
VideoPowerStandBy,
VideoPowerSuspend,
VideoPowerOff
};

public static class Device
{
const int SETPOWERMANAGEMENT = 6147;
const int GETPOWERMANAGEMENT = 6148;

[DllImport("coredll")]
extern static IntPtr GetDC(IntPtr hwnd);

[DllImport("coredll")]
extern static int ExtEscape(IntPtr hdc, int nEscape, int cbInput, ref VideoPowerManagement vpm, int zero, IntPtr empty);

[DllImport("coredll")]
extern static int ExtEscape(IntPtr hdc, int nEscape, int zero, IntPtr empty, int cbOutput, ref VideoPowerManagement outData);

struct VideoPowerManagement
{
public int Length;
public int DPMSVersion;
public VideoPowerState PowerState;
}

public static VideoPowerState VideoPowerState
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
VideoPowerManagement ret = new VideoPowerManagement();
ExtEscape(hdc, GETPOWERMANAGEMENT, 0, IntPtr.Zero, 12, ref ret);
return ret.PowerState;
}
set
{
IntPtr hdc = GetDC(IntPtr.Zero);
VideoPowerManagement vpm = new VideoPowerManagement();
vpm.Length = 12;
vpm.DPMSVersion = 1;
vpm.PowerState = value;
ExtEscape(hdc, SETPOWERMANAGEMENT, vpm.Length, ref vpm, 0, IntPtr.Zero);
}
}
}
}

Usage:

Just get or set the Device.VideoPowerState property to do whatever you need!

Windows Mobile Screen Capture

I often find myself needing to query the phone's screen dimensions or needing to take a screen shot for demo purposes. This usually resulted in me recycling some of the screen scraping code I wrote for Omnipresence (a prototype cross platform remote desktop type client). I figured I may as well post this code since it's been pretty handy to me, and that others may find it handy as well.

The code below lets you do just that:

  • PixelDimensions - Returns the device's resolution.
  • GetScreenCapture - Capture the current contents of a screen to a bitmap that can then be saved/manipulated however you please.
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

namespace WindowsMobile.Utilities
{
    public class DeviceScreen
    {
        enum RasterOperation : uint
        {
            SRC_COPY = 0x00CC0020
        }

        [DllImport("coredll.dll")]
        static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);

        [DllImport("coredll.dll")]
        private static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("coredll.dll")]
        private static extern int GetDeviceCaps(IntPtr hdc, DeviceCapsIndex nIndex);

        enum DeviceCapsIndex : int
        {
            HORZRES = 8,
            VERTRES = 10,
        }

        public static Size PixelDimensions
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                return new Size(GetDeviceCaps(hdc, DeviceCapsIndex.HORZRES), GetDeviceCaps(hdc, DeviceCapsIndex.VERTRES));
            }
        }

        public static Bitmap GetScreenCapture()
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            Size size = PixelDimensions;
            Bitmap bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format16bppRgb565);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                IntPtr dstHdc = graphics.GetHdc();
                BitBlt(dstHdc, 0, 0, size.Width, size.Height, hdc, 0, 0, RasterOperation.SRC_COPY);
                graphics.ReleaseHdc(dstHdc);
            }
            return bitmap;
        }
    }
}

Day 3: Outlook Notes Mobile

outlooknotes1 outlooknotes2

This isn't really so much a complaint about Windows Mobile development, but more so about hole in the platform's user experience.

If you're an avid Windows Mobile user, you are familiar with the Notes application: you can create a short text or image note and have it sync to your desktop. Then the desktop will sync it to Exchange. However, there's a couple problems:

  1. Only Pocket PCs come with the notes applications: Smartphones do not.
  2. You must use your desktop ActiveSync connection to sync with Exchange; it does not sync directly.

To resolve this, a few months ago I wrote an application that allows you to view, edit, and create notes on your Windows Mobile device, and sync directly with Exchange.

Download Outlook Notes Mobile.

Usage:

  1. Start Outlook Notes Mobile.
  2. Go to settings.
  3. Enter the same login information you provided ActiveSync. (The server will be in the format of "mydomain.com" or "mail.mydomain.com", ask your SysAdmin).
  4. Synchronize. (There is no automatic synchronization).

Note:

If you have problems getting this application to work, it may be due to your Exchange server setup. The Microsoft "recommended" Exchange deployment does not expose the Exchange Web Service (it redirects all requests to the OWA client).

HTC Touch Diamond Stylus Sensor API

StylusSensor

I spent a bit of time figuring out how to determine the stylus on the HTC Touch Diamond. It only took like 5 minutes: it was exactly where I suspected, a registry key that toggled depending on the stylus state. So basically it's really easy to access. I rolled access to this registry key up in the Sensor SDK.

(HKEY_CURRENT_USER\ControlPanel\Keybd\StylusOutStatus for those curious.)

The new HTCStylusSensor has 2 members:

StylusState

This property is has a value that is either StylusIn or StylusOut.

StylusStateChanged

This event fires whenever the StylusState property changes.

Click here if you want to download the APIs and source to access the G-Sensor, Light Sensor, Nav Sensor, or Stylus Sensor.

 

I will be releasing an tool shortly that allows users to launch any application, shortcut, sound file, etc, when the stylus is removed from the device.

Day 1 - Windows Mobile OpenFileDialog and SaveFileDialog, why are you so terrible?

Yeah, so whoever the UX person is behind the Windows Mobile version OpenFileDialog and SaveFileDialog, they need to reevaluate their career choice. Here's a screen shot of these beauties in action:

save open

What the hell is with the OpenFileDialog? You can't browse through the file system to find what you want. You gotta bust out the stylus (problem #1) and search for the file. And even then it has to be in the path of your My Documents folder (problem #2).

I try to avoid these dialogs like the plague, but finally ended up needing an OpenFileDialog. I ended up writing my own out of principle:

goodopen

Don't get me wrong, this isn't the end all be all of Windows Mobile OpenFileDialogs, but it is infinitely better than the stock version. It works basically like the standard OpenFileDialog:

  1. Create an instance.
  2. Set a filter if need be.
  3. Set the initial directory if need be.
  4. ShowDialog

I still want to tweak it a bit more so that the fonts and such are all customizable via the developer, and eventually write a SaveFileDialog (probably just throw a TextBox at the bottom). But this will do for now; you can download the assemblies for the Windows Mobile OpenFileDialog here. You'll need to deploy all the assemblies to use it, but the type in particular you should be interested in is WindowsMobile.CommonDialogs.OpenFileDialog.

30 Days of Bitching about .NET Compact Framework

If you're an aficionado of .NET Compact Framework development, you've probably stumbled across Chris Craft's blog and read 30 Days of .NET [Windows Mobile Applications].

All in all it was a great series. There were a good number of "fillers" so to speak, but the gems more than made up for it.

The tag line of my blog is "I like Windows Mobile development. Does that make me a masochist?"; and it is quite amazing how often that statement really rings true. Windows Mobile is by necessity a subset of the fully featured desktop version of Windows. And the same goes for .NET and it's little brother .NET Compact Framework. I retract that statement; "little brother" does not do .NET justice when comparing it to CF. I think "adopted bastard red headed stepchild" seems more fitting, don't you? [0][1]

Anyhow, the purpose of this post was to announce that in a sort of satirical homage to Chris' series I will be blogging/bitching the next 30 days about all the pitfalls of Windows Mobile and .NET CF. And if we're lucky, I'll describe any workarounds I may have found. Ok, I'll be up front: don't check this page every day expecting an update; I've been rather busy lately. However, I have more than enough to work with that I can catch up with any amount backlog should I fall behind.

And with that; I'll start with an easy one!

Day 0:

WPF or Silverlight. I want it on Windows Mobile. One of the more annoying aspects of Windows Mobile development is that there are so many screen resolutions to support. Designing an application that looks good on any screen resolution is quite a chore. To implement this properly, one would need a set of classes that allow you to lay out your screen elements in relative measurements rather than absolute dimensions.

The full version of .NET has a TableLayoutPanel class which has the aforementioned behavior. However, that class does not exist on .NET CF. In fact, no intelligent layout code exists from anything released by Microsoft. The Android SDK comes with this sort of UI framework in their V1 product. And I'm not too familiar with the iPhone SDK, but my guess is that when you are supporting a single screen size, it's probably not a huge issue.

Solutions:

Though I can't release the source, I basically wrote a bunch of WPF style classes to do intelligent layout. These classes include StackPanel, DockPanel, WrapPanel, Grid, and ItemsControl. You can probably just grab the WindowlessControls assembly (don't ask me why I called it that) out of any number of my released projects and try to figure out how to use it (hello ILDASM). I should also mention that all the controls support transparencies and "bubbling" up events to its parents; similar to WPF. The ItemsControl is also data driven and rendered using a ContentPresenter similar to WPF.

 

I somewhat lied about Silverlight not being available on Windows Mobile. It is, but it's in beta. The problem is that it requires it to be hosted in a browser. Unfortunately the WebBrowser control in Windows Mobile is not as fully featured, and does not give you access to the DOM. That makes reacting to events on the Silverlight control in non JavaScript code impossible; or at least I thought.

Recently I figured out a way how to invoke C# code through JavaScript. The first step is to get from JavaScript into unmanaged code:

  1. Create an ActiveX control project.
  2. Embed a WebBrowser in your Windows Forms application.
  3. Embed that ActiveX control in your browser HTML. (using <object>)
  4. Funnel all Silverlight events from JavaScript into your ActiveX control.  Now you are in unmanaged code.

Now to get from unmanaged code into managed code:

  1. In your ActiveX control project, create a DLL export that accepts and stores a function pointer or a COM object. This function pointer or COM object will be passed in from managed code.
  2. Create a DLLImport to that function. Pass in a pointer to a method/COM object in managed code.
  3. When JavaScript is invoked, your ActiveX is being called into. Now from that point, you can then call into the managed function pointer you provided earlier. I'll leave the exercise of passing and parsing arbitrary arguments up to the reader. You can basically invoke any method name and any method signatures of any C# function from JavaScript by using a crafty combination of string parsing and reflection. The solution I had was quite elegant for being a giant hack in the grand scheme of things.

And there you go! You are now creating Silverlight thick client applications just like on the desktop!

 

[0] I speak in jest. I do not mean any offense to anyone who is adopted, a bastard, or a step child. I did mean the red head remark though.

[1] Real developers zero index their blog footnotes.

Sensory Overload

SensoryOverload

A few days ago I published the Managed OpenGL ES wrapper. As a proof of concept, I went so far as to create a simple game for the HTC Touch Diamond that utilizes the G-Sensor, Nav Sensor, and the 3D hardware capabilities of the device. The end result is a simple "Asteroids" type game I call Sensory Overload.

The game is simple:

  • Move the ship by tilting the device.
  • Don't run into an asteroid.
  • Blow up the asteroids into tiny pieces.
  • When an asteroid spawns (it will be faded out), you have 5 seconds to get away from it before it can hurt you.
  • Rotate the Nav sensor clockwise to fire a bullet.
  • Rotate the Nav sensor counter clockwise to fire a spray of bullets. You can only use this special ability once every 5 seconds.
  • Asteroids spawn every 15 seconds.

This is mostly intended as a demo or proof of concept to provide other developers starting ground to create their own amazing games for the HTC Touch Diamond.

Known Bugs:

  • Small asteroids are hard to explode. The bullets travel "through" them between repaints, so they never actually collide. I may fix this in the future.

Click here to download the full source to Sensory Overload.

Click here to download the Sensory Overload CAB file to play the game.

.NET Compact Framework wrapper for OpenGL ES

OpenGL Test

Around a year ago today, I began writing an extensive UI framework for Windows Mobile. It turned out great, however I continually run into the limitations and performance issues of GDI/GDI+ on mobile devices. One of the steps I wanted to take into really improving performance was to utilize the hardware acceleration that we will begin to see in the new wave of Windows Mobile devices; in my case the HTC Touch Diamond.

The first step towards that end is to utilize one of the two 3D APIs available on the Windows Mobile platform. Direct3D Mobile .NET was not a reasonable option: it has limited support and is supposedly being phased out in Windows Mobile 7. In addition, the D3DM implementation on the HTC Touch Diamond is a just a wrapper around OpenGL ES... I find it a little distasteful that than an operating system specific 3D API is actually just a wrapper around a cross platform 3D API, hehe. And on the other hand, OpenGL ES does not have a managed API.

In My Humble Opinion, UI development should generally be in managed code. Although unmanaged code undoubtedly provides superior performance, the developer sacrifices too much of the ease and speed of managed development.

For that reason, I've started work on a managed wrapper for OpenGL ES: I now have a working set of wrappers for OpenGL ES. I won't take all the credit though. Most of the PInvokes were mass imported via the PInvoke Interop Assistant written by Jared Parsons.

The screen shot above is of the sample "Hello World" application written in Managed OpenGL ES. The code download includes the full source for the wrapper and the sample.

For those wanting to learn OpenGL, I highly recommend reading the NeHe OpenGL series. It's the best OpenGL tutorial on the Internet; I've practically had it book marked for 8 years.

Future work will include converting the various OpenGL constants into enums (I.e., GL_TRIANGLES, GL_TEXTURE0, etc) so that arguments are not so loosely typed.

Notes:

  • The sample uses floating point math, so not all devices may support it.
  • If your device does not have an implementation of OpenGL ES (hardware or software), you can get the free software implementation, Vincent 3D. Just drop the libgles_cm.dll into your \Windows directory. Vincent 3D is a fixed point implementation, so it does not support the sample either. I will probably convert the sample to fixed point eventually.

Windows Mobile Bar Code Manager and API

While I was checking out of the grocery store tonight, I realized I had left my "preferred savings" card in my car's glove compartment as usual. Naturally, my train of thought derailed into Windows Mobile development and how I could make my life easier. The answer was simple: why can't I save all my bar codes into a program and have the cashier scan the image from my cell phone? It would save wallet space and be really cool to boot!

After a quick investigation into how bar codes work, I began coding. The end result is the following:

barcode barcodeedit

Above, I have two of my grocery cards entered into my Bar Code manager. In the editor screen, one can enter a bar code number and view it in real time.

The API (BarCode.dll) is simple:

  1. Create a BarCodeSerializer object.
  2. Set the DisplayNumber property to your bar code number you want to process.
  3. Use the IsValid property verify it is a valid 12 digit bar code.
  4. Use the MakeValid property to make a valid 12 digit bar code from an 11 digit number. Some cards only show 11 of the 12 digits. The 12th is used as a "check" digit.
  5. Use the CreateBitmap method to create a bitmap of approximately the desired dimensions.

In a possible future release, I might extend the bar code manager to take a picture with a high resolution camera and import a bar code number. That would be an interesting computer vision problem!

Download the Bar Code Manager and API here.

Another Klaxon Release

As promised, I implemented more bug fixes and features for this release. Download Klaxon here.

  • The light sensor will only turn off your alarm if the phone is face up. This fixes the issue where the alarm gets shut off if the phones if flipped face down to snooze.
  • If the phone is snoozing, a sensor can not be used to turn the alarm off. The off button must be manually pressed. This is a precaution to ensure the phone doesn't get erroneously turned off.
  • The shake off function is implemented differently now: if at any point, the phone is subject to 20 G's of force, it will turn off. Previously, it was using an orientation change count. The G measurement method is much more reliable.
  • As a silent confirmation, the phone will vibrate once if you put it into Snooze mode. It will Vibrate twice if you turned it off.
  • All the sensor actions are configurable: you can now manually configure what you want the alarm to do when you shake it, flip it, or turn on the light.
  • Implemented some of the UI clean up changes. This includes bigger Vista style check boxes and radio buttons.
  • Implemented an About box which gives you information about your Klaxon version and the author.
  • Fixed a bug where the registry entries were not being deleted properly when an alarm was deleted.
  • Fixed a bug where the device would go to sleep after a Snooze and not wake up to alarm the user.
  • Fixed a bug where the Delay setting was not being saved after editing it.

New Klaxon Release

This new version addresses has the following improvements and fixes:

  • Fixed the bug where the alarm would not immediately fire if the device is in "Sleep" mode.
  • Fixed a bug where the screen would not light up when the alarm fired.
  • Introduced a new Audio Delay feature. Klaxon will now try to wake the user using only the back light for the designated time period. If the user does not snooze or turn off the Klaxon, the alarm will then go off.
  • AppToDate support.
  • Implemented the Light Sensor shut off: When the alarm starts, Klaxon samples the ambient light. If the light ever increases beyond a certain range from that ambient light, Klaxon will shut off the alarm automatically.

CeRunAppAtTime, CeSetUserNotificationEx, Connection Manager Process Scheduling and how they are affected by Power States in .NET Compact Framework

After releasing the first version of Klaxon, several users reported that Klaxon was not starting at the designated time if the device was sleeping: often several minutes late, or not at all.

My implementation of process scheduling was using Connection Manager. At first I thought the device going to sleep was disabling all the active connections, so the event would not fire. I switched the implementation to use CeRunAppAtTime, and still encountered the same problem. CeRunAppAtTime is deprecated and there were several blog posts describing the various issues people had with it. I then switched the implementation again; this time to use CeSetUserNotificationEx, which is the new hotness in process scheduling. Still the same issue. I did notice something peculiar however: if I scheduled the event with a System Notification Dialog (like a calendar event), it would work.

In all 3 implementations, Klaxon would launch immediately after the device was turned on. Another oddity was that the Klaxon form loaded was almost instantaneously, when generally it has a 5-6 second when I launch it via the Programs list. This led me to believe that it was actually launched and resident, but the device was then somehow put back into suspension. Turns out I was right. There are a few well hidden forum posts which document this issue.

Basically, if the device is not explicitly set to a "power on" state within a few seconds of going into the "resuming" state, it goes back into a suspended state. So the fix is to call SetSystemPowerState, which looks like the following:

using System;
using WindowsMobile.Utilities;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

namespace Klaxon
{
    static class Program
    {
        [DllImport("coredll.dll")]
        extern static UInt32 SetSystemPowerState(String pwsSystemState, UInt32 StateFlags, UInt32 Options);
        const UInt32 POWER_STATE_ON = 0x00010000;
        const UInt32 POWER_FORCE = 0x00001000;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [MTAThread]
        static void Main(string[] args)
        {
            SetSystemPowerState(null, POWER_STATE_ON, POWER_FORCE);
            Run(args);
        }

        static void Run(string[] args)
        {
            InteractiveService.Run(args, typeof(AlarmListForm), new ThreadStart(KlaxonService.Run));
        }
    }
}

Note that I am not calling the InteractiveService.Run in the Main method. This is because when Main is called, all types that it references will have their respective assemblies loaded. In my case, this would be System.Windows.Forms, WindowsMobile.Utilities, and a few others. This would add to the "spin up" time and risk the device being put into suspension before SetSystemPowerState is called.

Klaxon: Windows Mobile G-Sensor and Light Sensor Enabled Alarm Clock

klaxon

I mentioned a post ago that I was working on this. Well it's getting close to completion, and wanted to provide people something to give some feedback on. Right now the finishing touches are in the artwork. Beyond the first screen, the buttons and artwork are really ugly!

You can download Klaxon here.

Using Klaxon is pretty straightforward; it's more or less like the standard Clocks and Alarms application.

G-Sensor Instructions:

  • Flip your phone over to snooze.
  • Shake your phone to turn the alarm off.

Not yet implemented:

  • Artwork (I need to create pretty images to use for buttons)
  • Turn off the alarm if the light comes on in the room (using the Light Sensor!)
  • Turn on the phone light for 15 seconds, so you have a chance to turn off the alarm before it goes off.