Brothers In Code

...a serious misallocation of .net resources

Events in Global.asax Do Not Fire - Did You Forget to Drop the File?

I was working in a web service project where by default, the codebehind is compiled into a single dll.  I didn't expect to need the Global.asax file that went with it's corresponding .cs file, but it turns out that the events won't fire without it.

Unwanted Assembly/EXE Sharing in Windows Mobile

I just got done merging two Windows Mobile applications into one and a user complained that the combined version was missing a feature of one of the original apps.  As I set out to prove him wrong I bumped into something very wierd.  I set a breakpoint in the event in the old app that I was expecting to check and nothing happened.  The form in the app did absolutely nothing.  However, I was pushing all http traffic from the mobile device thru fiddler and I could see that the form was hitting the webservice that the new combined app was supposed to be using.  The device also gave the beep code I had programmed in after a successful operation.  I put a breakpoint in a couple of other methods like Form.Load and Form.Close and even a couple of Button.Click events and those I was able to debug.  I wasn't loading any assemblies in the GAC but even if I was I couldn't explain this partial debugging ability.  The new app was on the device but it was in a separate folder so at first I disregarding the possibility that I was getting some sort of cross contamination.  But then I thought what if the other app is actually running?  Sure enough, after checking task manager, I could see the new app was running in the background and killing it let me debug the old app.  How did this happen?  The classes do have the same namespace and name but I've never heard of an app sharing another app's code in memory.

Wrong Tab Order in Windows Mobile

I had a form that didn't seem to want to follow the TabIndex that I had set on a number of controls.  The cursor jumped around passed controls with a lower index and then would come back to them later.  The difference between this form and others was that this form had a panel on it that hid a couple of controls until they were displayed upon the click of a radio button.  I did notice that if I deleted the controls and recreated them in the order I wanted them to tab, they would tab correctly.  However, starting over is a lousy fix so I dug into it a bit deeper.  After debugging I found that the TabIndex on the controls within the panel were being reset.  It also turns out that even though a Panel control has no mention of a TabIndex property in the Properties pane or with intellisense, it does in fact have that property.  Setting the Panel's TabIndex in the form load event fixed the issue for me.  To make it so I wouldn't get bit by this again,  I set the panel's TabIndex to the index of the first control in the panel.

B

Catching 'Thrown' Exceptions in Visual Studio

Every once in a while I'll have an app crash without any warning at all.  One minute it's there, one minute it's not.  No exception message, no break in visual studio while debugging, nothing.  Each time this happens I just allow visual studio to catch 'thrown' exceptions rather than just 'user-unhandled' exceptions.  This means that visual studio will break right at the time it occurs, rather than letting it bubble up to see if it will be handled later in the code.  Go to File>Debug>Exceptions and check the 'Thrown' boxes...

Event-Based Keyboard Wedge Scanner

I just came off a project programming Motorola barcode canners based on Windows Mobile.  The Motorola/Symbol API was top notch and provided access to everything I needed.  This included an event driven API for the scanner.  This meant I had a nice "Scan" event to use from within my code rather than rely on simple keyboard emulation.  This great when a single barcode had multiple fields of data.  I could parse everything behind the scenes without using a "capture" field on my forms.

The next project also needed a barcode scanner but would be a Winforms app rather than a mobile app.  To my surprise the APIs for these usb and serial scanners were not nearly as good.  Only a select few scanners supported Motorola's usb SNAPI interface, and there was no native .net support there (just a bunch of DllImports).  Others had an RS232 based interface but it wasn't much better than reading raw data from the serial port.  A few of the scanners supported the OPOS standard which means I could have used POS for .net but that seemed overkill for my needs.

Finally I realized there was a much simpler solution.  Most of these scanners supported a keyboard emulation mode.  More importantly they supported the ability to be programmed to include prefixes and suffixes in the scan.  While most would use this feature to send an 'Enter' after a successful scan, I realized I could use this to send special characters to indicate the start and end of a scan and separate it from normal keyboard input.  From there making my own API was simple.

There were two main points to this.  The first was to monitor keypresses:

HostForm.KeyPreview = true;
this.enabled = true;
if (this.enabled)
{
  HostForm.KeyPress += new KeyPressEventHandler(KeyPressHandler);
}
else
{
  HostForm.KeyPress -= KeyPressHandler;
}

The line of interest here should be the Form.KeyPreview=true.  This allows you to pickup keyboard strokes at the form level rather than from the control with focus.

From there it's just a matter of looking for the started and ending characters (i chose ctrl-s and ctrl-t, ascii char 19 and 20 resp):

public void KeyPressHandler(object sender, KeyPressEventArgs e)
{
  //if a scan has started...
  if (!IsScanning && e.KeyChar == ScanStartCharacter)
  {
    IsScanning = true;
    timeoutTimer.Start();
    e.Handled = true;
    OnScanStarted();
  }
  //if a scan is in progress and is not being terminated...
  else if (IsScanning && e.KeyChar != ScanEndCharacter)
  {
    timeoutTimer.Stop();
    //...then add the char to the buffer
    scanBuffer.Append(e.KeyChar);

    timeoutTimer.Start();
    e.Handled = true;
  }
  //if a scan has ended
  else if (e.KeyChar == ScanEndCharacter)
  {
    timeoutTimer.Stop();

    CompleteScan(false);

    e.Handled = true;
  }
  else  //not scanning, pass the character on as keyboard input.
  {
    e.Handled = false;
  }
}

I threw a timer in there just to make sure the scan eventually completes, even if the user forgets to program the suffix into the scanner.

That's pretty much it.  The full code is attached.