hi friends ..

i've noticed that many pos applications that allow the use of a barcode reader device is designed in a way so that there is a textbox on the pos window that is supposed to be used to receive the scanned barcode.

this approach has a main crippling feature. the barcode textbox should be the one with the focus before scanning the barcode, otherwise the loaded barcode characters will be useless or may mess around other controls.

another feature is that in most of the barcode readers the default suffix (the last character in the loaded barcode) is {enter} key + a line feed, or a suffix of {tab} character. this will result in that after reading the code, the barcode textbox will lose the focus.

therefor, developers play around these features to keep the barcode textbox always in focus to ensure correct input and at the same time add codes to keep it focused after reading the code, to allow for the next item barcode be loaded correctly.

i believe that this way of development produce a less flexible interface and less user friendly.

my approach:

the way i deal with the use of barcode readers to have a more flexible (and smartly behaving) application is based on the following:

1) the configuration of the barcode reader:

the barcode reader has a vast number of configurable parameters (independent on the computer). each type of barcode readers has a user manual that contain the codes to program and configure the barcode reader. so that the reader is configured just by scanning some special barcode codes that the reader identify as a configuration process. of these parameters, two i used to apply my idea: the prefix and the suffix.

a common default way of loading the barcode is like this example:

actual barcode: 6281101220014 (small bottled water smile [:)])
the sent code: 
6281101220014{enter}+line feed or 6281101220014{tab}

(this is just to represent what is received, it is not actual code, the actual code is every number is send as ascii character and added to it ascii char 13 (for enter) + char 10 (for line feed), or 9 (for tab))

my idea will be based on adding a predefined prefix to the loaded barcode (this is done by the barcode reader) so that this prefix will be trapped by the form and after which the ascii codes received will be regarded as the actual barcode. then comes the suffix (i use the tab), so when the form trap a tab while it is in the mode of reading the barcode, it will consider that the barcode string is complete and ready to be processed.

the selected ascii character to be a prefix could be an uncommonly used printable ascii character or a non-printable character (ascii codes 0-31 non-printable). this selection depends on the application type, and other factors related to the developer and users so that the prefix selected is not to be used in the regular keyboard work. and the user can be notified not to use that character in his regular data entry.

in the example form i attached, i used the # char chr(35) as a prefix. its just as an example, you should choose what suits your work.

as an example of how to set up a barcode reader to be compatible with this approach, the picture below show the codes (extracted from the installation manual) to configure a metrologic ms9520/40 voyager® series barcode reader for this purpose.

manhattan barcode scanner
is another type that i found configurable but with a different sequence of codes. so, it depends on the type and manufacturer of the scanner.

2) the design of the form:

what we need here is that the form should be the one which receives and manages the barcode, not the textbox. and we need to add some custom properties and methods to the form to organize our work and add this new functionality to the form.

the custom properties added are:

barcode_firstchar: integer value representing the ascii code of the prefix (in the example form, it is defaulted to 35 which is the # character)

barcode_lastchar: integer value representing the ascii code of the suffix (in the example form, it is defaulted to 9 which is the tab character)

reading_barcode: logical value, the default is .f. used to indicate whether we are in the barcode reading mode or not. setting it to .t. will direct the keys in the keyboard buffer to build the barcode string till the barcode_lastchar is passed.

barcodestring: this character value will save the barcode while we are in the barcode reading mode.

the custom methods:

build_barcode: this method will recieve the keycode from the keypress event of the form during the barcode reading mode and add it to the barcodestring.

manage_barcode: this method is used to manage the received barcode after completion. here in this method the flexibility and smart barcoding is managed.
in the example attached, the form has a pageframe with 3 pages of different uses. one to simulate entry of a new item. the second to simulate finding an item by reading its barcode. the third is to simulate entering invoice items using the barcode reader.
manage_barcode will see which is the current active page to perform the proper action.
so, if it is the first page (new item) the code loaded will be shown in the barcode textbox of the new item.
if the second page (select item), the loaded barcode will be searched in the available item barcodes in the items table. if it is found, its data will be shown. if not, a notification messagebox appear to declare that this item is not identified.
if it is the third page (new invoice), the loaded barcode will be searched in the items table. if
it is available it will be inserted into the new invoice (or the quantity is increased by 1 if it is already in the invoice). if not available a messagebox will be shown to declare that this item is not identified.

in addition to these properties and methods, the form keypreview property should be set to .t. and the form keypress event will contain a control code to re-direct the keycode to build the barcode string during barcode reading mode and suppress the default behavior of the key.

to test the sample, you either can add real item barcodes to the items table, then run the form and use your configured barcode scanner. or, you can use the keyboard to simulate the process by pressing # to load the prefix, then as you enter the characters that represent an available barcode, the form will be in the reading mode. then press tab key to load the suffix character. at that time you will get the appropriate response to the entered barcode.

this way .. you will have a smart form that knows what to do with the loaded barcode wherever the current focus is because it is form-level activity not control-level.

and with a creative mind you can do any action based on the read code and the current form status like calling a new-item form when the loaded barcode is not identified .. or issue some control barcodes .... etc.

i hope these ideas are helpful


* some barcode scanners allow for a longer prefix with 2 or more characters.
* this barcode functionality can be saved into a custom class or a form class.
* the example i posted is not fault proof and i just post it to show the basic idea and the used code.
* the prefix and suffix in a real application can be stored in the configuration table so that they can be part of the application configuration and customization process.

the attachment:

here is the sample form and table. (run the form and it will automatically locate the items table included in the same folder):

download the sample


ammar hadi ... 22/8/2009

3 Responses to Flexible Smart Barcode Scanning

  • Tushar says:

    -Tushar: Nice idea.

    Ammar: Thanks a lot Tushar. Am glad for your opinion.

  • Alwy Ali says:

    Alwy Ali: Thanks Ya sayyidy.
    I have been looking for this kind of information for long time. Shukran Jazziyl

    Ammar: Am Glad it is helpful, welcome Alwy.


  • sandstorm36 says:

    This is very informative Doc.  I will say, using  the form’s Keypreview property is a must, IMHO, in a barcode application.   – jun

    Thanks a lot Jun. I appreciate your opinion and am glad that you regard it as useful. – Ammar

Leave a Reply

Your email address will not be published. Required fields are marked *