In my previous post [2] I show how to add characters in a textbox, without using the keyboard or using the KWYBOARD command, but altering the keyboard() event.
The major drawback of the solution, was that if the textbox has a controlsource, the variable from the controlsource isn't updated and the value property isn't preserved.
Also, the reason for that behavior is the switch of the order of the interactivechange(0 and keypress().
As a solution, I propose to simply update the controlsource in the interactivechange.
The next example shows this, having as controlsource a memory variable in txt2 and a cursor field in txt3. Next to this example follows several others, showing the same trick applied to editbox, combobox, grid, and with other data type, like number and date.
PUBLIC ofrm,lcVar
CLEAR
lcVar =
""
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT txt2 as MyText2 WITH width = 225, ControlSource = "lcVar"
ADD OBJECT txt3 as MyText2 WITH top=50, width = 225, ControlSource =
"cCur.cVar"
ADD OBJECT cmd as CommandButton
WITH left=250,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar
C(120))
APPEND BLANK
ENDPROC
PROCEDURE cmd.click
FOR lni = 97 TO 106
ThisForm.txt2.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt2.Keypress(13,0,.T.) && Enter
FOR lni = 65 TO 86
ThisForm.txt3.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt3.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar =
['+m.lcVar+']','cCur=['+cCur.cVar+']'
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as TextBox
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
The next example illustrate the same approach applied to editboxes (I changed only the baseclass type)
PUBLIC ofrm,lcVar
CLEAR
lcVar =
""
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT txt2 as MyText2 WITH width = 225, ControlSource =
"lcVar"
ADD OBJECT txt3 as MyText2 WITH top=100, width = 225, ControlSource =
"cCur.cVar"
ADD OBJECT cmd as CommandButton
WITH left=250,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar
C(120))
APPEND BLANK
ENDPROC
PROCEDURE cmd.click
FOR lni = 97 TO 105
ThisForm.txt2.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt2.Keypress(13,0,.T.) && Enter
FOR lni = 66 TO 86
ThisForm.txt3.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt3.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar = ['+m.lcVar+']','cCur=['+cCur.cVar+']'
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as EditBox
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
And the same approach applied to comboboxes (I changed only the baseclass type)
PUBLIC ofrm,lcVar
CLEAR
lcVar =
""
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT txt2 as MyText2 WITH width = 225, ControlSource =
"lcVar"
ADD OBJECT txt3 as MyText2 WITH top=50, width = 225, ControlSource =
"cCur.cVar"
ADD OBJECT cmd as CommandButton
WITH left=250,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar
C(120))
APPEND BLANK
ENDPROC
PROCEDURE cmd.click
FOR lni = 97 TO 105
ThisForm.txt2.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt2.Keypress(13,0,.T.) && Enter
FOR lni = 66 TO 86
ThisForm.txt3.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt3.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar =
['+m.lcVar+']','cCur=['+cCur.cVar+']'
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as ComboBox
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
Now let's try with a grid
PUBLIC ofrm,lcVar
CLEAR
lcVar =
""
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT grd as grid WITH
Recordsource = "cCur",allowaddnew = .T.
ADD OBJECT cmd as CommandButton
WITH left=325,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar
C(120))
APPEND BLANK
APPEND BLANK
APPEND BLANK
GO TOP
ENDPROC
PROCEDURE Init
This.grd.Column1.RemoveObject("Text1")
This.grd.Column1.AddObject("Text1","MyText2")
This.grd.Column1.Text1.Visible = .T.
PROCEDURE cmd.click
FOR lni = 97 TO 105
ThisForm.grd.Column1.Text1.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.grd.Column1.Text1.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar =
['+m.lcVar+']','cCur=['+cCur.cVar+']'
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as TextBox
margin = 0
borderstyle = 0
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
Now having numeric variable and field
PUBLIC ofrm,lcVar
CLEAR
lcVar = 0
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT txt2 as MyText2 WITH width = 225, ControlSource =
"lcVar"
ADD OBJECT txt3 as MyText2 WITH top=50, width = 225, ControlSource =
"cCur.cVar"
ADD OBJECT cmd as CommandButton
WITH left=250,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar
N(20))
APPEND BLANK
ENDPROC
PROCEDURE cmd.click
FOR lni = 53 TO 55
ThisForm.txt2.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt2.Keypress(13,0,.T.) && Enter
FOR lni = 48 TO 52
ThisForm.txt3.Keypress(m.lni,0,.T.) && A
NEXT
ThisForm.txt3.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar = ',m.lcVar,'cCur=',cCur.cVar
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as TextBox
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
Finally, having date variable and field
PUBLIC ofrm,lcVar
CLEAR
lcVar = {}
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
autocenter = .T.
ADD OBJECT txt2 as MyText2 WITH width = 225, ControlSource =
"lcVar"
ADD OBJECT txt3 as MyText2 WITH top=50, width = 225, ControlSource =
"cCur.cVar"
ADD OBJECT cmd as CommandButton
WITH left=250,Caption='click',Autosize=.T.
PROCEDURE load
CREATE CURSOR cCur (cVar D)
APPEND BLANK
ENDPROC
PROCEDURE cmd.click
FOR lni = 1 TO 6
ThisForm.txt2.Keypress(49,0,.T.) && A
NEXT
ThisForm.txt2.Keypress(13,0,.T.) && Enter
FOR lni = 1 TO 6
ThisForm.txt3.Keypress(49,0,.T.) && A
NEXT
ThisForm.txt3.Keypress(13,0,.T.) && Enter
ENDPROC
PROCEDURE click
ACTIVATE SCREEN
?'lcVar = ',m.lcVar,'cCur=',cCur.cVar
ENDDEFINE
*********************
* Text box class
2
*********************
DEFINE CLASS MyText2 as TextBox
PROCEDURE keypress
LPARAMETERS nKey,nShift,lraised
IF lraised
DODEFAULT(nKey,nShift)
=This.value
ENDIF
ENDPROC
PROCEDURE interactivechange
IF !EMPTY(This.ControlSource)
TRY
replace (This.ControlSource) WITH (This.Value)
CATCH
STORE (This.Value) TO (This.ControlSource)
ENDTRY
ENDIF
ENDPROC
ENDDEFINE
See also