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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Going to the next field when you don't want to

Status
Not open for further replies.

Chad Linville

Programmer
Jun 2, 2017
1
US
A "feature" of Foxpro is going to the next or previous tab stop when typing or backspacing.
When the user backspaces and it continues backspacing to and through the previous tab stop, try this.

Place this code in the form.init to bind all KeyPresses to the form's keypress:


Code:
* Stop backspacing through textboxes
FOR EACH loctl IN thisform.Controls
	DO case
		CASE INLIST(loctl.baseclass,'Textbox','Combobox','Listbox','Editbox')
			BINDEVENT(loctl, "KeyPress", thisform, "KeyPress")
	ENDCASE
NEXT

Place this in the form.keypress method to capture the backspace code, 127:

Code:
LPARAMETERS nKeyCode, nShiftAltCtrl

IF INLIST(thisform.ActiveControl.baseclass,'Textbox','Combobox','Listbox','Editbox')
	C_SelStart = thisform.ActiveControl.SelStart
	C_SelLength = thisform.ActiveControl.SelLength
	IF nKeyCode = 127 AND C_SelStart = 0 AND C_SelLength = 0
		NODEFAULT
	ENDIF
ENDIF


To prevent moving forward to the next tab stop automatically when you're happily typing along and reach the end of the field MaxLength, putting SET CONFIRM ON in the form.init seems to do the trick.
 
Thanks for this contribution, you could even make a FAQ from this.

What I personally think of this solution is, it should rather be the base code of the base controls you define than added via BINDEVENTS. BINDEVENTS always is introducing a hurdle of debugging code and making things less discoverable. So, in this case, I would rather propose having that code copied multiple times in the base controls you give in your INLIST as the better approach, even though copied code is always a bad idea. You could also instead base your own baseTextBox, baseCombobx, etc on control or container and add in a behavior class, that is called from Keypress, so you have the code in one central class.

If you take BINDEVENTS to extremes you'll notice it'll cause a heavy weight of checking for the need of execution of delegates, so the excessive use of BindEvents really slows down an application. Also, BindEvents applied this way just says you could have put delegates code in the main class and then to me it's always the more straightforward approach to doing that, Using BindEvents like this is postponing what you could have done in the concrete classes. When it is needed because developers used base classes on forms, then it is not an elegant use of advanced VFP features but a hack and using it as planned way of applying same behavior to multiple controls I also consider a hack. If there is a solution to use some general code with a call it is better for the performance than binding. Binding events makes sense as an implementation of loose coupling or inversion of control but this rather is tight coupling, you actually want this behavior in the base controls and this makes it a bad use of binding.

VFP developers always seem tempted to make use of some of the advanced features like macro substitution or BindEvents, indeed these are helpful extensions of the language, but the art rather is in avoiding them, where they are not needed. A good cook most used tool also is a knife, not a kitchen aid.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top