Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Disable keyboard input in Barcode textbox 2

Status
Not open for further replies.

TariqMehmod

Programmer
Mar 4, 2004
100
0
0
PK
Dear Experts

I have a textbox1 which gets input from Barcode scanner.
I want this textbox not to accept input from keyboard.

Background:

I scan barcodes of new products and save in database.
Some times user enters some wrong data into this textbox and save it in db.
I want to block user to input any data in said textbox to ensure correct data is being entered.

While googling I found this link similar to my problem

But do no know how to make procedures workable in VFP.

Please help
 
The solutions proposed in the StackOverflow thread won't work using native VFP functions because they depened on getting the current time to the nearest millisecond. VFP's DateTime() function only returns the time to the nearest second.

You might be able to use the Windows GetLocalTime() function instead. But a simpler solution would be look for a unique string within your barcode, and to only accept the input if it contains that string.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
In fact, Mike
Mike said:
The solutions proposed in the StackOverflow thread won't work using native VFP functions because they depened on getting the current time to the nearest millisecond.
the SECONDS() function offers a 10 millisecond precision, so it can be used as a basis for a VFP only solution.

So, Tariq, this probably will get you started. I have no scanner at hand to test, but this seems to be able to differentiate between human and machine input looking only at the time interval between key presses. It assumes that scanner input must be terminated with an Enter.

Code:
LOCAL Test AS TestForm

m.Test = CREATEOBJECT("TestForm")
m.Test.Show(1)

DEFINE CLASS TestForm AS Form

	ADD OBJECT lblRegular AS Label WITH Caption = "Regular", Top = 10, Autosize = .T.
	ADD OBJECT Regular AS TextBox WITH Top = 10, Left = 100
	ADD OBJECT lblScanner AS Label WITH Caption = "Scanner", Top = 40, Autosize = .T.
	ADD OBJECT Scanner AS ScannerBox WITH Top = 40, Left = 100

	ADD OBJECT Simulator AS CommandButton WITH Top = 80, Caption = "Simulate Scanner", Autosize = .T.

	PROCEDURE Simulator.Click

		Thisform.Scanner.SetFocus()
		KEYBOARD "0123456789{ENTER}" 

	ENDPROC

ENDDEFINE

DEFINE CLASS ScannerBox AS TextBox

	WaitForCR = .NULL.
	Chronos = .NULL.
	
	PROCEDURE Init
		This.WaitForCR = CREATEOBJECT("WaitForCR")
	ENDPROC

	PROCEDURE Destroy
		This.WaitForCR.ScannerReference = .NULL.
	ENDPROC

	PROCEDURE Reset
		This.WaitingForCR(.F.)
		This.Chronos = .NULL.
		This.Value = ""
	ENDPROC

	PROCEDURE WaitingForCR (DoWait AS Logical)
		IF m.DoWait
			This.WaitForCR.ScannerReference = This
			This.WaitForCR.Interval = 20
			This.WaitForCR.Enabled = .T.
		ELSE
			This.WaitForCR.Enabled = .F.
			This.WaitForCR.Interval = 0
			This.WaitForCR.ScannerReference = .NULL.
		ENDIF
	ENDPROC

	PROCEDURE KeyPress (KeyCode AS Integer, ShiftAltCtrl AS Integer)

		LOCAL Now AS Double

		m.Now = SECONDS()

		DO CASE
		CASE m.ShiftAltCtrl != 0		&& keyboard is being used

			This.Reset()
			NODEFAULT

		CASE ISNULL(This.Chronos)		&& (re)start input

			This.WaitingForCR(.F.)
			This.Chronos = m.Now

			This.WaitingForCR(m.KeyCode != 13)

		CASE m.Now >= This.Chronos AND m.Now < This.Chronos + 0.020		&& quick enough

			This.WaitingForCR(.F.)

			This.Chronos = m.Now
			This.WaitingForCR(m.KeyCode != 13)

		CASE m.Now < This.Chronos AND (m.Now + 86400) < This.Chronos + 0.020		&& quick enough past midnight

			This.WaitingForCR(.F.)

			This.Chronos = m.Now
			This.WaitingForCR(m.KeyCode != 13)

		OTHERWISE		&& scanner not recognized

			This.Reset()
			NODEFAULT

		ENDCASE

	ENDPROC

ENDDEFINE

DEFINE CLASS WaitForCR AS Timer

	ScannerReference = .NULL.

	PROCEDURE Timer
		IF !ISNULL(This.ScannerReference)
			This.ScannerReference.Reset()
			This.ScannerReference = .NULL.
		ENDIF
	ENDPROC

ENDDEFINE
 
Thanks Sir atlopes for helping

I hope your codes will work.
I am trying to apply your codes onto my form.
but facing problems.

Please help me more how to apply your codes with my form.

The attachment is work that I have done.

Please review.

Thanks in advance
 
 https://files.engineering.com/getfile.aspx?folder=e0d6afa7-e859-49fc-8b05-5e9fbedc8680&file=b.zip
Tariq, first of all, you have a self-contained demo that you can try. Just run the program and check if it works as you intend.

If it works, you must understand how it is built. As soon as you get it, it will be easy to port it to a visual class.

You must define two classes, ScannerBox based on TextBox, and WaitForCR based on Timer. They must work together, so it's ok to insert them in the same Visual Class Library.

Move the properties and methods to the two classes, not forgetting the parameters.

Afterward, you can just drop the ScannerBox control wherever required.
 
Sir,

I have simply sorted out everything.
I wrote these 3 lines on timer

[pre]if len(alltrim(thisform.text1.value))<5
thisform.text1.value=""
endif
[/pre]

Now text1 does not accept keyboard value.

So now I think I do not need to convert a long prg to scx provided by sir atlopes.

Anyway thanks to all.
 
That idea of timer resetting a textbox value is by no means safe anyway.

Scanners allow configuring a preamble, which could be, say, CTRL+F3 or any nonprintable hotkey combination. If your textbox expects that as input and only "unlocks" once that's given users would need to be inventive and use some app checking what a scanner enters including nonprintable characters to emulate that, but even if you know there is a preamble of CTRL+F3 (just as an example, use whatever is possible with your scanners) there is no way to put hotkeys like that into the _clipboard and paste them.

Otherwise, as atlopes Simulator.click shows, people can first input the barcode in a notepad and then copy&paste it into the barcode textbox.

People usually don't manually enter barcodes they could also scan, either they only do so having no scanner, but in a POS system, they'd be worse off in such a situation having to always manually enter barcodes or manually type prices.

The most common situation cashiers will manually enter barcodes is, no matter if to scan a known product or register a new one, if the barcode isn't scannable.

That means - in very short - you better solve this problem with either better scanners or using another readable sample product, which is scannable. Taking away the ability for manual input in a POS system in any situation will only mean a customer will either tell the cashier to leave this product out or need to get another one, which doesn't solve the readability of the barcode and just delays the problem to another customer.

If a product is registered wrong a scan if the product will reveal that it's not found in the system and the cashier with that problem should have an easy means to add that missing product himself, problem solved just in time. All you need is to remove products with no valid (recent) sale scans from time to time.

Overall, disabling manual input just causes more lost sales than it solves errors, so in my opinion, that's a bad idea. You can trust your cashiers better than that and even if a product is registered with wrong barcode, the only effect that has is another cashier will need to register it once more and most often then it will be a sample product with a scannable barcode.

And if your shop is doing this in the hours a shop is closed as a maintenance task and people enter codes manually because they have no scanner at hand, you should solve that real-world resource problem making scanners available where needed.

So, overall, I'd say you solve a problem with software here, that has better real-world solutions. Sometimes the job of a developer is pointing out no change in the software but a change in handling a problem is the simplest and cheapest solution.

Bye, Olaf.

Olaf Doschke Software Engineering
 

Thanks for helping, here I reply about _clipboard

I put this line on the GotFocus of text1

KEYBOARD '' CLEAR

In this way use can not paste any data in this textbox.

Sorry Sir, I am doing all this because I am unable to convert prg to scx. (codes given by atlopes)
 
That'll not help.

Users can set focus to the barcode textbox, then copy their input from notpad and paste it, there is no focus change and no gotficus event between that.

Anyway, my argument is you're implementing an unnecessary hindering hurdle that causes more problems than it solves.

It's your decision, the best solution is to have a preamble defined in your scanners (refer to scanner manual), if you insist on your bad idea. Only accepting barcodes if they are confimed with ENTER and making that a postamble key scanners send would also work, as ENTER also can't be put into the _clipboard. Again, you need to make use of scanner features here, and I don't know any scanner not allowing preamble and postamble configurations.

Another solution is also existing in the form of RS232 scanners not emulating a keyboard at all, but manually entering a barcode is an essential possibility in POS systems for any matter and disabling that - again - causes more trouble than it solves. You may need to make your experience to see it for yourself.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Tariq, having thought about this a bit more, I'm thinking it might be a mistake to try to disallow user input. I don't know anything about the environment that your application is running in. But in many barcode applications, the system does allow human input. This is necessary because barcodes are occasionally damaged or obscured, and the user then needs to enter the code manually.

So, instead of trying to distinguish human vs scanner input, should you perhaps be focusing on validating whatever appears in the text box to ensure that it is a valid barcode, regardless of how it got there? The barcode presumably conforms to a standard layout (a certain number of digits, for example), which should be easy for you to validate.

Just a thought.

Mike





__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Validation is a good idea. The 13th digit in an EAN-13 barcode, for example, is a checksum and while it doesn't prevent any error (the chance of entering the correct check digit is 10%) it helps most of the time hindering wrong manual input AND identifies wrong scans, too.

I bet GTIN doesn't differ in that aspect.

Since you talk of registering you don't have the check against the already registered barcodes, but you could even do a google search to see if a product barcode finds the product meant to be registered in your system, too, on top of the technical checksum validation.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top