Loring Software, Inc

A Software Developer's Notebook
I just landed a great little project. It is the first time I have developed for the Compact Framework, although I had some grand schemes brewing for it about 5 years ago. This job involves a Motorola 9090 Scanner with a Windows Mobile device on it, and an app to scan, store in a Compact DB, and talk to some web services. Just the stuff I love. And the development environment is great, alebit a bit slow. I tested with the emulator for a while because the device wouldn't connect to my laptop. I never figured out why, but when I finally attached it to a workstation, I couldn't believe my eyes when I hit F5 and the dang thing not only deployed to the device, but actually stopped at a breakpoint. I guess things have changed since the days of Newton development.

So, on the whole Microsoft has done a fine job with this device. You've got C#, pretty much the whole .Net framework, a SQL server, and even multi threading, all on a tiny handheld. Development time is only slightly slower than with a normal desktop app. It is a shame it is losing market share.

One problem I encountered which took ages to solve was a missing WaitCursor. I looked high and far for anyone out there with the same problem, reading probably two dozen posts, trying a few of them, and almost giving up and writing an async window process to take the cursor's place. I finally figured it out on my own, so I hope this post finds its way out there to help someone else.

Here's the problem: In a number of places in my code, I have to run through a number of tasks, and conditionally open another form, close it, and carry on. For example:

if (a_result != DialogResult.Cancel)
{
  
Cursor.Current = Cursors.WaitCursor;
  
if (LoginForm.WaitForValidLogin())
  
{
      
new CreateOrderForm(a_orderToStartWith).ShowDialog();
  
}
  
Cursor.Current = Cursors.Default;
}

In the above code, I have to wait to see if the user's credentials are actually valid before carrying on (I let them log in with stored credentials while an async web service goes out to really validate the credentials -- 99% of the logins will take half the time).  This wait can take a while, and so can the startup code in the Dialog (initializer and Load).  At a glance, this all looks to make sense.  When the form finally does open, the WaitCursor is gone, which is good (of course), so I figured the OS was smart enough to switch it out, and that was that.  And my Cursor.Current = Cursors.Default is for all intents and purposes a no-op when it returns, but I need it there for the case when the WaitForValidLogin returns false.

The problem, it turns out, is that any attempt (or, rather, most attempts -- sometimes it works) to show a wait cursor in the opened window just plain fail.  I spent the whole time looking for reasons that those calls to Cursor.Current = Cursors.WaitCursor were failing.  Was the process too quick (no, some were many seconds), was it a DB call, or a web service?  All were red herrings.  I amost got sucked into making PInvoke calls.  The problem was that, once the WaitCursor was set, and the ShowDialog was called, it just wouldn't show any others until it returned.  So, I changed the code to:

if (a_result != DialogResult.Cancel)
{
  
Cursor.Current = Cursors.WaitCursor;
  
if (LoginForm.WaitForValidLogin())
  
{
       Cursor.Current = Cursors.Default;
      
new CreateOrderForm(a_orderToStartWith).ShowDialog();
  
}
  
Cursor.Current = Cursors.Default;
}

and all was good in the universe again.



Copyright © 2024 Loring Software, Inc. All Rights Reserved
Questions about what I am writing about? Email me