# Monday, September 27, 2010

Are you missing Compact Framework (not Windows Phone, but everything else) support in Studio 2010?  Let Microsoft know and vote here.

Monday, September 27, 2010 11:33:49 AM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, September 24, 2010

I've made a small update to the ORM library.  I've added a SQLite assembly and started implementeing the SQLiteDataStore class.  Note that I say "started" meaning that it's not done and ready for use (far from it in fact).  I did do a rough pass for store (database and table) creation.  The idea is that it gives at least some seed code for anyone interested in getting ORM up and running on their Windows Phone using SQLite.  If you are interested in doing this, please let me know.  I don't really have the time to devote to getting this done, so I'm looking for a capable developer who would like to take this on.

Friday, September 24, 2010 9:05:53 AM (Central Daylight Time, UTC-05:00)  #     | 
# Monday, September 20, 2010

I've been developing for Windows CE for a while now, and generally speaking I've seen just about every class of business problem that people might run into.  Or so I thought.

I had a request from a client who wanted to change the default mouse cursor on their device for their solution.  The challenge was that their solution consists of not just one application, but two, and one is a managed application.

Initial research on the web said that this would be fairly easy.  Just put the cursor file out in the file system somewhere, then have each app load it up at runtime.  If only reality were that simple. 

It turns out that Windows CE is substantially limited in its ability to handle cursors.  The big problem is that LoadCursorFromFile, which is exactly what I needed, flat out doesn't exist in Windows CE.  The managed Cursor class also doesn't have a constructor that takes in a filename (likely because of the lack of that API).  I message around a bit trying to load a Bitmap and use the HBITMAP in some cursor calls, but every step led me to a dead-end.  So after an hour or two of doing nothing but exploring and ruling out options, I decided that maybe I'd accept a limitation that the cursor would have to be embedded as a resource in a native DLL.

Of course this still wasn't super straightforward or simple either. LoadImage can only load an image from a compiled resource file by name.  Of course EnumResourceNames, which you might use to get a resource name, doesn't exist either.

My first goal was to just get the cursor changed for the Form.  I assumed that the cursor would likely not be correct for child controls like TextBoxes, but really, baby steps are fine.  I used LoadLibraryEx to load up the native DLL, followed by LoadCursor to load the cursor resource by ID, then finally a call to SetCursor.

My initial test were returning valid (i.e. non-zero) return values but the cursor would change only briefly.  As soon as I moved the mouse, the cursor would revert to the default.  A little more research and I came across this gem in the MSDN remarks for SetCursor:

"If your application must set the cursor while it is in a window, make sure the class cursor for the specified window's class is set to NULL. If the class cursor is not NULL, the system restores the class cursor each time the mouse is moved."

That sounded a whole lot like the behavior I was seeing.  A little more searching and I came to the conclusion that I needed to call SetClassLong with GCL_HCURSOR.  This required that I give a pointer to the loaded cursor, so I have to move the results of LoadCursor to a broader scope, but once I'd done that, bingo!  The cursor was my custom cursor when on the Form. (I wanted to put a screen shot in this post here, but screen captures on the device omit the mouse cursor, so it's not terribly interesting.)

So now the goal was to get it to not change when I moved over another Control.  Again it was time to do more research.  It turns out that it could be done for each control class (so all TextBoxes, all Forms, etc) but that would mean I'd have to iterate through all of these types and set it.  And who knows what a custom or user control might turn up.  That just seemed risky and kludgy to me.  What are my other options?

It seems that if you handle the WM_SETCURSOR message for a control, you can override the default behavior to set the default cursor.  So all I had to do was subclass my Form.  Of course that's not 100% straightforward with the Compact Framework.  You can't just override WndProc like you can on the desktop, but still it wasn't groundbreaking territory and I'd done it before.  I ended up creating a simple Subclasser class that you could attach to a Form, then in it load up your cursor (using the code I'd done before) and then just call SetCursor with my desired cursor instead of the default.

The end result worked perfectly.  The source code for the work can be downloaded here: CursorTest.zip (9.15 KB) (the native source that holds the actual cursor is here: Cursors.zip (12.56 KB))

Some other thoughts I have on this that I leave to the ambitious:

  • I think you could probably use a similar technique to the Form subclass to do an application-wide cursor replacement using an OpenNETCF.Windows.Forms.IMessageFilter implementation, but I've not tested that.
  • This is going to kill your wait cursor, so if you want/need one, you're going to have to plumb in support for that
  • If you want to have multiple custom cursors (if you want to have a custom Form and a custom TextBox for example), then you're probably going to have to add support for that if you use the subclassing technique.
  • I've noticed that when you click a Button and it redraws, it appears to draw over the cursor until you move the mouse again, so this needs to be looked into.
Monday, September 20, 2010 3:17:05 PM (Central Daylight Time, UTC-05:00)  #     | 
# Thursday, September 16, 2010

I'm a big fan of writing less code or even actively deleting existing code.  Less code means less bugs, and who doesn't like shortcuts to getting around writing mind-numbing, repetitive code?  One place that I find a whole lot of repetition in my code is in calling event delegates.  Before calling an event delegate you always have to make sure it's not null, and a generally accepted practice is to make a copy of the delegate in case a subscriber unhooks the event after you've checked.  So a typical call to raise an event looks like this:

virtual void OnMyEvent(EventArgs args)
{
    var handler = MyEvent;
    if (handler != null) 
        return;

    handler(this, args);
}

Sure, it's small enough, but when you have a lot of events in a large solution, you have a whole lot of repetitive code.  Admit it - you've used CTRL-C/CTRL-V to copy this for a new event. There's got to be a better way, right? 

Well how about an extension method (well a pair, since you might have EventHandler<T>)?

public static class EventHandlerExtensions
{
    public static void Fire(this EventHandler h, object sender, EventArgs args)
    {
        var handler = h;
        if (handler == null) return;
        handler(sender, args);
    }

    public static void Fire(this EventHandler h, object sender, T args) where T : EventArgs
    {
        var handler = h;
        if (handler == null) return;
        handler(sender, args);
    }
}

Once you've done this your code becomes a simple one-liner:

virtual void OnMyEvent(EventArgs args)
{
    MyEvent.Fire(this, args);
}
Thursday, September 16, 2010 9:24:41 AM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, August 27, 2010

I've re-released the OpenNETCF.ORM library.  In my haste to port the code out of the production environment I'm using it in back to the Codeplex tree, I missed a file removal.  This broke the Codeplex release and, of course, I didn't check it before publishing the release.  I've rectified the problem and everything in Codeplex should now build.  If it doesn't send me an email or add a bug to the project to let me know.

Friday, August 27, 2010 10:28:56 AM (Central Daylight Time, UTC-05:00)  #     |