B+: Use TAB to switch between text fields..?

Blitz3D Forums/Blitz3D Beginners Area/B+: Use TAB to switch between text fields..?

BachFire(Posted 2003) [#1]
Hey,

I made an app with B+, which includes several text fields. I would like to move the curser to the next text field, when TAB is pressed.

I can't figure this out.. :( I have tried working with the 'HotKeyEvent' command, but have a hard time seeing how it works..

Could someone help me, please?


Oldefoxx(Posted 2003) [#2]
One of the best ways is to create arrays for values of x, y, and z (column,row,length) for each field. Your index then increments to point to the next field, and decrements to point to the previous field. If your index exceeds the maximum number of entries allowed in your arrays (goes beyond the last field), just have it start again at the first one, and if the index decrements back before the first field, just set it to the last one. You can use the LOCATE command to position to the column and row, but the
big problem is limiting the input to the length that you want the field to be. In addition, you may want to limit what characters are valid in that field (Only digits in a phone number field, for instance). Look in the code archives and in the forum elsewhere to find efforts to code routines to supplement INPUT to accomodate these requirements.


EOF(Posted 2003) [#3]
Here is a tabber example I done a while back with HotKeyEvent.
I make the TAB and Shift+TAB generate and event of $9000.

Note: This example has a userlib entry for selecting the values in the textboxes for editing.
If you just want to try out this example without having to set up the userlib just comment out the SendMessage command.

; Textboxes - adding 2 values
; with TABBING support and text 'selection'

; userlib
; ************************
; .lib "user32.dll"
; SendMessage%(hwnd,msg,wParam,mParam):"SendMessageA"
; ************************

Const EM_SETSEL=$b1 ;  select a range of characters in an edit control

Dim gad(4) : tab=1
Gosub CreateGUI

Repeat
	ev=WaitEvent()
	DebugLog "Event = $"+Right$(Hex$(ev),4) + "   "+EventSource() + "   "+EventData()
	Select ev
		Case $803 ; close [X]
			Exit
		Case $401 ;gadgethit
				total#=Float(TextFieldText(gad(1)))+Float(TextFieldText(gad(2)))
				SetGadgetText gad(3),Str$(total)
				lastgad=EventSource()
		Case $9000 ; TAB key event
				If lastgad=gad(1) tab=2
				If lastgad=gad(2) tab=1
				ActivateGadget gad(tab) : lastgad=gad(tab)
				SendMessage QueryObject(gad(tab),1),EM_SETSEL,0,-1 ; select all characters
	End Select
Forever

End

.CreateGUI
	win = CreateWindow("Adder",176,193,284,123,Desktop(),1)
	gad(1) = CreateTextField(20,20,100,20,win,0)
	gad(2) = CreateTextField(150,20,100,20,win,0)
	gad(3) = CreateTextField(106,56,100,20,win,0)
	CreateLabel("+",133,21,9,15,win,0)
	CreateLabel("=",80,57,10,16,win,0)
	HotKeyEvent 15,0,$9000,+1              ; TAB forward
	HotKeyEvent 15,1,$9000,-1              ; TAB back
	HotKeyEvent 1,0,$803                   ; ESC
	ActivateGadget gad(1)
Return



soja(Posted 2003) [#4]
Here's one I wrote. It doesn't rely on you to actively keep track of the focus, and it is very easy to add/subtract/rearrange items in the tab cycle order, so that might make it a little easier. But, it doesn't have the text selection stuff built-in like Syntax Error's, and there are other problems, but I think they're Blitz issues.
;------------------------------
; USERLIB DECLARATIONS 
; 
; .lib "user32.dll"
; GetFocus%():"GetFocus"

;------------------------------
; CONSTS

Const evWindowClose = $803	; "Real" Blitz event
Const evTab 		= $104	; "Made up" event for HotKeyEvent
Const vkTab			= 15	; Scancode for Tab key

;------------------------------
; TYPES

Type TabCycleGadget
	Field hgadget% ; Windows handle
	Field gadget% ; Blitz handle
End Type

;------------------------------
; GLOBALS

Global wnd%, txt%, txt2%, button%, txtarea%, listbox%, tree%, button2%

;------------------------------
; MAIN PROGRAM

InitGUI()
InitTabCycle()

While WaitEvent()
	Select EventID()
		Case evWindowClose : End
		Case evTab : PerformTabCycle(GetFocus(), EventData())
	End Select
Wend

;------------------------------
; FUNCTIONS

Function InitGUI()
	; Create Window
	width% = 320 : height% = 240
	x% = (ClientWidth(Desktop()) - width) / 2
	y% = (ClientHeight(Desktop()) - height) / 2
	wnd = CreateWindow("Tab Cycle Demo", x, y, width, height, 0, 1)

	; Create Gadgets
	txt = CreateTextField(5, 5, 200, 20, wnd,2)
	txt2 = CreateTextField(5, 30, 200, 20, wnd)
	button = CreateButton("Button", 5, 55, 80, 25, wnd)
	txtarea = CreateTextArea(5, 85, 200, 95, wnd)
	listbox = CreateListBox(210, 5, 100, 75, wnd)
	tree = CreateTreeView(210, 85, 100, 65, wnd)
	button2 = CreateButton("Button2", 210, 155, 80, 25, wnd)
	
	; Configure Gadgets
	AddGadgetItem listbox, "ListItem1"
	AddGadgetItem listbox, "ListItem2"
	SelectGadgetItem listbox, 1
	AddTreeViewNode("Node1", TreeViewRoot(tree))
	AddTreeViewNode("Node2", TreeViewRoot(tree))
End Function

Function InitTabCycle()
	; Set up Forward Tab Hotkey 
	HotKeyEvent vkTab, 0, evTab

	; Set up Backward Tab Hotkey 
	HotKeyEvent vkTab, 1, evTab, 1

	; Set up tab cycling in this order (empty list is ok)
	; i.e. to change tab order, just cut and paste!
	CreateTabCycleGadget(txt)
	CreateTabCycleGadget(txt2)
	CreateTabCycleGadget(button)
	CreateTabCycleGadget(txtarea)
	CreateTabCycleGadget(listbox)
	CreateTabCycleGadget(tree)
	CreateTabCycleGadget(button2)
End Function

Function CreateTabCycleGadget(g%)
	t.TabCycleGadget = New TabCycleGadget
	t\gadget = g
	t\hgadget = QueryObject(g, 1)
End Function

Function PerformTabCycle(g%, bBackwards%)
	Local t.TabCycleGadget = First TabCycleGadget
	If g <> 0 And t <> Null Then
		; Find out if current focused gadget is in tab cycle list
		While (g <> t\hgadget) And (t <> Last TabCycleGadget) t = After t : Wend
		; Change focus
		If t <> Null Then
			; Change from current focused gadget
			If bBackwards Then
				; Go backwards in cycle (SHIFT-TAB)
				If t = First TabCycleGadget Then
					t = Last TabCycleGadget
					ActivateGadget(t\gadget)
				Else
					t = Before t
					ActivateGadget(t\gadget)
				EndIf
			Else					
				; Go forwards in cycle (normal TAB)
				If t = Last TabCycleGadget Then
					t = First TabCycleGadget
					ActivateGadget(t\gadget)
				Else
					t = After t
					ActivateGadget(t\gadget)
				EndIf
			EndIf
		Else
			; Activate first gadget in cycle (no current focused gadget)
			t = First TabCycleGadget
			ActivateGadget(t\gadget)
		EndIf 
	EndIf
End Function