Click here to Skip to main content
14,383,744 members

How to Easily set up a Textbox to Accept Scans from Motorola/Symbol Barcode Scanners in Windows CE / .NET CF Projects

Rate this:
4.94 (9 votes)
Please Sign up or sign in to vote.
4.94 (9 votes)
19 Jan 2015CPOL
Step-by-step guide to add barcode-scanning capability to a Windows CE / Compact Framework app

Barcode Scanning (I couldn't think of a cleverer subheading)

So you wanna (more likely, need to) input some scanned data into a textbox on a form. It's not all that rocket-sciencey. Here are the steps:

First, reference the following two DLLs in your project:

  • Symbol
  • Symbol.Barcode

...which DLLs should be included along with your device; otherwise, they should be available from the Motorola site here or over yonder, although I couldn't find them (I didn't search all that hard since I already had about a gazillion copies of them on my PC).

Add these DLLs to the folder on your handheld device where your app resides, too.

Note: This code has been adapted from Motorola's CS_ScanSample1 sample project; basically, I de-nerdified some of the names of objects and methods (or super-nerdified - YMMV) and wrote the scanned value into a textbox. Also, instead of responding to a button click to start the scanning (as the demo app does), I used the textBox's GotFocus() event. And to stop the scanning, I set focus to the next control on the form after the data has been written to the textbox. This, in turn, calls the textbox's LostFocus() method for some cleanup code.

So, you can use this code as-is, with the exception that you will want to rename the textbox that will receive the scanned value ("textBoxUPC_PLU") and the next control where focus is set ("textBoxPackSize") to controls that make sense in your case.

The Code (I'm still suffering from a Brain Freeze, Catchy-Subheading-Wise)

Now for the code; add these members to your form:

private Symbol.Barcode.Reader barcodeReader;
private Symbol.Barcode.ReaderData barcodeReaderData;
private EventHandler barcodeEventHandler;

Then add this code:

private bool InitReader()
{
    // If reader is already present then retreat
    if (this.barcodeReader != null)
    {
        return false;
    }

    // Create new reader, first available reader will be used.
    this.barcodeReader = new Symbol.Barcode.Reader();

    // Create reader data
    this.barcodeReaderData = new Symbol.Barcode.ReaderData(
        Symbol.Barcode.ReaderDataTypes.Text,
        Symbol.Barcode.ReaderDataLengths.MaximumLabel);

    // Create event handler delegate
    this.barcodeEventHandler = this.BarcodeReader_ReadNotify;

    // Enable reader, with wait cursor
    this.barcodeReader.Actions.Enable();

    this.barcodeReader.Parameters.Feedback.Success.BeepTime = 0;
    this.barcodeReader.Parameters.Feedback.Success.WaveFile = "\\windows\\alarm3.wav";

    // Attach to activate and deactivate events
    this.Activated += ReaderForm_Activated;
    this.Deactivate += ReaderForm_Deactivate;

    return true;
}

private void StartRead()
{
    // If we have both a reader and a reader data
    if ((this.barcodeReader != null) && (this.barcodeReaderData != null))
    {
        // Submit a read -- I sometimes got an exception about a read already being pending here, so:
        if (this.barcodeReaderData.IsPending) return;
        this.barcodeReader.ReadNotify += this.barcodeEventHandler;
        this.barcodeReader.Actions.Read(this.barcodeReaderData);
    }
}

private void BarcodeReader_ReadNotify(object sender, EventArgs e)
{
    Symbol.Barcode.ReaderData TheReaderData = this.barcodeReader.GetNextReaderData();

    if (TheReaderData.Result == Symbol.Results.SUCCESS)
    {
        // Handle the data from this read
        this.HandleData(TheReaderData);
        // Start the next read
        this.StartRead();
    }
}

private void ReaderForm_Activated(object sender, EventArgs e)
{
    // If there are no reads pending on barcodeReader start a new read
    if (!this.barcodeReaderData.IsPending)
    {
        this.StartRead();
    }
}

private void ReaderForm_Deactivate(object sender, EventArgs e)
{
    this.StopRead();
}

private void StopRead()
{
    // If we have a reader
    if (this.barcodeReader != null)
    {
        // Flush (Cancel all pending reads)
        this.barcodeReader.ReadNotify -= this.barcodeEventHandler;
        this.barcodeReader.Actions.Flush();
    }
}

private void DisposeBarcodeReaderAndData()
{
    // If we have a reader
    if (this.barcodeReader != null)
    {
        // Disable the reader
        this.barcodeReader.Actions.Disable();
        // Free it up
        this.barcodeReader.Dispose();
        // Indicate we no longer have one
        this.barcodeReader = null;
    }

    // If we have a reader data
    if (this.barcodeReaderData != null)
    {
        // Free it up
        this.barcodeReaderData.Dispose();
        // Indicate we no longer have one
        this.barcodeReaderData = null;
    }
}

private void HandleData(Symbol.Barcode.ReaderData readerData)
{
    textBoxUPC_PLU.Text = readerData.Text;
    // now move off of it to next non-read-only textBox
    textBoxPackSize.Focus();
}

In HandleData(), replace "textBoxUPC_PLU" with the name you've given your TextBox control. Similarly, replace "textBoxPackSize" with the name of the next control you want to get the focus after scanning is complete.

Note: In my case, the code in DisposeBarcodeReaderAndData() was actually causing NREs; in at least one scenario, I had to comment out that code. YCEMV (Your Coding Experience May Vary).

Delayed Dispatch from the Trenches

I find that this is helpful/necessary when closing a form that does barcode scanning:

private void FrmDelivery_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    this.barcodeReader.Actions.Disable();         
}

This seems to allow subsequent forms to use barcode scanning (see my multiple-times-updated question here for the gory details of the problems I was having in attempting to do so).

More Crash Prevention

It turns out that calling barcodeReader.Actions.Disable() crashes the app if no scan was done. To ameliorate, adjudicate, and alleviate (but not anthropomorphize) this, we have to keep track of whether a scan was done.

So, being the neanderthalic brutish modified Luddite that I am, I simply added a bool to the form like so:

private bool scanWasDone;

...and then set that to true in the InitReader event (several events are fired when a scan is done, but this appears to be the first and functions (no pun intended) as good as any of them for this purpose):

private bool InitReader()
{
    scanWasDone = true;
	. . .

Finally, in the form's Closing event, only call Actions.Disable if a scan was done:

private void frmVerify_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    // Calling disable is necessary if a scan was done, but it crashes the app if no scan was done
    if (scanWasDone)
    {
        this.barcodeReader.Actions.Disable(); 
    }
}

Kudos and Cavalier Caveats

The above is pretty much the same as the Symbol sample code, except that I renamed things like "myEventHandler" to "barcodeEventHandler". I don't know why, but prepending "My" to software objects, methods, &c has always irked me (admittedly, way more than it should) and sounds to me like baby talk (goo goo, ga ga, etc.). I also changed the method name "TermReader" (which sounds like somebody is going to clamber up on a soapbox and regale an unsuspecting captive audience with the reading aloud of their term paper) to "DisposeBarcodeReaderAndData". Maybe you prefer the former; of course, you can name it "WhichIsYourFavoriteTrio_TheThreeMusketeersOrTheThreeLittlePigs" if you want to (but don't be a Dumas -- only do this if you are absolutely certain that those who might maintain your app in the future don't know where you live).

Notice, also, though, that I did add some my-form-specific code to the HandleData() method:

textBoxUPC_PLU.Text = readerData.Text;
// now move off of it to the next non-read-only textBox
textBoxPackSize.Focus();

I assigned the read data to the texbox set up to be responsive to the barcode scanner, and then I moved the cursor to the next control (which causes the LostFocus() / cleanup code to run).

Now that you've got that code, you can add the handler code to the textBox that makes this the "barcode-scan-responsive" control; first, there's the GotFocus() event:

private void textBoxUPC_PLU_GotFocus(object sender, EventArgs e)
{
    if (this.InitReader())
    {
        this.StartRead();
    }
}

...and next/finally is the textBox's LostFocus() event, which will do the requisite cleanup:

private void textBoxUPC_PLU_LostFocus(object sender, EventArgs e)
{
    this.DisposeBarcodeReaderAndData();
}

Und Damit Basta! (That's not Cussing, it's German)

Aha! Voila! Eureka! Woo-hoo! Yee-haw! Great Day in the Mornin'! (it works). While in the textBox that has been set up to receive scanning (textBoxUPC_PLU), if I scan an item, its value is entered into the textBox, and focus is then moved to the next textBox.

This was tested on a Motorola 3190 and a Windows CE project with the affiliated stripped-down version of .NET 3.5 (Compact Framework), using Visual Studio 2008. I reckon the code would also work in even feebler versions of .NET / CE / CF, and doubtless on other Motorola/Symbol devices.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

B. Clay Shannon
Founder Across Time & Space
United States United States
I am in the process of morphing from a software developer into a portrayer of Mark Twain. My monologue (or one-man play, entitled "The Adventures of Mark Twain: As Told By Himself" and set in 1896) features Twain giving an overview of his life up till then. The performance includes the relating of interesting experiences and humorous anecdotes from Twain's boyhood and youth, his time as a riverboat pilot, his wild and woolly adventures in the Territory of Nevada and California, and experiences as a writer and world traveler, including recollections of meetings with many of the famous and powerful of the 19th century - royalty, business magnates, fellow authors, as well as intimate glimpses into his home life (his parents, siblings, wife, and children).

Peripatetic and picaresque, I have lived in eight states; specifically, besides my native California (where I was born and where I now again reside) in chronological order: New York, Montana, Alaska, Oklahoma, Wisconsin, Idaho, and Missouri.

I am also a writer of both fiction (for which I use a nom de plume, "Blackbird Crow Raven", as a nod to my Native American heritage - I am "½ Cowboy, ½ Indian") and nonfiction, including a two-volume social and cultural history of the U.S. which covers important events from 1620-2006: http://www.lulu.com/spotlight/blackbirdcraven

Comments and Discussions

 
QuestionSymbol in Motorola MC9500 Pin
Member 117928118-Jul-19 6:16
memberMember 117928118-Jul-19 6:16 
QuestionAre you still here??? Pin
Member 142195328-Apr-19 2:38
memberMember 142195328-Apr-19 2:38 
QuestionProblem with MC92N0 model Pin
miguel_2-Feb-18 11:03
membermiguel_2-Feb-18 11:03 
PraiseEXCELLENT Pin
Laurent.iss2-Oct-17 14:01
memberLaurent.iss2-Oct-17 14:01 
QuestionPlease Help Me. Pin
sofianm_vb_net9-Aug-16 1:11
membersofianm_vb_net9-Aug-16 1:11 
Questionread barcode one character at Pin
hendaviher6-Apr-16 19:20
memberhendaviher6-Apr-16 19:20 
QuestionUnable to Download .dll Pin
PRASHANTPTL11-Mar-16 1:42
memberPRASHANTPTL11-Mar-16 1:42 
QuestionAndroid studio Pin
Member 1136150429-Sep-15 5:38
memberMember 1136150429-Sep-15 5:38 
AnswerRe: Android studio Pin
B. Clay Shannon29-Sep-15 5:56
professionalB. Clay Shannon29-Sep-15 5:56 
GeneralRe: Android studio Pin
Member 1136150429-Sep-15 8:14
memberMember 1136150429-Sep-15 8:14 
QuestionTaking it another step Pin
steveninnewton31-Aug-15 12:55
membersteveninnewton31-Aug-15 12:55 
AnswerRe: Taking it another step Pin
B. Clay Shannon31-Aug-15 13:07
professionalB. Clay Shannon31-Aug-15 13:07 
GeneralRe: Taking it another step Pin
steveninnewton1-Sep-15 10:19
membersteveninnewton1-Sep-15 10:19 
QuestionThanks! Pin
Member 118926976-Aug-15 23:55
memberMember 118926976-Aug-15 23:55 
AnswerRe: Thanks! Pin
B. Clay Shannon7-Aug-15 5:25
professionalB. Clay Shannon7-Aug-15 5:25 
QuestionUnable to download .dll Pin
Basmeh Awad11-Jan-15 20:35
professionalBasmeh Awad11-Jan-15 20:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Tip/Trick
Posted 20 Nov 2014

Tagged as

Stats

44.7K views
23 bookmarked