We had another very curious incident, this time on an Intermec terminal. Each time the terminal scanned a barcode our application would immediately exit.Â No warning, no exception, nothing but an immediate exit.Â And it wasn’t even a complicated application, just a simple prototype.
What made this even more curious was that it didn’t happen on all of our Intermec terminals and hadn’t occurred in the past with our other customers.Â Â AÂ few more details will make the problem a little clearer.Â First of all we are developing in .NET CF 2 with VS.NET 2005 and our SNAP application framework.Â The Intermec 760B terminal is runningÂ Pocket PC 2003 (OS 4.51 Premium with PSM 3.93.1 for 32MB Flash)Â and the Intermec 2.4 IDL.
SoÂ it was a matter of rolling up our sleeves and getting down in to the bowels of the source code.Â Initially we suspected that there was an exception in the scanner dll causing the application to abort.Â We tried the usual tasks such as walking through the code (difficult since scanning is event driven), and catching exceptions on invocation instead of where they are caught, all to no avail.Â Finally, it was a matter of controlling the scanning to catch the error, where we found a Windows Message conflict, essentially programmatically triggering the scanner to control the execution in the debugger.
Apparently Intermec has implemented their scanner code using messages and happened to assign the sameÂ Window Message ID (WM_USER+1 = Â 0x401)Â thatÂ we were using forÂ exiting a sequence of forms (in this case out of the application).Â And that’s the end of the application.
So whatÂ does that mean.Â The first thing one could argue is that a system object like thisÂ should notÂ expose the window messages to the application, or at least not use one that is quite so common.Â And I’d think you’d have a pretty good argument there.Â
So the simple solutionÂ is that rather than using WM_USER as our Message ID base, we could use a value that is unique within the system.Â The easy way to do this is to register the window message with the OS and request a unique id.Â Simply use the method:
[DllImport("CoreDll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern uint RegisterWindowMessage(string lpString);
static uint WM_MY_MSG = // use RegisterWindowMessage to ensure unique
Of course this isn’t 100% perfect since you canÂ still have people using the same string to register their message.Â To take it the next step you can create a GUID, but I think that’s getting a bit much.Â Just use a reasonable unique name and everything should be fine.Â
- Message Management: http://www.developerfusion.co.uk/show/1713/1/Â (This is a very nice overview of handling Window Messages).
- Intermec IDL: http://www.intermec.com/idl/
- Microsoft Doc for RegisterWindowMessage: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/html/cerefRegisterWindowMessage.asp